Skip to content
Merged
Show file tree
Hide file tree
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
36 changes: 26 additions & 10 deletions auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<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-<team>`, assigned to the Identity Center group `team-<team>` (the members of `teams/<team>.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-<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/<team>.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-<team>`, which gives you the `javabin-team-<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-<team>` is missing.** Check that you are in `teams/<team>.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-<team>`. If it is still missing after that, ask a platform admin.

## CI/CD: GitHub OIDC

Expand All @@ -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`:
Expand Down Expand Up @@ -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.

Expand All @@ -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 |
18 changes: 12 additions & 6 deletions getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<team>@java.no` and a GitHub team (members become maintainers)
- a Google Group `team-<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-<team>` and `javabin-ci-deploy-<team>` (only registry teams get them, so an unregistered team cannot deploy)
- an IAM Identity Center permission set `javabin-team-<team>` for the members
- a monthly AWS budget (alert at 80%, services scaled to zero at 200%)
Expand Down Expand Up @@ -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-<team>` profile for your team's resources (`--profile javabin-team-<team>` or `AWS_PROFILE`). Sessions last about 8 hours; renew with `aws sso login --sso-session javabin`.
Use the `javabin-team-<team>` profile for your team's resources (`--profile javabin-team-<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-<team>`, which gives them the `javabin-team-<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

Expand Down Expand Up @@ -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`).
4 changes: 2 additions & 2 deletions platform-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/`)

Expand Down Expand Up @@ -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.

Expand Down