Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add button to create an "automation token" and use it in SDF API #5143

Conversation

jkeiser
Copy link
Contributor

@jkeiser jkeiser commented Dec 17, 2024

This adds the ability to create "automation tokens" intended for use with API clients in hands-free contexts like github.

  • "Create API Token" button on Manage Workspace to generate a token and copy it to your buffer. This is not intended as a final UI; just a way to get this usable.
    image
  • Automation tokens:
    • Not revocable
    • Have an expiration of 1 day (which SDF does not appear to honor)
    • Are rejected by all SDF and module-index endpoints
  • Token format for existing users has not yet changed, to ensure we don't interrupt service. All services will be rolled out with the ability to handle the both the old token format and the new one, but only automation tokens will be minted with the new format until the next deployment.
  • Automation tokens are initially heavily restricted to a very small set of permissions. We may open it up to things we deem safe for automation.

Testing

I have tested:

  • Old and new format for user tokens both work when:
    • Creating a new workspace from the auth portal.
    • Installing components in a fresh workspace (installing new modules from a local module-index server).
    • Multiplayer and creating / moving components around.
    • Hitting the SDF and local module-index server.
  • Tokens generated by the old Auth API allow access to workspaces as well.
  • Automation tokens are rejected by the SDF API as well as the module-index API.

Automated tests: added tests for the new token formats. There is no new coverage in the SDF, DAL or auth api automated tests.

It is critical we ensure SDF and module-index are working after deploy in preprod. I have not tested the new tokens against preprod or prod module-index / SDF, because that requires private keys from those environments to create the tokens.

Deployment

auth api, SDF, and module-index will all have to be deployed. It doesn't matter what order they are deployed in, but all need to be deployed to ensure the new code is generating and accepting tokens correctly to ensure service doesn't get interrupted.

Caveats

  • Tokens have a 1 day expiration date, but SDF does not honor it. jwt.io indicates the token should be expired. Something to be aware of: I don't expect many people to create these tokens yet until they, you know, do something, so I'll address this soon after.

Quickstart

You too can have your API requests denied due to lack of permission:

  1. Run the auth api and portal locally (see instructions in bin/auth-api/README.md).
  2. Create a new workspace.
  3. Click the "Generate Automation Token" button (see image above). Key is now in your buffer.
  4. Hit curl -H "Authorization: Bearer $MY_AUTH_API_TOKEN" http://localhost:5156/api/v2/workspaces/01JF8X1BCPAFTFR18J24JHQGBE/integrations

See your very own 401 saying you don't have a web role.

token

@jkeiser jkeiser changed the title Add button to create an "automation token" and use it in SDF API feat: Add button to create an "automation token" and use it in SDF API Dec 17, 2024
@jkeiser jkeiser force-pushed the jkeiser/eng-2880-add-simple-endpoint-to-generate-api-token-on-auth-api branch from 350b82b to 3bd4f5f Compare December 17, 2024 19:02
@jkeiser jkeiser requested a review from nickgerace December 17, 2024 19:03
@jkeiser jkeiser requested review from stack72 and nickgerace and removed request for nickgerace December 17, 2024 19:03
@jkeiser jkeiser force-pushed the jkeiser/eng-2880-add-simple-endpoint-to-generate-api-token-on-auth-api branch from 3bd4f5f to ec6b468 Compare December 17, 2024 19:05
const token = createSdfAuthToken({
userId: user.id,
workspaceId,
role: "web",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really want to hard code a role of "web" - can't this at least be an enum we extend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enum is here: https://github.com/systeminit/si/pull/5143/files#diff-45a5a885b573adda0e5349e1af441abf982f4f977141755f48dd5780d52a17bdR52

Basically in TS (at least in my experience) unless an enum has extra data they are generally a type union of the possible values, and you specify those values directly. TS will yell at you if you don't use one of them.

Copy link
Contributor Author

@jkeiser jkeiser Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github is being weird about the link, but the line is in auth.service.ts:

export type SdfAuthTokenRole = "web" | "automation";

And it's part of the type on the parameter you pass to createSdfAuthToken, which is how TS knows what values are allowed.

const token = createSdfAuthToken({
userId: authUser.id,
workspaceId: workspace.id,
role: "automation",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should also be part of the enum

const token = createSdfAuthToken({
userId: user.id,
workspaceId,
role: "web",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused by this - we're scoping this token to only be used by the web app?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort of. Roles are a general indication of what you're using the token for, and that tells you about both what you can access as well as the scope of the token. The current tokens we give people are designed for use during active sessions in a web browser, so we called it "web". Alternate names are absolutely accepted :) What we didn't want was to leave it blank for this purpose; giving you essentially maximal access by default seemed undesirable.

workspaceId: workspace.id,
role: "automation",
}, {
expiresIn: "1 day",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's been a while since I was in JWT spec land - does this add the exp claim to the token? I would have expected that to get automatically enforced by SDF's middleware but I could be wayyy off here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have too; looking at the token at https://jwt.io it appears correct, but I'll definitely be revisiting this.

@jkeiser jkeiser force-pushed the jkeiser/eng-2880-add-simple-endpoint-to-generate-api-token-on-auth-api branch from ec6b468 to 5f45814 Compare December 17, 2024 20:05
@jkeiser jkeiser added this pull request to the merge queue Dec 17, 2024
Merged via the queue into main with commit 34574ad Dec 17, 2024
9 checks passed
@jkeiser jkeiser deleted the jkeiser/eng-2880-add-simple-endpoint-to-generate-api-token-on-auth-api branch December 17, 2024 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants