
Ask HN: Can A give permission to C to access B, without B talking to A? - mangeletti
### Context<p>I&#x27;m Alpha server, and I can grant permission to access things on Beta server at any point in the future, but I can only talk with Beta server one time, during initial setup (to share a secret, etc.).<p>Gamma server can talk to me and to Beta server any time. I can also give Gamma server instructions.<p>### Scenario<p>Gamma server comes to Beta server and says, &quot;let me in&quot;. Beta server says, &quot;go ask Alpha server for permission and return with proof of permission&quot;.<p>### Question<p>How can the above scenario be achieved? Does this type of permission mechanism already have a name? Would it simply require some shared secret between Alpha server and Beta server and some sort of hash calculation?<p>I&#x27;d also like the permission to expire after a certain period of time (or at a specific datetime).<p>### Notes<p>I realize this has similarities to OAuth 2, but since Alpha server can only speak to Beta server one time ever (initial setup), OAuth 2 cannot be used.
======
patio11
There exist a variety of ways to do this. How complicated do you want it to
be, and how many other concerns does this implicate? Does Gamma have to auth
as actually being Gamma to Beta or is that out of scope? etc

The most straightforward way to be is (duh duh) public key crypto. GPG is
fine. Gamma talks to Alpha. Alpha tells Gamma: "Give this message to Beta: 'I
trust Gamma. Nonce: whatever.' Here's the corresponding signature." Beta has
pre-arranged to have Alpha's public key. On presentation of Alpha's message
from Gamma and verification of the signature, Beta extends trust to Gamma.

There are a variety of ways to screw this up. Don't roll your own crypto
primitives. It is highly likely you have consequential requirements which
break the design of this cryptosystem, like e.g. requiring the ability for
Alpha to say "Nah, actually, changed my mind about Gamma. They're not
authorized anymore."

~~~
mangeletti
Thanks for your reply. Pertaining your last point, I've actually already added
some scope creep to the OP (see the second paragraph of the question section,
pertaining expiration, etc.).

~~~
kmowery
That's still fairly straightforward; change the message A signs to "I trust
Gamma. Nonce: whatever. Valid Until: DateTime". B should then 1) check the
signature and 2) check the datetime (in that order).

------
e12e
Is this a homework question on HN?

[http://en.wikipedia.org/wiki/File:Kerberos.svg](http://en.wikipedia.org/wiki/File:Kerberos.svg)

I generally frown on the "need" for higher education as a requirement for
work, but this is pretty basic stuff?

On the off chance that it wasn't, perhaps you want to look into ssh
certificates (as an alternative to kerberos), or CAS for a way to deploy
something kerberos-like for web:

[http://jasig.github.io/cas/4.0.x/protocol/CAS-
Protocol.html](http://jasig.github.io/cas/4.0.x/protocol/CAS-Protocol.html)

For web, one of the big issues with login is managing both Single-Sign On (eg:
you can be logged into an authentication provider like gmail or facebook, and
then not have to authenticate again (with eg. login/pw) to use a different
service (like... um... blogger or flickr or something that delegates
authentication (who you are), and does authoriation based on that (now that I
know who you are, what are you allowed to do).

And managing Single-Sign Out: when you log out from one service, all
tokens/sessions etc are logged out. So if you click logout in flickr, you're
also logged out from facebook.

As for ssh certificates, they (can) AFAIK embed information on who you are
(uid) and where you can log in from (source-ip), and where you can log in to
(uid@host), along with an expiry date. The client gets a cert from the CA, the
ssh server gets a cert from the CA, and the ssh server can look at the cert
and see a) it's valid, b) it's valid for user X, c) it's valid for user X from
ip n.n.n.n and d) it's valid for user X@server.

It does not allow for too fine grained delegation of authorization without
some other method (eg: communication between the ssh server and a trusted
authority, like radius, ldap etc).

[ed: as others noted, see also x509, of which ssh certs is a simplification,
intended for use with ssh]

~~~
mangeletti
Thanks for the reply. This is not homework. I'm actually trying to find a
solution for something at work, and I've never had work on something like
this.

~~~
e12e
In which case, you might want to supply us with a little more detail. Last I
looked (it's been a while) CAS seemed the most sane choice for something like
this for an intranet-ish thing over http(s!) -- if you can't just use ssh and
ssh certs (obviously very different use cases).

Does anyone have any insight to what the state of the art is marrying kerberos
ideas and nacl? I found this:

[http://www.slideshare.net/pieterh/zeromq-
security](http://www.slideshare.net/pieterh/zeromq-security)

But it is obviously somewhat dated now -- did zeromq+sasl+nacl go anywhere? In
what form? I'd hoped that this would "get sorted" and allow saltstack to
leverage something a little more standard (which would alleviate my last
doubts about salt -- but my fears might be unfounded -- I've just not seen
anything that really addresses the early issues they had with
security/transport/encryption).

Anyone using:
[https://github.com/zeromq/libcurve](https://github.com/zeromq/libcurve) in
anger?

Finally, I can't resist posting this soundtrack that I had serendipitously
playing in the background as I read the above slidedeck: "Nothin' \- Townes
Van Zandt". Seemed oddly appropriate to go along with forward secrecy:

[https://www.youtube.com/watch?v=zZcH2OOMV4A](https://www.youtube.com/watch?v=zZcH2OOMV4A)

~~~
mangeletti
I wanted to understand the problem at an abstract level, rather than
describing my exact use case, leading people into digressions, debates, etc.

Also note, I answered my own question with HMAC being the probable solution
(before anyone else mentioned HMAC), and others seemed to verify that this
might be the best fit by answering with the same thing shortly thereafter. If
I can give permission and I only need to provide permission, the only thing I
only need is a way to transmit a message and prove that it wasn't modified
while in-transit.

------
captn3m0
Use HMAC. The shared secret key can be used to sign messages and they can be
verified. Basically, every Gamma server has a id. This id is converted into a
message (which includes expiry time). This message is then signed by the Alpha
server.

Gamma server takes this response+signature back to Beta server. Beta server
verifies this and grants access. Depending on your design, you could have this
signature sent on every request, or accept the message as confirmed and add it
to beta server's knowledge (so next time gamma can authenticate much more
easily via methods such as sessions or cookies or tokens).

ie, Beta issues a token to Gamma once Gamma presents proof. The token is
internally linked in Beta's knowledge to a certain expiry date and Gamma's ID.
For every next request, Gamma simply presents this token.

------
dragonwriter
I think a couple suggestions already point this way, but this I think is more
detailed (which may or may not be helpful):

When A talks to B the one time it is allowed to, it gives B an X.509
certificate to which A holds the private key for each role for which A is
permitted to delegate access on B. A later gives C a certificate, signed with
the appropriate private key, for each role on B to which it is delegating
access to C.

C then presents the appropriate certificate to B with any operation, proving
that it has been authorized.

(You can do this with just one certificate for each A->B and A->C->B if you
identify the roles within the certificate, which is technically doable within
X.509 but I think requires going through IANA to get official identifiers for
each role to be delegated -- these would be identified in the certificate A
gives to C to present to B -- which may or not be practical.)

~~~
e12e
Does anyone have happy memories using SAML for anything remotely useful? It
always struck me as possibly even more convoluted to get right than x.509 (and
recall eg: python not validation server host names in certs by default for a
long, long time -- so getting x.509 right in production isn't exactly trivial
-- especially if you're not a domain expert).

That said, yes I think SAML could be leveraged to fulfill the requirements in
the question. I just think it would be quite painful ;-)

------
amalcon
This is more-or-less the problem that X.509 solves. Consider the SSL
certificate case. In this case, A is the certificate authority, C is the
server or organization receiving the connection, and B is "the ability to
authenticate as some specific hostname".

For a less abstract comparison, consider a VPN. Let's say I have OpenVPN
running on a server somewhere (B). I keep the CA on another system (A). If I
want to give my laptop (C) access to the VPN (B), all I need to do is generate
a new certificate on C and sign it with the CA I keep on A. B will then accept
the certificate with no direct message from A.

X.509 might be overkill for what you're trying to do, but the upside is that
there is a lot of software for working with it, so you won't need to roll your
own solution.

------
mangeletti
It seems the answer _could_ be to use HMAC. Perhaps, others could expand on
this?

~~~
anfedorov
You certainly could. If you want to add something more complicated like an
expiration time to prevent replay attacks, it might be a good use case for
JSON Web Tokens: [http://jwt.io/](http://jwt.io/)

~~~
captn3m0
I've always wanted to try JWT. This seems like a nice usecase.

------
ebbv
Yes you can absolutely do this. Alpha server has a private key which Beta also
knows, it uses the private key to sign an authorization ticket for Gamma.
Gamma has its own public key which it gives to Alpha when it requests access.
The ticket could look like this as an example:

    
    
        signature = sha256(gammaskey + starttime + endttime + privatekey);
        request = { key: gammaskey, start: starttime, end: endtime, signature: signature };
    

Gamma then sends the request to Beta, Beta can verify authorization by making
the signature itself and verifying it matches.

------
fl0wenol
In this scenario, is gamma a single server making requests of Beta under a
single authorization?

Or is it a stand in for multiple remote resource consumers with potentially
different things happening under different authorizations/identities which may
require Alpha to say, "You there, Gamma_3 running a job for Mr. Manager, you
are allowed to eat those Beta cookies, here's your voucher!" versus "Hey,
Gamma_5 running a job for Ms. Accountant, you are not allowed to have cookies,
did you want this spreadsheet Beta has?"

------
jlank
This sounds a lot like SAML (Security Assertion Markup Language) Alpha = IdP,
Beta = Service Provider, Gamme = a user or some server requesting access to
Beta's data or services. Alpha would contain a set of ACL's (Access Control
Lists) that prescribe what groups / users have access to what content or
services on B.

[http://en.wikipedia.org/wiki/Security_Assertion_Markup_Langu...](http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language)

------
halayli
I would suggest using PKI certificate extensions and create an extension in
the certificate that has a list of permissions. Beta Server provides a
certificate to Gamma server with the permissions it has, and after validation,
it will look into a custom extension that has all the permissions Beta server
is granted.

The good thing here is that you don't need Alpha server anymore.

------
eof
yes. the permission access is as strong as a shared_secret between Alpha and
Beta.

    
    
        shared_secret
        AUTH_TOKEN=HASH(shared_secret + challenge_string)
    

when Gamma asks for access to Beta, Beta gives a unique challenge_string, and
says "give me AUTH_TOKEN and I will let you in":

    
    
      Gamma -> Beta
        "let me in"
      Beta -> Gamma
        challenge_string = "dlkjaflkjaflkjflkjflfkjflkj"
        "give me AUTH_TOKEN and I will let you in"
    
      Gamma -> Alpha
        challenge_string = "dlkjaflkjaflkjflkjflfkjflkj"
        "can you give me AUTH_TOKEN?"
    
      Alpha -> Gamma
        AUTH_TOKEN= HASH(shared_secret + "dlkjaflkjaflkjflkjflfkjflkj")
        "here is AUTH_TOKEN"
    
      Gamma -> Beta
        "here is AUTH_TOKEN and challenge_string let me in"
    
      Beta -> Gamma
         if (AUTH_TOKEN == HASH(SHARED_SECRET+CHALLENGE_STRING)
            "you can come in"
         else
            "no"

------
cmpb
I'm not entirely certain, but I believe this is a major use case of Macaroons
third-party caveats.

[http://hackingdistributed.com/2014/05/16/macaroons-are-
bette...](http://hackingdistributed.com/2014/05/16/macaroons-are-better-than-
cookies/)

------
schoen
I think Kerberos can be used in this kind of structure (with Kerberos
tickets), but I should double-check that it doesn't require the ticket issuer
to interact with the resource that's the subject of the tickets.

~~~
anishathalye
Kerberos should work in this situation. After setting up initial secrets, the
Kerberos master/TGT service doesn't need to communicate with servers.

