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

Role Variables #1120

Closed
russjones opened this issue Jul 7, 2017 · 0 comments
Closed

Role Variables #1120

russjones opened this issue Jul 7, 2017 · 0 comments
Milestone

Comments

@russjones
Copy link
Contributor

russjones commented Jul 7, 2017

Problem

At the moment, if you use OIDC/SAML with dynamic roles (also called role templates), Teleport creates many roles in the backend. This can be confusing for Teleport users because Teleport does not support roles and for Enterprise users because every time they look at the list of roles it potentially changes.

Solution

We should have a single role but allow injecting additional data into it at runtime. Teleport users will always belong to a single role and Enterprise users will get a coherent view of what roles exist in their system.

We accomplish this my making changes to services.User and services.Role.

User Traits

We introduce the concept of user traits which is a map[string][]string and that contains information about the user obtained either from an identity provider (through OIDC claims or SAML assertions) or from a system administrator for local accounts (see #1136).

Role Variables

We allow variables to be defined within the list of logins for a role. Role variables will be substituted with data from user traits when the role is evaluated. Note, variables substitution will not work for trusted clusters, it only works for local roles.

Role variables are enclosed by {{ and }} and begin with the source of user traits either being external or internal. Next is the variable name which is either specified as .variable_name or if it includes special characters as ["variable_name"]. Here are a few examples:

{{internal.logins}}
{{external.nickname}}
{{external["https://www.example.com"]

Implementation

UX Changes

In the role allow defining {{external.variable_name}} in the list of logins. This will be filled in from user traits (either from claims for OIDC or assertions for SAML users).

For example, suppose you have a OIDC provider that returns the following claims:

group: user
personal_account_name: rjones
svc_account_name: git

and you have the following role:

kind: role
version: v3
metadata:
  name: "developer"
spec:
  allow:
      logins: ["{{external.personal_account_name}}", "{{external.svc_account_name}}", "ops"]       

If the above user with group claim of user successfully logins in, rjones and git would be added to ops and set as the principals on your certificate. This is used by OpenSSH for principal based access controls and will also be used by Teleport for Role-based Access Control (RBAC) by Teleport.

Code Changes

Login

Upon successful login save all claims and assertions in services.User as traits. When generating a certificate (see below) the services.User traits information will be consulted to populate the principals field in the certificate.

https://github.com/gravitational/teleport/blob/master/lib/auth/oidc.go#L286-L342

Certificate Generation

When generating a user certificate, if any logins in the role contain {{external.variable_name}} substitute based off the traits information in services.User (stored claims and assertions). This will preserve OpenSSH compatibility and will be used as the source of truth when making a RBAC decision (see below).

https://github.com/gravitational/teleport/blob/master/lib/auth/auth.go#L617-L683

Authenticating with a server

When connecting to a Teleport node, first perform a check if the principal listed on the certificate can access a server. If the principal can login, then fetch the user from the backend and do substitution like the section below and then perform a RBAC check as usual (checking if the tuple of logins, namespaces, and labels) can access a server.

https://github.com/gravitational/teleport/blob/master/lib/srv/sshserver.go#L462-L535

@russjones russjones added this to the 2.3 milestone Jul 7, 2017
@russjones russjones changed the title Remove Dynamic Roles Role Variables Jul 15, 2017
@russjones russjones mentioned this issue Jul 25, 2017
30 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant