[openstack-dev] [Manila] Share allow/deny by shared secret
ben at swartzlander.org
Wed Oct 28 01:32:55 UTC 2015
On 10/27/2015 02:58 AM, John Spray wrote:
> On Tue, Oct 27, 2015 at 6:39 AM, Ben Swartzlander <ben at swartzlander.org> wrote:
>>> The NFS-style process that Manila expects is:
>>> Caller> I know a credential (IP address, x509 certificate) and I want
>>> you to authorize it
>>> Driver> OK, I have stored that credential and you can now use it to
>>> access the share.
>> This is accurate. Manila presumes the existence of an external
>> authentication mechanism which servers can use to identify clients, so that
>> Manila's role can be limited to telling the server which clients should have
>>> The Ceph native process is more like:
>>> Caller> I want to access this share
>>> Driver> OK, I have generated a credential for you, here it is, you can
>>> now use it to access the share
>>> The important distinction is where the credential comes from. Manila
>>> expects it to come from the caller, Ceph expects to generate it for
>>> the caller.
>> The problem with the above statement is that you don't define who "I" am.
> I think my "I" concept here is the all-powerful (within his own
> tenancy) manila API consumer who is taking on the responsibility to
> know about the external entities (like guests, groups of guests).
>> The Manila API client is all-powerful when it comes to modifying access
>> rules, insofar as a tenant has the power to add/remove any rule from any
>> share that that tenant owns. Obviously if you have access to modify the
>> access rules then you have de-facto access to all the shares. The purpose of
>> the access-allow/deny APIs is to delegate access to shares to identities
>> that exist outside of Manila, such as to IP addresses, to users, or to x509
>> principles. These things need to be named somehow so that the file system
>> server, the client, and manila can all talk about the same set of
> The thing making delegation of access control awkward here is that
> Ceph is both the provider of the storage and also the provider of the
> authentication: there is no external entity (an IP network, an x509
> CA) that we defer to. If the authentication was to an external
> system, it would make sense to say that clients should first configure
> their identity externally, and then call into Manila to authorize that
> identity. When the system of identities is built into the storage
> system, having the API consumer call out to create their identity
> would leave them talking directly to Ceph, in addition to talking to
> Ceph via Manila.
> I should point out that it would also be possible to extend the Ceph
> interface to allow users to pass in their own generated key. In this
> case we could have API consumers generate their own secrets, and pass
> them into ceph. So your access id would be something like
> "alice/a7df6d76d57f". The Ceph driver would then have to create the
> alice identity in ceph if it didn't already exist, and throw an error
> if the existing alice identity wasn't already using that particular
> shared secret. This isn't ideal from a security POV, because it
> relies on Manila API consumers to have a suitable source of
> randomness, and it's less than ideal usability because they have to
> know the expected size/format of the secret.
> The usability part is a big concern for me: there's a huge leap
> between "pick an ID and pass it into authorize" and "pick an ID, and
> generate a cryptographically secure random number N bytes long,
> concatenate it with the ID like so and pass it into authorize".
> Either we rely on users to get it right (a bit optimistic) or we have
> to give them a library for generating it (which isn't very RESTful).
>>> To enable us to expose ceph native auth, I propose:
>>> * Add a "key" column to the ShareAccessMapping model
>>> * Enable drivers to optionally populate this from allow() methods
>>> * Expose this to API consumers: right to see a share mapping is the
>>> right to see the key.
>>> The security model is that the key is a secret, which Manila API users
>>> (i.e. administrative functions) are allowed to see, and it is up to
>>> them to selectively share the secret with guests. The reason for
>>> giving them allow/deny rather than just having a key per share is so
>>> that the administrator can selectively revoke keys.
>> I don't see why the driver should be the place where secrets are generated.
>> It seems equally valid for the caller of the Manila API to generate the
>> secret himself, and to ask Manila to grant access to a share to anyone
>> knowing that secret. This would fit the existing model, and more
>> importantly, it would allow granting of shares to multiple users with
>> different secrets. I don't see in the above proposal how to grant access to
>> a share to both Alice and Bob without telling the same secret to both Alice
>> and Bob. The problem that creates is that I can't revoke access to the share
>> from Alice without also revoking access from Bob. Maybe I'm misreading what
>> you wrote above about key revocation, but it sounds like you have 1 key per
>> share, and you can revoke access to each share individually, but if you have
> Ah, no -- I think I wasn't clear enough about this part. We wouldn't
> have one key per share. You can have as many keys as you want. In
> the change I was proposing, callers could "allow alice to share X" and
> get one key, then "allow bob to access share X" and you'll get a
> second key. If you then "allow alice to share Y" you'll get Alice's
> key again (same as for share X), but you'll now find that the key lets
> you into share Y too. In this example, alice and bob are arbitrary
> client names that the API caller has made up. In practice I would
> imagine API callers' would use things like names of guest instances,
> names of groups of guest instances associated with a particular
>>> The "key" column should be pretty short (255 chars is plenty) -- this
>>> isn't meant for storing big things like PKI certificates, it's
>>> specifically for shared secrets.
>>> I don't know of any other drivers that would use this, but it is a
>>> pretty generic concept in itself: "grant access by a shared key that
>>> the storage system generates".
>> I'm not opposed to the idea of modifying the Manila API to make your use
>> case possible, but I want to make sure there's not a better way to solve the
>> problem first, and I also want to make sure that the we're solving the
>> problem in the right way. Supporting multiple users accessing multiple
>> shares is an important use case and I'm not clear on how this proposal
>> addresses that.
> I think this probably comes down to a balance between the API purity
> of delegating auth to external identities, and the Ceph case where the
> "external" identity management is within the storage system. I'm
> hoping we can define a sufficiently small change to make the Ceph case
> slick without causing much disruption -- looking forward to discussing
> face to face tomorrow (I noticed one of the work sessions has been
> marked for "Access Allow/Deny Driver Interface").
Okay is sounds like you do have scheme in mind for supporting multiple
users. In that case I'm wondering who's responsibility it is to remember
existing users and their secrets. In the example above, when Alice is
granted access to share Y, the system somehow knew that Alice already
existed and was able to retrieve her secret. This implies the existence
of an authentication database that lives somewhere. As long as that
database lives outside Manila (and I hope it does, otherwise it
represents significant new state to track) then that's the "external
authentication mechanism" I was referring to at the top of my original
I see no problem with Manila manipulating an external authentication
database, such as a mapping of user names to secrets, and manipulating
the access tables in the storage system (which is the whole point of the
access APIs). The only remaining question, then, is does it makes sense
for Manila to also be the conduit for informing the API client about
newly-generated secrets for users, or could the caller of the Manila API
obtain that information another way, allowing us to avoid changing the API.
Indeed we have a session today called "Access Allow/Deny Driver
Interface" but the goal of that session is to discuss changing the
driver interface, not the REST API. If we have extra time we can also
discuss this topic.
> OpenStack Development Mailing List (not for usage questions)
> Unsubscribe: OpenStack-dev-request at lists.openstack.org?subject:unsubscribe
More information about the OpenStack-dev