cross-model relation anonymization is incompatible with authorization

Bug #1751279 reported by Stuart Bishop
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Canonical Juju
Triaged
Low
Unassigned

Bug Description

If a provider does not know who a consumer is, then the provider cannot authorize the consumer's access to any shared data. The provider could allow the consumer to create new data, but access to any shared or pre-existing data needs to be restricted.

Some charms and services do not handle authorization. If a client unit has been given authentication credentials to Cassandra, then they can access all the data in Cassandra. There is no authorization, just authentication.

Other charms do handle authorization. If a client unit is given authentication credentials to PostgreSQL, then they can only access the tables they create or have been granted access to by other PostgreSQL users. MySQL is similar, as are likely MongoDB and other databases.

A problem occurs when doing redeployments, either redeploying a client application or redeploying a service (such as PostgreSQL, redeploying using existing data from persistent Juju storage). When the client is reconnected to PostgreSQL, PostgreSQL needs to provide them the same authentication credentials as before so the client can access its data. This was quite simple - PostgreSQL and MySQL just used the client application name as the username, and if the client was redeployed with the same name it would be given access to the same database user and would have access to the same data. These charms rely on extracting the remote application name from the $REMOTE_UNIT environment variable in the hook context.

With cross model relations, it was decided that the relation between client and server should be anonymized. $REMOTE_UNIT is now a UUID, and the server does not know the remote client application's name by design. The server now lacks the only trusted information it had, and has no way of providing the correct credentials to a client. Now, when clients are related they must be handed fresh credentials with no access to any existing data.

The relation data set by the client is also untrusted, so the client cannot instruct the server who it is and what privileges it should be granted. The relation data cannot be trusted, because it can be altered by a compromised client and this would allow a compromised client to escalate is privileges.

If anonymization needs to remain, then providers in this situation need some way to de-anonymize the relation. One way would be an action, allowing the operator of the provider charm to map anonymized relations to credentials (so for PostgreSQL, an action that lets you specify which database user a relation should be using). This is more explicit and provides advantages to the $REMOTE_USER heuristic, but does increase operator burden. It also begs the question if anonymization should be done in the first place, given there are charms that cannot be operated securely without de-anonymization.

Revision history for this message
John A Meinel (jameinel) wrote : Re: [Bug 1751279] [NEW] cross-model relation anonymization is incompatible with authorization
Download full text (3.7 KiB)

The postgres charm could generate a unique identifier that cannot really be
guessed (UUID, 256 bytes of random data). And then trust that only a client
that knew that data would be able to present it back to postgres.
(it's essentially just password auth, instead of username auth)

Wouldn't that work?

John
=:->

On Feb 23, 2018 18:01, "Stuart Bishop" <email address hidden> wrote:

> Public bug reported:
>
> If a provider does not know who a consumer is, then the provider cannot
> authorize the consumer's access to any shared data. The provider could
> allow the consumer to create new data, but access to any shared or pre-
> existing data needs to be restricted.
>
> Some charms and services do not handle authorization. If a client unit
> has been given authentication credentials to Cassandra, then they can
> access all the data in Cassandra. There is no authorization, just
> authentication.
>
> Other charms do handle authorization. If a client unit is given
> authentication credentials to PostgreSQL, then they can only access the
> tables they create or have been granted access to by other PostgreSQL
> users. MySQL is similar, as are likely MongoDB and other databases.
>
> A problem occurs when doing redeployments, either redeploying a client
> application or redeploying a service (such as PostgreSQL, redeploying
> using existing data from persistent Juju storage). When the client is
> reconnected to PostgreSQL, PostgreSQL needs to provide them the same
> authentication credentials as before so the client can access its data.
> This was quite simple - PostgreSQL and MySQL just used the client
> application name as the username, and if the client was redeployed with
> the same name it would be given access to the same database user and
> would have access to the same data. These charms rely on extracting the
> remote application name from the $REMOTE_UNIT environment variable in
> the hook context.
>
> With cross model relations, it was decided that the relation between
> client and server should be anonymized. $REMOTE_UNIT is now a UUID, and
> the server does not know the remote client application's name by design.
> The server now lacks the only trusted information it had, and has no way
> of providing the correct credentials to a client. Now, when clients are
> related they must be handed fresh credentials with no access to any
> existing data.
>
> The relation data set by the client is also untrusted, so the client
> cannot instruct the server who it is and what privileges it should be
> granted. The relation data cannot be trusted, because it can be altered
> by a compromised client and this would allow a compromised client to
> escalate is privileges.
>
> If anonymization needs to remain, then providers in this situation need
> some way to de-anonymize the relation. One way would be an action,
> allowing the operator of the provider charm to map anonymized relations
> to credentials (so for PostgreSQL, an action that lets you specify which
> database user a relation should be using). This is more explicit and
> provides advantages to the $REMOTE_USER heuristic, but does increase
> operator burden. It also begs the question if anony...

Read more...

Revision history for this message
Stuart Bishop (stub) wrote :

@jameinel The operator of the client charm would need to backup the token somewhere, so it could be reused when redeploying. Every client charm would need to provide some mechanism to retrieve the token. I think the user experience here is worse than adding an action on the server to map relations to credentials (which certainly isn't ideal, but possible).

Revision history for this message
John A Meinel (jameinel) wrote :

I think this is certainly something worth thinking about. The difficulties of "not allowing clients to say who they want to access as", but needing the ability to re-use a pre-existing identity is difficult.
Even if we didn't have anonymization, cross-model relations would mean that each new deploy should show up as a different identity. I suppose you could try to set up a chain-of-trust that "I am application foo in model UUID X-Y-Z", and find a way to trust that nobody else could pretend to be a model UUID X-Y-Z with name foo.

You sort of have implicit trust in the single-model case, as whoever deployed 'postgresql' has the same access permissions as whoever deployed its client.

However, CMR explicitly means you have different access control lists (even on the same controller).

It still feels to me that the only way you can really do it is to default each application as getting a unique identifier, generated by the authorizing charm, which can then be saved by the operator, and supplied as config in a future deployment.

We could certainly make it more straigtforward to manage this information (having to run 'juju run relation-get' is not a pleasant way to get information.)

Changed in juju:
importance: Undecided → Medium
status: New → Triaged
Revision history for this message
Stuart Bishop (stub) wrote :

per-relation configuration may be a solution, which has been discussed in the past. If the operator could 'juju relation-set postgresql db:0 dbuser=foo', we would have a standard mechanism for charms to use to allow operators to assign an identity to a remote charm. TBH I'm not sure if this is a major UX improvement over adding an action to do the same thing (juju run-action --wait --leader postgresql set-dbuser relation=db:0 user=foo)

Revision history for this message
Stuart Bishop (stub) wrote :

(By per-relation configuration, I mean configuration attached to the relation that may be set by the operator. Unlike relation-set, which can be modified by the charm and other code running in the container and for ACL purposes should be considered untrusted)

Revision history for this message
Stuart Bishop (stub) wrote :

(although PostgreSQL could certainly trust the data it finds in the PostgreSQL side of the relation settings, the UX is quite poor and the data propagated as new units are brought up)

Revision history for this message
Stuart Bishop (stub) wrote :

I have discovered that it works fine to make the offer in the client model, and consume it into the server model using a name of your choosing (ie offer the client rather than the more obvious offer the service). So charms using the remote application name can continue to do so using CMR, provided they are in the consuming model, and no functionality has been lost. It is still not ideal, but we are in the same situation as without CMR.

juju add-model client
juju deploy cs:~postgresql-charmers/postgresql-client psql
juju offer psql:db client-db
juju add-model server
juju deploy cs:postgresql
juju consume admin/client.client-db psql
juju add-relation postgresql:db psql:db # Exactly like it is today without CMR

Revision history for this message
Canonical Juju QA Bot (juju-qa-bot) wrote :

This bug has not been updated in 2 years, so we're marking it Low importance. If you believe this is incorrect, please update the importance.

Changed in juju:
importance: Medium → Low
tags: added: expirebugs-bot
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.