EarthScope / ringserver

Apache License 2.0
30 stars 16 forks source link

Authorization via JWT tokens #21

Closed crotwell closed 2 years ago

crotwell commented 5 years ago

Add datalink AUTHORIZATION command for non-IP based WRITE permission based on JWT token.

chad-earthscope commented 5 years ago

In concept, this is pretty cool, thanks. Given the dependencies, this would need to be optional in the build process.

If I understand correctly, the code as is only allows a single, static key (in authdir/secret.key). If so it's limited to a single write authorization with a single pattern. Ideally, we'd want more flexibility.

crotwell commented 5 years ago

Yes, more dependencies. Also my C and makefile skills were limited enough I didn't try to deal with the dependency compilation. I just did the simplest possible thing to get it working.

No, there can be many tokens signed by the same secret. Think of the secret key not as a password but as a password to generate and verify the tokens. JWT tokens are a digital signature based system. So to create a new token you create a snippet of json like

    {
        'exp': <expire time>,
        'iat': <issue time>,
        'sub': <subject>,
        'wpat': <writePattern>
    }

exp, iat, and sub are more or less standard keys, I added wpat for the write pattern and there could easily be a rpat for the read pattern. Then the payload is digitally signed using the secret. A header showing the algorithm, the payload and the signature are then encoded as 3 base64 strings separated by periods and given to the client. All this happens external to ringserver. See for example encodeAuthToken in simpleDali.py.

The client on making a connection does a AUTHORIZATION command and sends in the token. The ringserver extracts the payload, verifies the signature matches the payload using its secret key, and then uses the values. The payload is not encrypted, but the client can't modify it to give themselves more privileges as then the signature would not match.

jwt.io has a good overview.

I put the secret key in a "auth" directory because I was thinking there may be other things that need a place to live, like maybe tokens that the server decided to invalidate before their expiration time or maybe stuff related to token creation. I didn't get around to any of that, but securing a single directory seemed easier than maybe securing multiple files.

This read pattern would be a nice match I think for making restricted data available in real time via the ringserver. Or another use would be for a network to run a ringserver with no public read access, but then give the DMC a read token to allow you to pull the data for archiving.