[openstack-dev] [Manila] Share allow/deny by shared secret

John Spray jspray at redhat.com
Tue Oct 27 06:58:17 UTC 2015

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
> access.
>> 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
> identities.

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").


More information about the OpenStack-dev mailing list