Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

We are tentatively planning to use SASL.

Different authentication mechanisms will be available on different ports. We will continue to support the existing unauthenticated communication, but add a new secure.port for SASL-based authentication.

SASL does not actually transmit the bits required for authentication. To handle this we will need to add a new AuthRequest/AuthResponse API to our protocol. This will contain only a simple byte array containing the auth stuff SASL needs.

Generally you would expect authentication to happen at connection time, but I don't think there is really any reason to require this. I think instead we can allow it at any time during a session or even multiple times during a session (if the client wishes to change their user a la su). However this is fundamentally attached to the connection, so if the client reconnects they will lose their authentication and need to re-authenticate.

All connections that have not yet been authenticated All connections on the unauthenticated port will be assigned a fake user ("nobody" or "josephk" or something).

Implementing Authentication

This feature requires some co-operation between the socket server and the api layer. The API layer will handle the authenticate request, but the username will be associated with the connection. One approach to implementing this would be to add the concept of a Session object that is maintained with the connection and contains the username. The session would be stored in the context for the socket in socket server and destroyed as part of socket close. The session would be passed down to the API layer with each request and we would have something like session.authenticatedAs() to get the username to use for authorization purposes.

Integrity and Encryption

SASL supports authentication alone, authentication + integrity protection (signing), and authentication + integrity & encryption.

Integrity protection and encryption require actually wrapping and unwrapping the bytes being transmitted. These will not work with the sendfile optimization and we would have to disable this optimization for requests with this more stringent security requirement. Presumably this would apply to the contents of sends but not to the size boundaries we use to delimit them (i.e. for encrypted messages the size would be the size post encryption and the size itself would not be encrypted)The acceptor thread that currently handles socket acceptance will become responsible for authenticating the user as themselves. This thread will add the user Subject or some proxy for this to the socket's context information. This subject will be passed along by the socket server as part of each Request object sent on the RequestChannel. Authorization will be handled in the API layer.

Authorization

The plan will be to support unix-like permissions on a per-topic level.

...

READ - Permission to fetch data from the topic
WRITE - Permission to publish data to the topic
DELETE - Permission to delete the topic
CREATE - Permission to create the topic
CONFIGURE - Permission to change the configuration for the topic
LIST DESCRIBE - Permission to fetch metadata on the topic
REPLICATE - Permission to participate as a replica (i.e. issue a fetch request with a non-negative node id). This is different from READ in that it has implications for when a write request is committed.

Permission are not hierarchical since topics are not hierarchical. So a user will have a default value for these (a kind of umask) as well as a potential override on a per-topic basis. Note that CREATE and DESCRIBE permission primarily only makes sense at the default level.

...