# Thinking Out Loud ## Enforcing authz Give me a token with these claims: ```json { "iss": "authz.hashicorp.com", "sub": "id", <- id of the user, team, organization "aud": "app.terraform.io", "exp": "unix-timestamp", "nbf": "unix-timestamp", "iat": "unix-timestamp", "jti": "token id generated by issuer", "scope": "terraform.teams.create, terraform.teams.read", // how do we scope this to each organization? } ``` ## Example List teams GET /api/v2/org/:org_id/teams Host: app.terraform.io Authorization: Bearer my.jwt.token * authz: * find user, team, or org record. how do we know which type to load? * POST /tokens/ Host: authz.hashicorp.com { "token": "my.jwt.token" } 200 OK { sub: "id", <- id of the user, team, organization scope: "terraform.teams.create, terraform.teams.read", // how do we scope this to each organization? } ## Managing authz * ## TFC 1. User-Agent goes to https://app.terraform.io/items/ 2. app.terraform.io redirects User-Agent to https://idp.terraform.io 3. user enters credentials 4. idp determines grant type to respond with (e.g. authorization code grant, saml bearer token grant, openid ref token, openid identity token) 5. idp redirects/posts to resource server (https://app.terraform.io) with grant. 6. resource server (https://app.terraform.io) converts grant to access token. 7. redirect to https://app.terraform.io/items/ 8. browser presents access token with JWT claims. 9. resource server verifies claims in the token and determines if subject has access to the resource. ## TFE 1. User-Agent goes to https://app.terraform.internal/items/ 2. app.terraform.internal redirects User-Agent to https://idp.terraform.internal (alias for app.terraform.internal or external idp that support OpenID Connect) 3. user enters credentials 4. idp determines grant type to respond with (e.g. authorization code grant, saml bearer token grant, openid ref token, openid identity token) 5. idp redirects/posts to resource server (https://app.terraform.internal) with grant. 6. resource server (https://app.terraform.internal) converts grant to access token. 7. redirect to https://app.terraform.internal/items/ 8. browser presents access token with JWT claims. 9. resource server verifies claims in the token and determines if subject has access to the resource. ```plaintext | ------------------- | |->| gRPC Gateway | | | ------------------- | | | --------- --------- | ------------------ | --------v---------- |AWS ALB| ->|Traefik|---->| consul service | -- | gRPC Public API | --------- --------- | ------------------ ------------------- | | | --------v---------- | | gRPC Private API | | _------------------- | ----------------------------------- | 1. RBAC: is request allowed? | | 1. Billing: is request allowed? | | 1. Access resource | | 1. Record event for auditing | ----------------------------------- ``` ``` --------------------- |-->| Service Principals | | --------------------- | ---------------- | --------- | Organization | ----->| Users | ---------------- | --------- | | | | ---------- | |-->| Groups | | ---------- | | | |----------------|--------------------| | | | ------------- ------------- ------------ | Project 1 | | Project 2 | | Folder A | ------------- ------------- ------------ | | ------------- ------------- | Project 3 | | Project 4 | ------------- ------------- Permissions: * `consul.cluster.create` * `consul.cluster.get` * `consul.cluster.delete` Roles: * Permissions: [ consul.cluster.create, consul.cluster.get, consul.cluster.delete ] Bindings: * Principal, Permissions, Level { role: "role/admin", principals: [ "group/managers", "user/123", "service_principal/456" ] } ``` ``` { "organization_id": 123, "project_id": 456, "required_permission": "consul.cluster.create", } ``` Hashicorp (PKI) ```plaintext -------------------- | Let's Encrypt CA | -------------------- | | issues ---------------------- | Let's Encrypt Cert | ---------------------- ? --------------------- | HashiCorp Root CA | --------------------- | | signs | ---v--------------------------------------------- | HashiCorp Primary Intermediate CA (HC 101 CA) | ------------------------------------------------- | ---v-------------------- | Vault: Data-Plane CA | ------------------------ | signs |---------------------------------------- | | ---v--------------------------- -------v---------------------------- | Role: RoleConsulServerCerts | | Role: RoleHostManagerServerCerts | ------------------------------- ------------------------------------ | issues |----------------------------------- | | ---v----------------- ---v------------------ | consul server | | host manager | | server.crt/key.pem| | server.crt/key.pem | --------------------- ---------------------- ``` Questions: 1. What happens when the authz server goes down? 1. How does revocation propagate? 1. What type of authorization header does a resource server receive? 1. How does a service explain why a subject is not able to access a resource? 1. Does this impact authn for each service? 1. Do we delegate entitlement checks to the authz server to perform billing checks? 1. Is there concern that every Authz check assumes a Most Privileged Access check and there is no way to reduce privileges for specific sessions? 1. How does impersonation work? 1. How does delegated authorization work? e.g. temporary developer or support access? 1. How do we handle Managed Service Provider (MSP) scenarios? 1. How does service to service interaction work? e.g. Terraform to Vault. Authenticatable: * User * Team * AgentJob * AgentPool * TaskResult * Run TODO: * Example of Token Introspection Endpoint. * Example of Grant Exchange. * Example of Token Revocation. * Example of JWT Token with Claims/permissions. * Example of elevated vs reduced permissions. (sudo mode vs low priv mode) ### References: * [HCP-007 Resource hierarchy and IAM](https://docs.google.com/document/d/1sawA84ZLt768RIi4VZuCfVUSthAcpcc4ufAkWj-9nlc) * [HCP-104 Permission naming](https://docs.google.com/document/d/1ZKBRVBKqZU_l4WcKLugYgY_IUACM4SGHWpnJAuWUf70) * [HCP-128 Internal Operators](https://docs.google.com/document/d/1x2z0jSOGt0l-sHsbBunepOJeuR62yL31_otNmkd0KNc) * [HCP-167 Human operators RBAC](https://docs.google.com/document/d/14wluO-VnTz5ku5qN5KDkBZCoBgtOZLobMK4Fb1yfn6w) * [HCP-183 Provisioning roles and permissions](https://docs.google.com/document/u/0/d/10gl7CaoISY5dIqEeIoCdES2yQrrJn26bIUp0mHhvBDk) * [Presentation: Alex Dadgar](https://hashicorp.zoom.us/rec/share/_mMXheCQJuXTdblyq3uzNsq8PNYj3tI-r2pVJNU-QWSzx3TrvghRJ2AJex-4WHZQ.CRT--WKINJRLg1-b) password: `*y$cLK39` * [Presentation: Joe](https://hashicorp.zoom.us/rec/share/v8FpIZfpxmhOZ5HJ6WjQW4whBYP3X6a813BNrPALy034-oF5wTfbterEkePMGqM) password: `&445zfl0` * [RFC 6749 - OAuth 2.0 Authz Framework](https://datatracker.ietf.org/doc/html/rfc6749) * [RFC 7519 - JSON Web Token (JWT)](https://datatracker.ietf.org/doc/html/rfc7519) * https://github.com/hashicorp/cloud-resource-manager