diff --git a/auth.md b/auth.md index 823766e..a833148 100644 --- a/auth.md +++ b/auth.md @@ -4,17 +4,33 @@ How identity and access control work in the Javabin platform. ## Google Workspace Accounts -All javaBin heroes get a `@java.no` Google Workspace account, auto-created when their entry is added to `groups/heros.yaml` in the registry. An invite is sent to their personal email. Heroes can also request an email alias (e.g., `alex@java.no`) via PR. +All javaBin heroes get a `@java.no` Google Workspace account, auto-created when their entry is added to `groups/members.yaml` in the registry. An invite is sent to their personal email. Heroes can also request an email alias (e.g., `alex@java.no`) via PR. ## AWS Console and CLI: IAM Identity Center + Google Workspace -IAM Identity Center gives javaBin volunteers AWS console and CLI access, federated via Google Workspace SAML. Volunteers sign in with their `@java.no` account. +IAM Identity Center gives javaBin volunteers AWS console and CLI access. Its identity source is Google Workspace: volunteers sign in with their `@java.no` Google account (SAML), and Google's AWS app provisions users into Identity Center (SCIM). It provisions only the **direct** members of `drift@`, `styret@` and `javabin-developer@java.no`; nested groups are not expanded. -- Groups with `identity_center: true` in the registry's `groups/groups.yaml` are synced to Identity Center; `memberships` in `groups/heros.yaml` decides who is in them. -- General permission sets: `javabin-admin`, `javabin-developer`, `javabin-readonly`. -- Each registered team gets `javabin-team-` for its members, scoped to the team's own resources. Use this one for app work (setting secrets, inspecting your services). +- Each registered team gets the permission set `javabin-team-`, assigned to the Identity Center group `team-` (the members of `teams/.yaml`). It is scoped to the team's own resources. Use this one for app work (setting secrets, inspecting your services). +- Groups with `identity_center: true` in the registry's `groups/groups.yaml` are synced to Identity Center with the `permission_set` they name; `memberships` in `groups/members.yaml` decides who is in them. Today: `styret` gets `javabin-readonly`, `drift` gets `javabin-admin`, `kodesmia` gets `javabin-developer`. +- `javabin-developer` cannot reach team resources. It relies on a `team` session tag that Identity Center never sets for humans, so its team-scoped rules match nothing. Use `javabin-team-` instead. +- Sessions last 4 hours (every permission set uses `PT4H`). -Set up the CLI with `javabin aws setup` (writes the SSO session and one profile per role you have, then signs in) and check it with `javabin aws doctor`. Install with `brew install javaBin/tap/javabin`. +### How sign-in works + +1. A registry change creates your `@java.no` Google account (`groups/members.yaml`) and puts you in your team (`teams/.yaml`) or in `kodesmia`. +2. The team provisioner adds team members and kodesmia members (by their `@java.no` address) as direct members of `javabin-developer@java.no`. Personal addresses can't be provisioned. +3. Google's SCIM sync then creates your Identity Center user, some time later. +4. A provisioner run every 3 hours adds your Identity Center user to `team-`, which gives you the `javabin-team-` role (and to `kodesmia` if you are in it). The registry run that added you to `javabin-developer@` skipped you because your user did not exist yet. +5. You sign in at `https://aws.javabin.no` (redirects to `https://javabin.awsapps.com/start/`), or from the CLI after `javabin aws setup`. The access portal lists one role per permission set you have. + +Set up the CLI with `javabin aws setup` (writes the SSO session and one profile per role you have, then signs in) and check it with `javabin aws doctor`. Install with `brew install javaBin/tap/javabin`. Renew an expired session with `aws sso login --sso-session javabin`. + +### When AWS sign-in fails + +- **Google signs you in, but AWS refuses you or shows no account.** Identity Center has no user for your Google account. Google's SCIM sync may not have run yet after you were added to `javabin-developer@`; if it persists, you are not provisioned. You cannot fix this yourself: ask a platform admin. +- **Google says the app is not configured for you.** The AWS app is not turned on for your account. A Google Workspace admin has to enable it. +- **AWS sees the wrong Google account.** Google's SAML sign-in uses the browser's active Google session and shows no account chooser. Switch to your `@java.no` account first, or use a private window. +- **You sign in but `javabin-team-` is missing.** Check that you are in `teams/.yaml`. If you are, your Identity Center user was probably created after the last team sync: the 3-hourly provisioner run adds you to `team-`. If it is still missing after that, ask a platform admin. ## CI/CD: GitHub OIDC @@ -29,7 +45,7 @@ App repos authenticate to AWS in CI with GitHub's OIDC provider. No long-lived c | Pool | Purpose | Users | |------|---------|-------| -| **Internal** | javaBin volunteers, admin tools | `@java.no` accounts via Google Workspace SAML | +| **Internal** | javaBin volunteers, admin tools | `@java.no` accounts via Google sign-in (OIDC) | | **External** | Public-facing apps | Self-registration | Apps declare auth in `app.yaml`: @@ -58,7 +74,7 @@ The container receives `COGNITO_USER_POOL_ID`, `COGNITO_DOMAIN`, `COGNITO_ISSUER **How clients are created.** App CI only requests a client (an SSM parameter under the team's own path). The platform's `app-auth-sync` Lambda creates the Cognito client `{team}-{name}` and its credentials, so teams can never touch each other's clients. -**Google Workspace.** Sign-in to the internal pool goes through the Google Workspace SAML app "Javabin Apps (Cognito)". It must be turned on for a user's organizational unit; it is on for java.no. +**Google sign-in.** The internal pool signs users in through Google OIDC (Cognito identity provider `Google`). Google shows its account chooser when the app (or the platform's ALB sign-in) asks for it, and its consent screen is Internal, so only `@java.no` accounts complete sign-in; Google shows anyone else an error page with an account switcher. Apps that pass `identity_provider` themselves should read `COGNITO_IDENTITY_PROVIDER` instead of hardcoding a name. App sign-in does not depend on Identity Center provisioning. See [cognito-google-setup](https://github.com/javaBin/platform/blob/main/docs/cognito-google-setup.md). Details: [app.yaml reference — auth](https://github.com/javaBin/platform/blob/main/docs/app-yaml-reference.md#auth). Cupcake (`javaBin/frosting`, `client: public`) and cupcake-backend (`javaBin/cupcake`, `client: none`) show the frontend/API split. @@ -77,9 +93,9 @@ The `javabin` CLI uses: | Context | Mechanism | |---------|-----------| -| AWS console / CLI | Identity Center + Google Workspace SAML (`javabin aws setup`) | +| AWS console / CLI | Identity Center, Google Workspace SAML + auto-provisioning (`javabin aws setup`) | | CI/CD | GitHub OIDC → platform broker → team CI roles | -| App users (internal) | Cognito internal pool + Google Workspace SAML | +| App users (internal) | Cognito internal pool + Google OIDC | | App users (external) | Cognito external pool | | Legacy app auth | Auth0 (`login.javazone.no`) | | Developer CLI | gh CLI + AWS SSO profiles | diff --git a/getting-started.md b/getting-started.md index 5c0965e..e9eb459 100644 --- a/getting-started.md +++ b/getting-started.md @@ -26,7 +26,8 @@ budget_nok: 5000 # optional, default 500 NOK/month A platform owner (`@javaBin/platform-owners`) reviews and merges. The merge provisions: -- a Google Group `team-@java.no` and a GitHub team (members become maintainers) +- a Google Group `team-@java.no` and a GitHub team. Members are GitHub team maintainers, so they can add repos to the team; add `role: member` to a member's entry to make them a plain team member instead. In the Google Group everyone is a member unless their entry says `role: maintainer` (then manager). +- `@java.no` members are added to `javabin-developer@java.no`, which is how Google provisions them into IAM Identity Center (see step 4) - the team's AWS CI roles `javabin-ci-team-` and `javabin-ci-deploy-` (only registry teams get them, so an unregistered team cannot deploy) - an IAM Identity Center permission set `javabin-team-` for the members - a monthly AWS budget (alert at 80%, services scaled to zero at 200%) @@ -86,7 +87,11 @@ javabin aws setup # writes the SSO session + one profile per role you have, javabin aws doctor # checks config, token, and which profile javabin would use ``` -Use the `javabin-team-` profile for your team's resources (`--profile javabin-team-` or `AWS_PROFILE`). Sessions last about 8 hours; renew with `aws sso login --sso-session javabin`. +Use the `javabin-team-` profile for your team's resources (`--profile javabin-team-` or `AWS_PROFILE`). The `javabin-developer` profile, if you have it, cannot reach team resources. Sessions last 4 hours; renew with `aws sso login --sso-session javabin`. + +How you get AWS access: Google provisions only the direct members of `drift@`, `styret@` and `javabin-developer@java.no` into IAM Identity Center. The team provisioner adds team members and kodesmia members to `javabin-developer@`, Google's SCIM sync then creates their Identity Center user, and a provisioner run every 3 hours adds them to `team-`, which gives them the `javabin-team-` role. A new member can therefore wait a few hours before the role shows up. + +If Google signs you in but AWS refuses you, you have not been provisioned into IAM Identity Center: ask a platform admin. See [When AWS sign-in fails](auth.md#when-aws-sign-in-fails). ## 5. Secrets @@ -121,15 +126,16 @@ These fail the pipeline with an explanation (see [Not supported](https://github. The registry is also the source of truth for all javaBin hero volunteers (~70 people/year). This is separate from teams: teams are for app developers who need AWS access, heroes are all active volunteers. 1. The board sends yearly Google Forms for hero applications; approved heroes are marked in the response sheet. -2. A sync opens a PR on the registry updating `groups/heros.yaml`. -3. Merging provisions Google Workspace accounts for new heroes, adds everyone to `helter@java.no`, and adds heroes to their membership groups (styret, javazone, pkom, kodesmia, region, etc.). +2. A sync opens a PR on the registry updating `groups/members.yaml`. +3. Merging provisions Google Workspace accounts for new heroes and adds them to the groups in their `memberships` (helter, styret, javazone, pkom, kodesmia, region, etc.). ``` registry/ teams/ # app developer teams (GitHub team, AWS roles, budget) groups/ groups.yaml # group definitions (Google email, Cognito/Identity Center flags) - heros.yaml # heroes (name, email, alias, memberships) + members.yaml # heroes (name, emails, alias, memberships) + access.yaml # which groups may use Gmail, Drive, Chat, Meet ``` -Being in `heros.yaml` implies membership of `helter`; the `memberships` field adds other groups. Heroes can PR an email alias (e.g. `alex@java.no`). +All group memberships are explicit, `helter` included: list every group in `memberships`. Heroes can PR an email alias (e.g. `alex@java.no`). diff --git a/platform-overview.md b/platform-overview.md index abf0125..c143bdd 100644 --- a/platform-overview.md +++ b/platform-overview.md @@ -38,7 +38,7 @@ Seven Terraform sub-modules manage shared resources: | **compute** | ECS Fargate cluster (`javabin-platform`), ECR base config | | **monitoring** | SNS topics, EventBridge rules, AWS Config, GuardDuty, Security Hub | | **lambdas** | Lambda functions for alerts, cost reporting, compliance, budget enforcement, tagging, team provisioning, CI credential brokering, plan review, Cognito clients, secret rollout | -| **identity** | Cognito user pools (internal + external), `auth-claims` trigger. Internal pool signs in via Google Workspace SAML. Identity Center is in `terraform/org/` | +| **identity** | Cognito user pools (internal + external), `auth-claims` trigger. Internal pool signs in via Google OIDC. Identity Center is in `terraform/org/` | ### Reusable Modules (`terraform/modules/`) @@ -98,7 +98,7 @@ The [registry](https://github.com/javaBin/registry) serves two purposes: **Groups & Heroes** (`groups/`) — organizational membership for all javaBin volunteers: - `groups.yaml` defines all groups (helter, styret, javazone, pkom, kodesmia, region, drift, admin, developers, etc.) with their properties (Google Workspace email, Cognito/Identity Center flags) -- `heros.yaml` defines all hero members with their group assignments +- `members.yaml` defines all hero members with their group assignments Changes to `groups/` trigger provisioning: Google Workspace account creation, group membership sync, email aliases, and Cognito/Identity Center sync where configured. Heroes are synced from a yearly Google Sheets application process.