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

RFC: Service accounts #101

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions 101-service-accounts/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Summary

Teams should be able to define a list of service accounts during `fly set-team`
that can be used in automation.


# Motivation

While Concourse is very good at automating things, it's not so good at
automating itself. We've made progress towards it via things like the
[set_pipeline step][set-pipeline-step] and the future [projects RFC][projects].
However, there are still advanced use cases (like pausing pipelines, jobs,
onboarding teams, pinning resources, etc) which are not solved by an RFC.

Many Concourse operators end up creating local users to be used in scripts to
setup Concourse. However, this presents a security risk since these accounts
usually have god powers as the owner of the main team. It's also difficult to
rotate local users' passwords since it requires a restart of the web node.

# Proposal

Multiple service accounts can be created at the team level and be explicitly

Choose a reason for hiding this comment

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

This is a similar proposal to #63, with some differences worth calling out:

  1. In RFC: API Auth Flow for Applications #63, token creation is decoupled from teams, whereas in this proposal, a token must be associated to a team
  2. In RFC: API Auth Flow for Applications #63, the token is auto-generated, whereas in this proposal, the token is user provided
  3. RFC: API Auth Flow for Applications #63 just proposes access to (some subset of) the read API (there's nothing inherent about that in the auth mechanism, but there's no talk about assigning actions to a token)

The main distinction for me is point 1. Allowing service accounts to bind to multiple teams would make them more similar to how users operate, and might make it easier to automate the "full stack" - if you need to configure things per-team, you can have a single admin service account, rather than needing to manage one per team. It complicates the permissions model, though - if there's a CreateServiceAccount action, and a service account is granted that action, then that service account could escalate their permissions by creating a new service account with all actions to all teams if we aren't careful.

Choose a reason for hiding this comment

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

Also worth pointing out #98 which takes an alternative approach (cc @efejjota)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allowing service accounts to bind to multiple teams would make them more similar to how users operate

If you're talking about having to explicitly configure per team, then users also have to be explicitly bound to each team. If you're talking about being able to seamlessly auth to different teams, then I think they would be able to have a similar experience by using the same token (i.e. using the same secret path) for multiple teams. Although that could be a security no-no.

if you need to configure things per-team, you can have a single admin service account, rather than needing to manage one per team.

A service account configured under the main team should have this power.

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 wonder if there's scenarios where there's non-main teams managing other teams. My current experience with multi-tenancy is that there's a cluster operator team with god mode managing the main team, and then sub teams are only 1 level deep.

main
├── team-1
└── team-2

I wonder if there's cases where there's sub-teams in charge of sub-teams

main
├── operator-1
│   ├── operator-2
│   │   └── ...
│   ├── team-2
│   └── team-3
└── team-1

granted permissions to perform automation. They are created with an user
supplied token and can be used in `fly login --team foo --token
'user-provided'` to authenticate to the cluster.

The config passed to `fly set-team` can have a section to create service
accounts for that team. These service accounts will have a human readable
name, a token, and a list of allowed actions that service account can make.

```yaml
roles:
...
service_accounts:
- name: team-onboarding
token: user-provided

Choose a reason for hiding this comment

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

Not sure how I feel about encoding this info in the config file, or even using a user-provided token in the first place.

Did you consider having fly generate a secure token for you to avoid the risks of using an insecure token and/or accidentally checking the token in to VCS?

EDIT: ah, I see the line below:

Concourse should not be responsible for generating or rotating this token.

Could you elaborate on the motivation for not wanting Concourse to generate the token?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you elaborate on the motivation for not wanting Concourse to generate the token?

Concourse shouldn't be the source of truth for creds, that should be left to dedicated solutions like Vault. Since different clusters would have different security requirements (most importantly rotating creds), it would be nice to offload this responsibility to somewhere else.

Also, if Concourse generated (and rotated) the token, there would be additional complexities in syncing the token back into the cred manager. Whereas if the source of truth is the cred manager, we can leverage the existing creds flow.

Not sure how I feel about encoding this info in the config file, or even using a user-provided token in the first place.

I originally thought fly set-team supported ((var)) interpolation, in which case task params can be used to pass in the token from the cred manager. But I just checked and fly set-team doesn't actually support interpolation, maybe that feature should be included in this RFC?

actions:
- SetTeam
```

The `name` should be unique and human readable as it will be treated as the
username for audit logging and OPA integrations.

The `token` is provided by the user and will use a simple string comparison to
authenticate a `fly login`. It should be redacted in the output of `fly
get-team`. Concourse should not be responsible for generating or rotating this
token.

The `actions` lists all the [actions][action-matrix] that service account would
be allowed.


This would involve a rework of the auth system as it's now possible for an
incomming request to be from a user or a service account. Users are authorized
to a limited number of roles via the [RBAC system][rbac], whereas service
accounts are authorized to a dynamic set of actions.

# Open Questions

- Service accounts encourages the idea of "automating the automation", and can
be used to make it harder to identify missing features in the core product.
Is there a better way to make service accounts less desirable to use for the
average user (and prompting feature requests) but still unblocking power
users? Maybe service accounts should be restricted from common actions
(`SetPipeline`, `CreateJobBuild`, `RerunJobBuild`, etc)?


# Answered Questions

# New Implications

[action-matrix]: https://concourse-ci.org/user-roles.html#action-matrix
[set-pipeline-step]: https://github.com/concourse/rfcs/blob/master/031-set-pipeline-step/proposal.md
[projects]: https://github.com/concourse/rfcs/pull/32
[rbac]: https://github.com/concourse/rfcs/blob/master/003-rbac/proposal.md