This is not directly part of ick, but Qvisqve, but it’s something ick needs, so I’m putting this in the ick blog.

Access control to ick APIs happens using OAuth2 and OpenID Connect (OIDC) access tokens. The API client and end-user authenticate themselves to Qvisqve, and the API client gets an access token in return. The API grants access based on the access token. The token is digitally signed by Qvisqve, and only grants specific access. The signature prevents anyone from modifying the token to gain extra access.

Qvisqve currently implements two methods for getting access tokens:

  • The OAuth2 “client credentials grant” is for non-human API users and are based on “client id” and “client secret”; this is what icktool uses.

  • The OIDC “authorization code flow” is for interactive authentication of humans.

The problems I am current worried about are:

  • Ick needs to start isolating its users from each other. If Alice has a project, Bob should not be able to modify it, delete it, see it, or even know it exists. Because of this, icktool needs to identify the end-user, but the client credentials grant doesn’t do that.

  • Non-interactive use of the ick APIs (icktool in a cron job, for example) needs to use instance specific credentials that can be monitored and revoked individually. It doesn’t seem good for all machines using icktool to use the same credentials: if those leak, all machines lose access at once. Also, different machines may need different types of access, and shouldn’t get any more than they need.

I can see two solutions:

  • Create a new “client” for each user and use instance: if Alice needs to run icktool on her laptop and a server, that’s two clients, with different client ids and secrets (alice_on_laptop and alice_on_server). This creates a separate identity for each instance, allowing separate monitoring and revocation: if Alice’s laptop gets stolen, only the alice_on_laptop identity needs to be revoked (or secret changed). Also, each of the clients gets tied to a user. The user would manage their API clients’ access via a web application, as a logged-in user, granting and revoking client access as they need to.

    Pro: this is standard OAuth2 and requires no changes for clients to support it.

    Con: this results in a fair number of API client identities, but that’s not a serious problem.

    Con: users need to give API clients two things (client id, client secret), which also isn’t a very serious problem.

  • Add support for an “API token”. This would be a new kind of token that can only be used for getting an access token, in lieu of client credentials. The API token would identify the user, and what subset of the user’s access the token grants. API clients would give the API token to Qvisqve, and get a normal access token. The API token would optionally not expire.

    Pro: slightly easier for the user: just one thing to handle, instead of two.

    Con: non-standard OAuth2 extension, would require all API clients to support it. Might be an issue for OAuth2 libraries.

I’m currently not sure which of these is better, but I put out this blog post to document my thinking on this. Feedback is welcome.