Evolving Tuist tokens

Need/problem

We have recently added two new ways to authenticate:

  • OIDC tokens, a more secure and convenient way to authenticate on supported CI providers
  • Account tokens, offering a flexible way to communicate with the API – either on the CI or in local environments. Heavily inspired by GitHub tokens with fine-grained permissions.

These two types of tokens are on top of what we’ve already had:

On the CI, it’s confusing which token to pick – an OIDC token, an account token, or a project token? Especially, account tokens and project tokens now serve a very similar purpose.

That’s why I would like to propose to deprecate project tokens in favor of OIDC and account tokens.

Detailed design

Teams should use OIDC tokens on the CI – if possible – since they are more secure.

If not, then teams should use account tokens instead of project tokens. However, we should make sure that the account tokens don’t need to be regenerated when new features are added. Right now, the project token has access to the following scopes:

  • project:previews:write
  • project:cache:write
  • project:bundles:write
  • project:tests:write
  • project:builds:write

And we expand what the project token can do when we add new features.

But account tokens need to have their scopes defined explicitly when they are created. To ensure the migration to account tokens doesn’t negatively impact the UX, I’m suggesting to add a new scope group project:ci. This scope group would be expanded into the above scopes – and we could automatically include new scopes for this group when new features are added.

The command to create a CI token would then be:

tuist account tokens create my-account --name ci-token --scopes project:ci
tuist account tokens create my-account --name ci-token --scopes project:ci --projects my-project # if you want to limit the token to specific projects

Compared to the current command:

tuist project tokens create my-account/my-project

Drawbacks

Now, the new command is definitely a bit more complex. But it does allow teams to create tokens with access to all projects instead of being forced to create a token per project. Since this would be well-documented in our docs, I don’t think the slightly longer command is a reason not to adopt this.

Alternatives

We can definitely keep the account tokens and project tokens co-existing. But I believe this causes confusion and having to support both on the server makes us more susceptible to bugs.

We can also change tuist project tokens create command to create an account token under the hood tailored for CI. This is definitely possible, but again, I believe this would cause confusion.

Adoption strategy

We should deprecate the tuist project tokens commands and refer to the documentation for how to create a CI account token instead. After 6 months, we should remove the project token support from the server.

Fully on board with having fewer types of tokens. For the deprecation, I’d maybe even go so far as to show a banner on the dashboard when a project token has been used recently, since it’s inherently a CI thing and a CLI-based notice might be missed.

Oh yeah, that’s a good idea :+1:

I’m in favor of getting rid of project tokens since account tokens are a more flexible solution that can be used to address the same need.

Resolving scopes dynamically on the server, like we used to do with the project tokens, and through what you are suggesting with the CI scope is something I’d avoid. If we change the scopes it resolves to down the line, we’d be escalating permissions without the user not knowing about it, which I don’t think is a good patter security wise. It also complicates auditing, because you can’t just look at a token in a moment in time, but you need to take into account the version of the software a token was resolved with.

I’d add an interface to change the scopes of a particular token, and I’d also make sure in the error messages that the server returns we includes the scopes that are missing, so one can easily diagnose what the problem is.

For the deprecation, I’d return a warning header from the server, which the CLI can parse and present pointing users to the documentation about account tokens.

I don’t agree with this. This provides friction when adopting new features for very little benefits. Users can always choose to pick specific scopes if they want to be in tight control of them. Other services, like Vercel, don’t even have fine-grained permissions – we’ve gone further than some.

Sure, we can do that, but as @cschmatzler mentioned, this will only show up in the CI logs and it will be very easy to miss.

Security is a huge benefit. We are trading security for convenience, and I don’t think that’s what we should do. What we can do is provide a convenient interface to update or create a token such that you can pass a set of scopes together (e.g. a category of tokens). But I don’t think ci should be a scope.

We’re making the tokens unnecessary strict – most services have what’s equivalent to the GitHub access token. Also, I don’t see how this is a security risk when the scopes are owned by us, a trusted entity. So … still disagree.

Fair enough. My main concern was the implicit expansion, but you’re right that we control what goes into that group and it stays within CI-relevant actions. I’m fine with project:ci as proposed.

One small suggestion: maybe we document clearly what scopes it includes and update the docs when it expands, so teams doing security reviews have a clear reference.

Definitely, I’ll make sure to include that :+1:

I’d also be careful with implicitly adding scopes to tokens. Maybe we can take inspiration from GitHub apps where there’s a “this app (token) requests extra permissions for new feature x” and it needs to be confirmed?

Offering groups, fully for it.

We can do that and I like that proposal, but would consider postponing that for later as that would increase the scope of the project token deprecation. We will also need to adjust OIDC tokens as those also currently have a default set of scopes that we might extend in the future.

For OIDC tokens, it would definitely make sense to allow teams to specify the scopes explicitly, but that’s also something I’d postpone for now.

Definitely a stretch goal to add the prompt and all. Which is very much fine since we won’t be immediately adding new scopes anyways.