How to get SE-PostgreSQL acceptable
I have re-reviewed the SE-PostgreSQL patch set. I don't want to talk
about here whether the security model is appropriate, how foreign keys
are to be handled etc. I want to discuss that I really don't like the
architecture of this patch. I have said this before in previous review
rounds, but let me make it a little clearer here. Steps to get your
patch accepted:
One feature at a time
---------------------
By my count, your patch set implements at least three or four major
features:
1a. System-wide consistency in access control
1b. Mandatory access control
2. Row-level security
3. Additional privileges (permission to alter tables, modify large
objects, etc.)
You may object and say, these morally belong together in a
proper/professional/adequate implementation of this feature you have
planned. But realistically, they can be separated. And if a feature is
controversial, difficult, or complicated, it would be in your interest
to deal with one feature at a time. "Deal" means the whole round:
discuss design, write patch, review, test, commit, relax.
If I had to do this, I would first write a patch for #1: A patch that
additionally executes existing privilege checks against an SELinux
policy. Existing privilege checks are a well-defined set: they mostly
happen through pg_xxx_aclcheck() functions. Hook your checks in there.
This patch would already provide useful functionality, but it would be
much easier to review and verify, because we know how permission
checking works in the existing system, so we can compare them. And it
would build confidence among developers and users about the whole idea,
about SELinux integration etc.
Then you can tackle #3: Place permission checks in more places. This
patch would be simple to review and verify, because at this point we
already know how SELinux integration works, and making more use of it is
not such a big step. At this point we could also discuss whether some
of these additional checks are useful enough to also expose via the
traditional SQL ACLs, which would further simplify the patch.
Row-level security should also be developed as a completely separate
feature, without any SELinux tie-in initially. This is not only
important to make review and verification simpler, but also because we
really need a wider test community for such a tricky feature. And the
set of SELinux users is quite limited, and the intersection with
PostgreSQL developers is almost empty. This was already previously
discussed at length.
No in-code frameworks
---------------------
Write your code so that it is fully integrated with the existing code.
Or write a plugin interface and then write a plugin. But don't invent a
"framework" because you are afraid to integrate the new code with the
old code.
As mentioned above, permission checks are done through pg_xxx_aclcheck()
functions, which is enough of a framework. I wouldn't want yet another
framework that does more permission checking at other times and places.
If the existing interfaces are not adequate for your purpose, by all
means, extend, refactor, or rewrite them. But don't just avoid it
because you don't want to interfere with the existing code. So scrap
the whole "PGACE" thing.
If you need to refactor the aclcheck interfaces, that's another separate
patch, which can easily be reviewed and verified, simplifying the
following patches even further.
These things are not going to get done within two weeks. But if you
start producing small, self-contained patches along the above lines, you
are much more likely to make progress over the coming development cycle.
Sorry for long description again.
Peter Eisentraut wrote:
I have re-reviewed the SE-PostgreSQL patch set. I don't want to talk
about here whether the security model is appropriate, how foreign keys
are to be handled etc. I want to discuss that I really don't like the
architecture of this patch. I have said this before in previous review
rounds, but let me make it a little clearer here. Steps to get your
patch accepted:One feature at a time
---------------------By my count, your patch set implements at least three or four major
features:1a. System-wide consistency in access control
1b. Mandatory access control
2. Row-level security
3. Additional privileges (permission to alter tables, modify large
objects, etc.)You may object and say, these morally belong together in a
proper/professional/adequate implementation of this feature you have
planned. But realistically, they can be separated. And if a feature is
controversial, difficult, or complicated, it would be in your interest
to deal with one feature at a time. "Deal" means the whole round:
discuss design, write patch, review, test, commit, relax.
I can't afford not to make clear these issues.
In this case, (1a) and (1b) are indivisible, because I want to apply
SELinux as a security server of (1a), SELinux has to be MAC feature.
However, I don't deny a (1b) without (1a) feature like "Oracle Label
Security", which is not a facility I want to make.
I guess (1b) also contains a feature to manage security label.
Please note that I don't really want to (1b) only feature.
The system-wide consistency in access control is the soul.
We can consider (2) as a separated issue. In fact, I already provide
a GUC: sepostgresql_row_level=on/off. It also means whether users
accept a set of benefit(row-level granularity) and demerit(cover
channel of PK/FK), or not.
OK, I don't discuss about covert channel here.
The (3) is involved to (1b). As a basic assumption, MAC system
need to check *any actions* come from clients, even if they have
superuser privileges.
We already have SQL-level privileges, like ACL_SELECT and so on.
However, some of operations implicitly assume request come from
superuser is safe. For example, superuser is allowed to load
a discretionary shared library file, but it also means he is
trusted.
If security design (which is defined by (1a) and (1b) primarily)
does not allow unconditionally trusted user, it is quite natural
to apply additional privileges, even if vanilla one unconditionally
trust superuser.
Unfortunatelly, we don't have any access controls on large object,
but SELinux does not want to provide an information store without
mandatory access controls. So, SE-PostgreSQL applies its access
controls on large object. Thus, (3) is also indivisible from (1a).
If I had to do this, I would first write a patch for #1: A patch that
additionally executes existing privilege checks against an SELinux
policy. Existing privilege checks are a well-defined set: they mostly
happen through pg_xxx_aclcheck() functions. Hook your checks in there.
I had a concern about pg_xxx_aclcheck().
When we accesses a table via a view, pg_xxx_aclcheck() checkes view's
ACLs and table's ACLs are left for unchecked, even if it accesses
same object.
SELinux always makes its decision based on the attribute of object
itself. In other word, the route to access taget object does not
make any affect on its decision making.
For example, a filesystem object (inode) can have multiple pathname
using hard link on operating system. SELinux always makes ite decision
based on inode's attribute (called as security context), independent
from its pathname. Do you know a previous hot discussion between
SELinux and AppArmor in Linux developers?
Please note that I don't deny the benefit of view. It has various
effective usages so we cannot ignore them.
However, it mismatched with the security design, so I needed to put
security hooks on different strategic points.
Row-level security should also be developed as a completely separate
feature, without any SELinux tie-in initially. This is not only
important to make review and verification simpler, but also because we
really need a wider test community for such a tricky feature. And the
set of SELinux users is quite limited, and the intersection with
PostgreSQL developers is almost empty. This was already previously
discussed at length.
It would be possible.
However, note that we should not implement the first step ignoring
upcoming facility.
Eventually I would implement "SE-PostgreSQL 1st edition" with
paying attention for the upcoming row level security.
No in-code frameworks
---------------------Write your code so that it is fully integrated with the existing code.
Or write a plugin interface and then write a plugin. But don't invent a
"framework" because you are afraid to integrate the new code with the
old code.
At least, PGACE is not a purpose for me.
If fully integrated archtencture is absolutely necessary,
I'll scrap PGACE framework.
Trusted Solaris folks may concern about it, but I cannot give
them higher priority than SE-PostgreSQL getting merged.
(Might sound insensitive, I don't have leeway now.)
The very earlier SE-PostgreSQL put its code directly, because
I didn't pay mention for T-Sol folks at that time.
However...
As mentioned above, permission checks are done through pg_xxx_aclcheck()
functions, which is enough of a framework. I wouldn't want yet another
framework that does more permission checking at other times and places.
If the existing interfaces are not adequate for your purpose, by all
means, extend, refactor, or rewrite them. But don't just avoid it
because you don't want to interfere with the existing code. So scrap
the whole "PGACE" thing.
However, it is a different issue whether pg_xxx_aclcheck() can work as
an alternative of PGACE, or not.
SE-PostgreSQL want to make its decision more than pg_xxx_aclcheck(),
so, in finally, we need to put a code to check on different strategic
points where currently pgaceXXXX() are deployed.
If you need to refactor the aclcheck interfaces, that's another separate
patch, which can easily be reviewed and verified, simplifying the
following patches even further.
I believe a basic premise is vanilla PostgreSQL keeps correct behavior
based on SQL standard. An enhanced security should apply its access
controls orthogonally.
So, I cannot believe refactoring pg_xxx_aclcheck() is not acceptable.
If vanilla PostgreSQL become to check ACLs on tables, independent
from views, do you think it is acceptable?
These things are not going to get done within two weeks.
No wonder!
However, we have to make clear whether the PGACE architecture
is incorrect, or not, at first.
I think the name of PGACE is not important, but it is necessary
to make SELinux's decision in similar strategic point in finally.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
However, we have to make clear whether the PGACE architecture
is incorrect, or not, at first.
I think the name of PGACE is not important, but it is necessary
to make SELinux's decision in similar strategic point in finally.
I've been thinking about this issue as well. I think a framework of
some kind could be acceptable, but only if we're convinced that the
framework is really general enough to handle all of the cases that we
care about. For example, can we back-port our existing DAC
infrastructure to use PGACE? Is it really true that SE-PostgreSQL
interacts through the rest of the system ONLY through PGACE? If the
answers to both questions are YES, then it's a framework. If the
answer to either question is NO, then it's just a bunch of places
where you needed to stick code to make SE-PostgreSQL work.
I haven't read the code, but from reading the docs, I have a feeling
that right now the answer to both questions are NO, which means it
doesn't really have a lot of value. One example of this is the
pg_security system catalog. The catalog representation you're
proposing is probably just fine for associating OIDs to SELinux
security labels. But trying to present it as a general thing that
some other security implementation could reuse just doesn't seem
realistic. Who is to say that the next person who writes an enhanced
security feature will want to use text as the representation for their
security domains? It could just as easily be two integers, or an
array of booleans. This is after all a database product, so the
chances that someone would want to do something with structured data
seem non-negligible.
In the end, you're going to have to be the one who makes the decision
on which way to go. In some ways, I think that a plugin architecture
would be better for everyone: we worry about the things on our side of
the abstraction boundary, and you worry about the things on your side.
Potentially you or someone else can release enhanced security plugins
without needing any changes to core, and potentially on a different
release cycle. On the other hand, a plugin architecture is probably
going to be a lot of work. It seems that to install the plugin you
would need to make system catalog changes as well as stuff additional
system attributes into every table, which are relatively invasive
changes. And you'll need to convince everyone that it's really a
plug-in architecture and not just a special case for SE-PostgreSQL, so
you'll need to prove that there are multiple viable clients, perhaps
by backporting our existing DAC.
...Robert
* KaiGai Kohei (kaigai@kaigai.gr.jp) wrote:
So, I cannot believe refactoring pg_xxx_aclcheck() is not acceptable.
If vanilla PostgreSQL become to check ACLs on tables, independent
from views, do you think it is acceptable?
Well, just to be clear, ACLs are checked on tables under views, but
they're checked using the privileges of the view owner rather than
the privileges of the current user. I've run into that empirically
because I've gotten 'permission denied' errors when using a view that
I've clearly got full rights on but was owned by someone else (who
didn't have rights on the table underneath).
That being said, I'd think that if we do need different semantics from
that for SE-PostgreSQL, we could implement it using a GUC or similar to
keep the current behavior as well allow the SE-PostgreSQL behavior.
However, we have to make clear whether the PGACE architecture
is incorrect, or not, at first.
It really bothers me that it seems like these kinds of reviews of the
larger patches don't happen until it's time to decide about the next
release. Perhaps these issues were all brought up seperately in prior
threads, or they weren't articulated as requirements or show-stoppers,
and if so then I apologize for not following those more closely.
If the approach Peter outlined is what core wants to see and is willing
to go along with to get SE-PostgreSQL included then let's please decide
that now and agree that unless some serious problem comes up we'll stick
to it and not require the whole thing be rewritten again later.
I'm not sure about KaiGai's feelings on this, but it strikes me that
adding SELinux support for the existing levels of access control in PG
might be straight-forward and small enough to include for 8.4 and would
show some commitment to this approach of "do it for PG, add SELinux
checks for it". Alternatively, maybe a progression-towards-SE-PostgreSQL
wiki/webpage that outlines the plan, current work, what's been
committed, etc, that everyone reviews and agrees to?
As a side-note, I've gotten some extremely positive feedback about
SE-PostgreSQL from folks in my organization who run systems where it
would be used. I'm going to be having a more detailed discussion later
today.
Thanks,
Stephen
That being said, I'd think that if we do need different semantics from
that for SE-PostgreSQL, we could implement it using a GUC or similar to
keep the current behavior as well allow the SE-PostgreSQL behavior.
I don't think a GUC is what you need because you need both behaviors
simultaneously, one for MAC and the other for DAC. But I am sure
there must be some way to code around the problem.
...Robert
Robert Haas wrote:
I haven't read the code, but from reading the docs, I have a feeling
that right now the answer to both questions are NO, which means it
doesn't really have a lot of value. One example of this is the
pg_security system catalog. The catalog representation you're
proposing is probably just fine for associating OIDs to SELinux
security labels. But trying to present it as a general thing that
some other security implementation could reuse just doesn't seem
realistic. Who is to say that the next person who writes an enhanced
security feature will want to use text as the representation for their
security domains? It could just as easily be two integers, or an
array of booleans. This is after all a database product, so the
chances that someone would want to do something with structured data
seem non-negligible.
Text represented security attribute is the most common format
for any other security mechanism also.
(For example, T-SOL also have its text representation.)
In addition, TEXT is the most flexible format. If any other
feature want to handle it as an array, it can be stored as
a text representation.
In the end, you're going to have to be the one who makes the decision
on which way to go. In some ways, I think that a plugin architecture
would be better for everyone: we worry about the things on our side of
the abstraction boundary, and you worry about the things on your side.
Potentially you or someone else can release enhanced security plugins
without needing any changes to core, and potentially on a different
release cycle. On the other hand, a plugin architecture is probably
going to be a lot of work. It seems that to install the plugin you
would need to make system catalog changes as well as stuff additional
system attributes into every table, which are relatively invasive
changes. And you'll need to convince everyone that it's really a
plug-in architecture and not just a special case for SE-PostgreSQL, so
you'll need to prove that there are multiple viable clients, perhaps
by backporting our existing DAC.
Please make clear the meaning of terms.
The 'plugin' means a loadable module which provides its own security
policy, doesn't it?
There is fundamental difference between built-in and plug-in.
The most important factor is where the hooks are deployed, and
what facility enables to manage security attribute.
Even if I implement SE-PostgreSQL as a loadable module, core
PostgreSQL has to provide proper hooks in strategic points and
facilities to manage security attribute (pg_security system catalog
and security_label system column).
If you require to implement it without these facilities, I think
it is impossible and prefer scraping PGACE and integrate SE- code
into core.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
Text represented security attribute is the most common format
for any other security mechanism also.
(For example, T-SOL also have its text representation.)
In addition, TEXT is the most flexible format. If any other
feature want to handle it as an array, it can be stored as
a text representation.
Right, but that sort of misses the point of using a DATABASE. I could
store everything as text if I wanted to and skip using a database
altogether, but I don't want to. That's why I use a database.
Please make clear the meaning of terms.
The 'plugin' means a loadable module which provides its own security
policy, doesn't it?
That is what I meant, yes.
Even if I implement SE-PostgreSQL as a loadable module, core
PostgreSQL has to provide proper hooks in strategic points and
facilities to manage security attribute (pg_security system catalog
and security_label system column).
If you require to implement it without these facilities, I think
it is impossible and prefer scraping PGACE and integrate SE- code
into core.
I am not in a position to require anything since I am not a committer,
but I would think that you would need to convince people that the
facilities which your plugin requires were pretty much the same as the
facilities that any other future plugin might require - that the
plugin framework was client-agnostic.
...Robert
Stephen Frost wrote:
* KaiGai Kohei (kaigai@kaigai.gr.jp) wrote:
So, I cannot believe refactoring pg_xxx_aclcheck() is not acceptable.
If vanilla PostgreSQL become to check ACLs on tables, independent
from views, do you think it is acceptable?Well, just to be clear, ACLs are checked on tables under views, but
they're checked using the privileges of the view owner rather than
the privileges of the current user. I've run into that empirically
because I've gotten 'permission denied' errors when using a view that
I've clearly got full rights on but was owned by someone else (who
didn't have rights on the table underneath).That being said, I'd think that if we do need different semantics from
that for SE-PostgreSQL, we could implement it using a GUC or similar to
keep the current behavior as well allow the SE-PostgreSQL behavior.
I think it is not reasonable.
If there are different philosophies, "one for one" seems to me
straight forward approach, for security especially.
However, we have to make clear whether the PGACE architecture
is incorrect, or not, at first.It really bothers me that it seems like these kinds of reviews of the
larger patches don't happen until it's time to decide about the next
release. Perhaps these issues were all brought up seperately in prior
threads, or they weren't articulated as requirements or show-stoppers,
and if so then I apologize for not following those more closely.If the approach Peter outlined is what core wants to see and is willing
to go along with to get SE-PostgreSQL included then let's please decide
that now and agree that unless some serious problem comes up we'll stick
to it and not require the whole thing be rewritten again later.
As I noted, PGACE is not my goal.
I don't tremble to integrate SELinux related code into the core.
I'm not sure about KaiGai's feelings on this, but it strikes me that
adding SELinux support for the existing levels of access control in PG
might be straight-forward and small enough to include for 8.4 and would
show some commitment to this approach of "do it for PG, add SELinux
checks for it". Alternatively, maybe a progression-towards-SE-PostgreSQL
wiki/webpage that outlines the plan, current work, what's been
committed, etc, that everyone reviews and agrees to?
Are you saying enlargement step-by-step, aren't you?
At least, it is far preferable to a death punishment.
I would like to here Joshua's opinion also.
adding SELinux support for the existing levels of access control in PG
is
- table/column level access controls
- permission checks on database login
- permission checks on function invocation
- they need a facility to manage security label
- I want permission checks on loading a library,
though existing PG checks superuser() only.
and
- removing PGACE, integrate SEPG code into core
- permission checks on largeobjects is postponed
- row level security is postponed (NOT REJECTED!)
- so, writable system column is also postponed
If summary is necessary, I'll post it tommorow JST.
Because it is not a zero-based implementation, so I believe it can
be minimized within acceptable timescale.
As a side-note, I've gotten some extremely positive feedback about
SE-PostgreSQL from folks in my organization who run systems where it
would be used. I'm going to be having a more detailed discussion later
today.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
KaiGai Kohei wrote:
I'm not sure about KaiGai's feelings on this, but it strikes me that
adding SELinux support for the existing levels of access control in PG
might be straight-forward and small enough to include for 8.4 and would
show some commitment to this approach of "do it for PG, add SELinux
checks for it". Alternatively, maybe a progression-towards-SE-PostgreSQL
wiki/webpage that outlines the plan, current work, what's been
committed, etc, that everyone reviews and agrees to?Are you saying enlargement step-by-step, aren't you?
At least, it is far preferable to a death punishment.I would like to here Joshua's opinion also.
s/here/hear/g
Sorry,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
Even if I implement SE-PostgreSQL as a loadable module, core
PostgreSQL has to provide proper hooks in strategic points and
facilities to manage security attribute (pg_security system catalog
and security_label system column).
If you require to implement it without these facilities, I think
it is impossible and prefer scraping PGACE and integrate SE- code
into core.I am not in a position to require anything since I am not a committer,
but I would think that you would need to convince people that the
facilities which your plugin requires were pretty much the same as the
facilities that any other future plugin might require - that the
plugin framework was client-agnostic.
We (as a security folks) know any MAC facility have similar
architecture called as reference monitor, so I believe it is
quite possible to implement them as same basis.
But it is a hard request to take an evidence immediately.
IMO, the framework is purely implementation matter, so it is
not late when the second one appeared.
As I noted to another message, I can accept to integrate limited
functional SE-PostgreSQL without any PGACE.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
KaiGai Kohei wrote:
Stephen Frost wrote:
* KaiGai Kohei (kaigai@kaigai.gr.jp) wrote:
So, I cannot believe refactoring pg_xxx_aclcheck() is not acceptable.
If vanilla PostgreSQL become to check ACLs on tables, independent
from views, do you think it is acceptable?Well, just to be clear, ACLs are checked on tables under views, but
they're checked using the privileges of the view owner rather than
the privileges of the current user. I've run into that empirically
because I've gotten 'permission denied' errors when using a view that
I've clearly got full rights on but was owned by someone else (who
didn't have rights on the table underneath).That being said, I'd think that if we do need different semantics from
that for SE-PostgreSQL, we could implement it using a GUC or similar to
keep the current behavior as well allow the SE-PostgreSQL behavior.I think it is not reasonable.
If there are different philosophies, "one for one" seems to me
straight forward approach, for security especially.
When we talk about mandatory access control we are generally very clear that for
it to be mandatory and for the policy to be analyzable you must identify objects
unambiguously. For SE-Postgres this is an absolute necessity.
At the same time, if view-based ACL's are there, and people want them and use
them then that doesn't affect us (the people that want to use sepostgres). They
must be orthogonal and sepostgres must have a way of unambiguously labeling objects.
However, we have to make clear whether the PGACE architecture
is incorrect, or not, at first.It really bothers me that it seems like these kinds of reviews of the
larger patches don't happen until it's time to decide about the next
release. Perhaps these issues were all brought up seperately in prior
threads, or they weren't articulated as requirements or show-stoppers,
and if so then I apologize for not following those more closely.
As a new-comer to this discussion (and indeed this list/community) I find it
baffling that a patchset that has been around this long is just now having basic
architectural questions asked about it.
If the approach Peter outlined is what core wants to see and is willing
to go along with to get SE-PostgreSQL included then let's please decide
that now and agree that unless some serious problem comes up we'll stick
to it and not require the whole thing be rewritten again later.As I noted, PGACE is not my goal.
I don't tremble to integrate SELinux related code into the core.
Flask (from which SELinux is derived) has the basic architecture of separating
enforcement from policy. This generally means that a security server (or
backend) knows what the policy is and how to calculate access vectors and it
passes those answers to the enforcement points. Flask itself is a framework. In
Linux and Xorg a more general framework was built that interfaces to flask,
because the flask security server wasn't seen as something that could implement
any kind of security policy (whether that is correct or not is a point of
contention, as the selinux security server already implements a kind of RBAC,
type enforcement and multilevel security).
PCACE is, architecturally, similar to LSM in the linux kernel and XACE in in
Xorg but is not an absolute necessity for SELinux integration.
I'm not sure about KaiGai's feelings on this, but it strikes me that
adding SELinux support for the existing levels of access control in PG
might be straight-forward and small enough to include for 8.4 and would
show some commitment to this approach of "do it for PG, add SELinux
checks for it". Alternatively, maybe a progression-towards-SE-PostgreSQL
wiki/webpage that outlines the plan, current work, what's been
committed, etc, that everyone reviews and agrees to?
If you look at the patches you'll see that the bulk of them are adding the
SELinux infrastructure. An access vector cache, the label translation functions,
the libselinux interface and so on. Over 2/3's of the patch is in
src/backend/security.
I'm not sure how much it would cut to remove row level access controls, but I do
have some points here. To me, row level access controls are the most important
part, this is the feature that lets us put secret and top secret data in the
same table and use the clients selinux context to decide what they can see,
transparently and without modification to the application. Without it you have
to use seperate postgres instances, modify the application to select from
different sets of tables depending on their label and so on.
That said, SELinux didn't start out as fine grained as it is today. A fair
number of object classes were present back in '99 when it started but more have
been added over time, the policy infrastructure allows that to happen, in fact
the policy allows object class/permissions to be added, removed and modified if
the access controls were inadequate or unnecessary.
Are you saying enlargement step-by-step, aren't you?
At least, it is far preferable to a death punishment.I would like to here Joshua's opinion also.
namespace collision...
adding SELinux support for the existing levels of access control in PG
is
- table/column level access controls
- permission checks on database login
- permission checks on function invocation
- they need a facility to manage security label
- I want permission checks on loading a library,
though existing PG checks superuser() only.and
- removing PGACE, integrate SEPG code into core
- permission checks on largeobjects is postponed
- row level security is postponed (NOT REJECTED!)
- so, writable system column is also postponedIf summary is necessary, I'll post it tommorow JST.
Because it is not a zero-based implementation, so I believe it can
be minimized within acceptable timescale.As a side-note, I've gotten some extremely positive feedback about
SE-PostgreSQL from folks in my organization who run systems where it
would be used. I'm going to be having a more detailed discussion later
today.
It's good to hear that, I hope you'll ask them how important row level access
controls are.
Joshua Brindle <method@manicmethod.com> writes:
I'm not sure how much it would cut to remove row level access
controls, but I do have some points here. To me, row level access
controls are the most important part, this is the feature that lets us
put secret and top secret data in the same table and use the clients
selinux context to decide what they can see,
For me, the row-level access controls are really the sticking point.
There is absolutely nothing you can say that will convince me that they
don't break SQL in fundamental ways, and I also don't believe that it's
going to be possible to implement them without a constant stream of bugs
of omission and commission. (Those two points are not unrelated.)
Now that you've admitted that you aren't trying to accomplish the
equivalent sort of data hiding within the filesystem, the argument that
you have to have them seems fairly weak, certainly not strong enough to
justify the costs. We have already touched on some ways that you can
accomplish similar goals with just table- and column-level access
permissions, which are well understood and don't violate anyone's
expectations. There's probably a need to twiddle our permissions rules
for inheritance/partitioning cases, but that was already on the table
anyway for other reasons.
I could be persuaded to get behind a patch that does Peter's step #1
(ie, use SELinux permissions as an additional filter for existing SQL
permission checks). I don't believe I will ever think that row-level
checks are a good idea; as long as those are in the patch I will vote
against applying it.
regards, tom lane
Tom Lane wrote:
Joshua Brindle <method@manicmethod.com> writes:
I'm not sure how much it would cut to remove row level access
controls, but I do have some points here. To me, row level access
controls are the most important part, this is the feature that lets us
put secret and top secret data in the same table and use the clients
selinux context to decide what they can see,For me, the row-level access controls are really the sticking point.
There is absolutely nothing you can say that will convince me that they
don't break SQL in fundamental ways, and I also don't believe that it's
going to be possible to implement them without a constant stream of bugs
of omission and commission. (Those two points are not unrelated.)
This isn't going to be something that the vast majority of your users use. The
people that need them understand the ramifications of row filtering and the
absence of inaccessible rows won't be surprising.
Now that you've admitted that you aren't trying to accomplish the
equivalent sort of data hiding within the filesystem, the argument that
We apply access controls on reading and writing files, this is equivalent (in my
mind) to applying access controls on tuples, as they are the structured object
holding data (just like files).
you have to have them seems fairly weak, certainly not strong enough to
justify the costs. We have already touched on some ways that you can
The costs are nil for people who don't want this feature.
accomplish similar goals with just table- and column-level access
permissions, which are well understood and don't violate anyone's
I've already pointed out how table and column level access control don't provide
enough. Holding data of multiple classifications in a single table is something
of great concern. Unmodified applications need to be able to query out of a
table and get the data they are cleared to see. Column level access control
doesn't help because those same applications, of course, will need access to the
data in those columns.
Splitting data into different tables isn't an option in many cases because
applications aren't always configurable wrt to the database or tables they use.
Further, clients of multiple clearances should be able to use the same
application, and we can not trust the application to make the decision as to
which database or table is correct.
And even further, maintaining multiple sets of databases or tables that hold the
same kinds of information (and therefore have the same schema) is a maintenance,
backup and restoration issue.
expectations. There's probably a need to twiddle our permissions rules
for inheritance/partitioning cases, but that was already on the table
anyway for other reasons.
partitions don't help because, once again, the application would be making the
determination about which partition to query. For mandatory access control that
we need in the kind of environments to work the application doesn't get to make
security relevant decisions, the database holds the data and needs to say who
can access it.
Further, partitioning isn't fine grained. I can't say user X can read secret
rows and read/write top secret rows and get that data out in a transparent way
(the applications would have to be aware of the partitions). Relabeling of data
also looks like a challenge with partitions (if I correctly understand how they
work).
I could be persuaded to get behind a patch that does Peter's step #1
(ie, use SELinux permissions as an additional filter for existing SQL
permission checks). I don't believe I will ever think that row-level
checks are a good idea; as long as those are in the patch I will vote
against applying it.
We've already used postgresql in sensitive environments and had to make
compromises because of the lack of fine grained access control. We've been
telling customers for years that we hope postgresql will have said access
controls in the future and that it will help them solve many of the problems
they have.
We've been enthusiastic about the work KaiGai has been doing with respect to the
environments we operate in and it would be a shame for all that to be discarded.
Joshua Brindle <method@manicmethod.com> writes:
partitions don't help because, once again, the application would be making the
determination about which partition to query.
Not necessarily since the database can be programmed to automatically put the
records into the right partition. Right now it's a pain but we're definitely
headed in that direction.
Further, partitioning isn't fine grained. I can't say user X can read secret
rows and read/write top secret rows and get that data out in a transparent way
(the applications would have to be aware of the partitions). Relabeling of data
also looks like a challenge with partitions (if I correctly understand how they
work).
I think the "transparent" is the source of the problem. The application should
issue a query for the data it wants. It shouldn't "transparently" get magic
extra clauses attached to the query. That's where the SQL semantics are being
violated.
Row-level security isn't inherently a problem. It's just that the security is
affecting the data returned that's causing a problem.
I don't think partitioning is really the same thing as row-level security. But
I wonder if some of the same infrastructure could be used for both -- once we
have it.
--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Get trained by Bruce Momjian - ask me about EnterpriseDB's PostgreSQL training!
Gregory Stark <stark@enterprisedb.com> writes:
I don't think partitioning is really the same thing as row-level
security.
Of course not, but it seems to me that it can be used to accomplish most
of the same practical use-cases. The main gripe about doing it via
partitioning is that the user's nose gets rubbed in the fact that there
can't be an enormous number of different security classifications in the
same table (since he has to explicitly make a partition for each one).
But the proposed implementation of row-level security would poop out
pretty darn quick for such a case, too, and frankly I'm not seeing an
application that would demand it.
regards, tom lane
On Wed, Jan 28, 2009 at 01:49:21PM -0500, Joshua Brindle wrote:
use. The people that need them understand the ramifications of row
filtering and the absence of inaccessible rows won't be surprising.
I wish there was even a little bit of evidence that users of a
security system may be relied upon to understand its implications and
effects. In my experience, however, they often don't.
you have to have them seems fairly weak, certainly not strong enough to
justify the costs. We have already touched on some ways that you canThe costs are nil for people who don't want this feature.
That's also false, because developers who don't care about the feature
have to continue to maintain it as part of the system. If maintenance
were free, I suspect nobody would be objecting to the feature. But
this feature will in fact constrain future development and will impose
maintenance requirements on the programmers of the system. Those
maintenance requirements in turn amount to a cost that every user has
to pay, because time spent addressing issues that result from this
feature (or accommodating it in new development) is time that is not
spent on other problems users might face.
If I imagined I were project manager of the PostgreSQL project (a
preposterous supposition, let me be clear), then I'd be very worried
that this feature, which is apparently poorly understood by at least
one big contributor to the project, would amount to a significant drag
on future development work. In that case, I'd have to ask why having
this feature as part of the main line of PostgreSQL is a good
trade-off. Happily, I'm not someone who has to make that
determination, so I can't say whether it _is_ a good trade-off. But I
think that's what the resistance to the feature is all about, so
you'll need to make the case that the trade-off is a good one.
A
--
Andrew Sullivan
ajs@crankycanuck.ca
Andrew Sullivan <ajs@crankycanuck.ca> writes:
On Wed, Jan 28, 2009 at 01:49:21PM -0500, Joshua Brindle wrote:
The costs are nil for people who don't want this feature.
That's also false, because developers who don't care about the feature
have to continue to maintain it as part of the system. If maintenance
were free, I suspect nobody would be objecting to the feature. But
this feature will in fact constrain future development and will impose
maintenance requirements on the programmers of the system.
Right. The major implementation problem I have with row-level security
is that it will require sticking its hands into every part of the
backend; at least if you want it to be actually *secure* with no holes,
and if not I guess I'm failing to grasp the point. Every future patch
will have to be vetted to ensure that it's not accidentally breaking
that security. This stems directly from the fact that you're trying to
impose behavior that's fundamentally at odds with SQL, and therefore
there isn't any well-defined choke point at which you could apply the
checks and be done with it. The system simply isn't modularized that
way. (Of course we could throw it all away and start over...)
BTW, in regard to the upthread question about how much of the patch
could be discarded if we removed row-level security: having now taken
another look through it, I'd put the fraction at well north of 90%.
(That's exclusive of the security policy file, which I don't understand
at all and so can't tell how much might be specific to row security.)
What's worse, the current patch footprint is conservative because the
placement of hooks is simply wrong. You can't usefully apply checks in
simple_heap_insert, for example, since it has no idea who called it or
why. It's got to be done at a higher level and therefore in a lot more
places. And I don't see any attempt at all to restrict system-driven
fetches, yet surely there has to be some control over that (otherwise
why are we worrying about system-driven updates?)
regards, tom lane
Sorry for top-posting and avoiding to paste online doc URL.
Joshua, you sound like you're missing an important point. Sorry for
misunderstanding if that's not true.
Partitioning is supported in a way that a query does not need to know
about it, be it a SELECT, INSERT, UPDATE or DELETE. And 8.4 onwards,
some more.
What Tom is talking about is adding support for discarding partitions
based on GRANTed rights rather than WHERE clauses.
No application rewrite.
Columns obfuscating remains to be cared of: what about allowing views
as partitions?
HTH, regards,
--
dim
Le 28 janv. 09 à 19:49, Joshua Brindle <method@manicmethod.com> a
écrit :
Show quoted text
Tom Lane wrote:
Joshua Brindle <method@manicmethod.com> writes:
I'm not sure how much it would cut to remove row level access
controls, but I do have some points here. To me, row level access
controls are the most important part, this is the feature that
lets us
put secret and top secret data in the same table and use the clients
selinux context to decide what they can see,For me, the row-level access controls are really the sticking point.
There is absolutely nothing you can say that will convince me that
they
don't break SQL in fundamental ways, and I also don't believe that
it's
going to be possible to implement them without a constant stream of
bugs
of omission and commission. (Those two points are not unrelated.)This isn't going to be something that the vast majority of your
users use. The people that need them understand the ramifications of
row filtering and the absence of inaccessible rows won't be
surprising.Now that you've admitted that you aren't trying to accomplish the
equivalent sort of data hiding within the filesystem, the argument
thatWe apply access controls on reading and writing files, this is
equivalent (in my mind) to applying access controls on tuples, as
they are the structured object holding data (just like files).you have to have them seems fairly weak, certainly not strong
enough to
justify the costs. We have already touched on some ways that you canThe costs are nil for people who don't want this feature.
accomplish similar goals with just table- and column-level access
permissions, which are well understood and don't violate anyone'sI've already pointed out how table and column level access control
don't provide enough. Holding data of multiple classifications in a
single table is something of great concern. Unmodified applications
need to be able to query out of a table and get the data they are
cleared to see. Column level access control doesn't help because
those same applications, of course, will need access to the data in
those columns.Splitting data into different tables isn't an option in many cases
because applications aren't always configurable wrt to the database
or tables they use. Further, clients of multiple clearances should
be able to use the same application, and we can not trust the
application to make the decision as to which database or table is
correct.And even further, maintaining multiple sets of databases or tables
that hold the same kinds of information (and therefore have the same
schema) is a maintenance, backup and restoration issue.expectations. There's probably a need to twiddle our permissions
rules
for inheritance/partitioning cases, but that was already on the table
anyway for other reasons.partitions don't help because, once again, the application would be
making the determination about which partition to query. For
mandatory access control that we need in the kind of environments to
work the application doesn't get to make security relevant
decisions, the database holds the data and needs to say who can
access it.Further, partitioning isn't fine grained. I can't say user X can
read secret rows and read/write top secret rows and get that data
out in a transparent way (the applications would have to be aware of
the partitions). Relabeling of data also looks like a challenge with
partitions (if I correctly understand how they work).I could be persuaded to get behind a patch that does Peter's step #1
(ie, use SELinux permissions as an additional filter for existing SQL
permission checks). I don't believe I will ever think that row-level
checks are a good idea; as long as those are in the patch I will vote
against applying it.We've already used postgresql in sensitive environments and had to
make compromises because of the lack of fine grained access control.
We've been telling customers for years that we hope postgresql will
have said access controls in the future and that it will help them
solve many of the problems they have.We've been enthusiastic about the work KaiGai has been doing with
respect to the environments we operate in and it would be a shame
for all that to be discarded.--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Jan 28, 2009 at 3:58 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Andrew Sullivan <ajs@crankycanuck.ca> writes:
On Wed, Jan 28, 2009 at 01:49:21PM -0500, Joshua Brindle wrote:
The costs are nil for people who don't want this feature.
That's also false, because developers who don't care about the feature
have to continue to maintain it as part of the system. If maintenance
were free, I suspect nobody would be objecting to the feature. But
this feature will in fact constrain future development and will impose
maintenance requirements on the programmers of the system.Right. The major implementation problem I have with row-level security
is that it will require sticking its hands into every part of the
backend; at least if you want it to be actually *secure* with no holes,
and if not I guess I'm failing to grasp the point. Every future patch
will have to be vetted to ensure that it's not accidentally breaking
that security. This stems directly from the fact that you're trying to
impose behavior that's fundamentally at odds with SQL, and therefore
there isn't any well-defined choke point at which you could apply the
checks and be done with it. The system simply isn't modularized that
way. (Of course we could throw it all away and start over...)BTW, in regard to the upthread question about how much of the patch
could be discarded if we removed row-level security: having now taken
another look through it, I'd put the fraction at well north of 90%.
(That's exclusive of the security policy file, which I don't understand
at all and so can't tell how much might be specific to row security.)
What's worse, the current patch footprint is conservative because the
placement of hooks is simply wrong. You can't usefully apply checks in
simple_heap_insert, for example, since it has no idea who called it or
why. It's got to be done at a higher level and therefore in a lot more
places. And I don't see any attempt at all to restrict system-driven
fetches, yet surely there has to be some control over that (otherwise
why are we worrying about system-driven updates?)
I'm not clear that I understand why it would be necessary for
row-level security to touch every part of the code. If the current
implementation requires that, then maybe that's a defect in the
implementation rather than an inherent problem with row-level
security. It seems to me that the crucial decision is "Where are we
trying to erect the security wall?". If we're trying to put it
between the client and the postgres backend, then maybe the right
thing to do is apply some sort of processing step to each query that
is submitted, essentially rewriting "SELECT * FROM a, b" as "SELECT *
FROM a, b WHERE you_can_see(a.securityid) AND
you_can_see(b.securityid)". Maybe you (Tom) still won't like this
because it breaks SQL semantics, but it seems like it would at least
centralize the code. Unless I'm totally off base here?
...Robert
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
For me, the row-level access controls are really the sticking point.
There is absolutely nothing you can say that will convince me that they
don't break SQL in fundamental ways, and I also don't believe that it's
going to be possible to implement them without a constant stream of bugs
of omission and commission. (Those two points are not unrelated.)
And, just to go full circle, row-level access controls are exactly what
the other enterprise RDBMSs have and is what is used in these security
circles today. One of the major issues, as I understand it, is to be
able to use stock applications with multiple security levels where the
application doesn't know (or care about) the security level. Doing that
through views and partitions and triggers and whatnot for each and every
application that is run on these systems will be a big hurdle to those
users, if it ends up being workable at all.
Thanks,
Stephen