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
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ Team group OWNERs are admin-managed and never removed by the sync; non-@java.no
| 0a | AWS Discovery | **Done** |
| 0b | Bootstrap State Backend | **Done** — S3 backend live |
| 0c | Organizations + Permission Boundary | **Done** — org enabled, boundary deployed, SCP deferred |
| 1 | Identity (Google + Identity Center + Cognito) | **Deployed** — GCP SA with domain-wide delegation, Identity Center with ABAC + 3 permission sets in `terraform/org/`. Google Workspace SAML IdP for SSO (auto-provisions users, groups synced via CI/team-provisioner). Cognito pool TF exists but not yet applied (needs Google OAuth client). |
| 1 | Identity (Google + Identity Center + Cognito) | **Deployed** — GCP SA with domain-wide delegation, Identity Center with ABAC + 3 permission sets in `terraform/org/`. Google Workspace SAML IdP for SSO (auto-provisions users, groups synced via CI/team-provisioner). Cognito pools deployed; the internal pool signs in with the Terraform-managed Google OIDC IdP. |
| 2a | Networking | **Deployed** — VPC, subnets, NAT |
| 2b | Ingress | **Deployed** — ALB + ACM cert |
| 2c | IAM / OIDC | **Deployed** — 6 CI roles (infra, infra-plan, per-app, deploy, override-approver, registry), team-prefixed naming + permission boundary |
Expand All @@ -334,7 +334,7 @@ Team group OWNERs are admin-managed and never removed by the sync; non-@java.no

### Known Issues
- **ECS deploy stabilization**: platform-test-app task registers but service fails health check
- **Cognito**: pools deployed; internal pool's `GoogleSAML` IdP was created outside Terraform. It is replaced by the Terraform-managed Google OIDC IdP at cutover (docs/cognito-google-setup.md), then deleted
- **Cognito**: pools deployed; the internal pool has been cut over to the Terraform-managed Google OIDC IdP (`internal_identity_providers` defaults to `["Google"]`). The old `GoogleSAML` IdP, created outside Terraform, is still in the pool but offered on no app client until it is deleted (docs/cognito-google-setup.md, "Decommission GoogleSAML")
- **Google SCIM provisions only direct members** of `drift@`, `styret@` and `javabin-developer@java.no` to Identity Center; it does not expand nested groups. Nobody gets an Identity Center user (and so no AWS access, team role included) unless they are a direct member of one of those. The team provisioner adds team members and (via `flatten: true` in the registry's `groups/access.yaml`) kodesmia members to `javabin-developer@` one by one; SCIM creates the user later, and the 3-hourly `sync_access_members` run adds them to their Identity Center groups. Don't create Identity Center users through the API: they'd have no link to Google (see `docs/lambda-functions.md`).
- **SSO sessions carry no `team` tag**: the Identity Center ABAC attribute (`${path:enterprise.team}`) is never set on users, so `${aws:PrincipalTag/team}` is empty for humans. Per-team permission sets (`javabin-team-{team}`) therefore use `javabin-team-{team}-guardrails` (the developer boundary rendered with the team name) as their permissions boundary instead. It must stay a boundary: its baseline `Allow *` attached as a policy grants everything its Denies miss (every untagged resource). A team with no guardrails policy (`platform`, or a new team before platform CI) gets read-only access only. The ABAC-based `javabin-developer` permission set in `terraform/org` cannot reach team resources
- **App databases share one network path** (fixed by `app-network`): service-rds now allows ingress only from the app's own `{team}-{app}-tasks` SG; each app moves off the shared ECS tasks SG on its next pipeline run
Expand Down
6 changes: 3 additions & 3 deletions docs/platform-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ GitHub OIDC provider (data source), CI roles, permission boundary, ECS execution
| `javabin-ci-deploy-{team}` | CI broker Lambda (not OIDC) | ECR push, ECS deploy |
| `javabin-ci-override-approver` | Board members, pinned to `approve-override.yml` | SSM override tokens |
| `javabin-ci-registry` | Registry repo, `main` only | Team provisioning dispatch |
| `javabin-ecs-execution` | ECS tasks | Pull images, write logs, read secrets |
| `javabin-ecs-exec-{team}` | ECS tasks | Pull images, write logs, read the team's own secrets (`/javabin/apps/{team}/*`). One per registry team |
| `javabin-ecs-execution` | ECS tasks | Deprecated shared role: image pull and logs only, no secrets. Teams can no longer pass it |

**Key design:** `job_workflow_ref` condition prevents app repos from writing rogue workflows.

Expand Down Expand Up @@ -118,5 +119,4 @@ Team SSO roles' `CredentialAccess:IAMUser/AnomalousBehavior` on `ssm:GetParamete

## identity

**Not yet implemented.** Will contain IAM Identity Center + Cognito user pools.
Blocked on Google Admin access for SAML federation.
Cognito user pools (internal + external) and the `auth-claims` trigger. The internal pool signs in through Google OIDC (provider `Google`, from the `internal_identity_providers` variable); the hand-made `GoogleSAML` provider is still in the pool but no longer offered on app clients. See [cognito-google-setup.md](cognito-google-setup.md). IAM Identity Center is in `terraform/org/`, not here.
2 changes: 1 addition & 1 deletion docs/reusable-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ source = "git::https://github.com/javaBin/platform.git//terraform/modules/{name}
| Security group | `javabin-ecs-tasks-sg` |
| ALB | `javabin-alb` |
| ECS cluster | `javabin-platform` |
| Execution role | `javabin-ecs-execution` |
| Execution role | `javabin-ecs-exec-{team}` (from the `team` input; reads only that team's secrets) |
| Route53 zones | `javazone.no` (`route53_zone_id`); `javazone.no`, `java.no`, `javabin.no` (`route53_zone_ids` map) |

**Key outputs:** `vpc_id`, `private_subnet_ids`, `ecs_cluster_id`, `https_listener_arn`, `execution_role_arn`, `route53_zone_id`, `route53_zone_ids`
Expand Down
3 changes: 2 additions & 1 deletion terraform/modules/cognito-app-client/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#
# Those parameters are owned by the Lambda, not by this Terraform. Their ARNs
# are deterministic, so the ECS task definition can reference them up front;
# the shared execution role reads /<project>/apps/* at task launch.
# the team's execution role (<project>-ecs-exec-<team>, which can read only
# /<project>/apps/<team>/*) resolves them at task launch.
#
# With `slot` set (e.g. "login-1", used by service-routing for ALB sign-in),
# everything moves one level down — /<project>/apps/<team>/<app>/<slot>/auth —
Expand Down
12 changes: 9 additions & 3 deletions terraform/org/identity-center.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
# Prerequisite: Google Workspace SAML sync must be configured first so that
# Identity Center groups (infra@, heroes@, board@, pkom@) exist.
#
# ABAC: The "team" attribute flows from Google group membership through
# SAML assertion → Identity Center → STS session tag. This lets a single
# JavabinDeveloper permission set work for all teams.
# ABAC: The "team" attribute was meant to flow from Google group membership
# through SAML assertion → Identity Center → STS session tag, so a single
# JavabinDeveloper permission set would work for all teams.
#
# NOTE: the "team" attribute is never populated on Identity Center users, so
# SSO sessions carry no team tag and javabin-developer gets no access to team
# resources. Developers use the per-team permission sets (javabin-team-{team})
# created by the team-provisioner Lambda instead (see CLAUDE.md, Known Issues).
################################################################################

data "aws_ssoadmin_instances" "this" {}
Expand All @@ -20,6 +25,7 @@ locals {

################################################################################
# Access Control Attributes (ABAC) — map "team" from SAML assertion
# (the source attribute is never set today; see the ABAC note above)
################################################################################

resource "aws_ssoadmin_instance_access_control_attributes" "this" {
Expand Down
6 changes: 3 additions & 3 deletions terraform/platform/iam/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -998,10 +998,10 @@ resource "aws_iam_role_policy" "ci_apply_gate" {
}

################################################################################
# ECS Execution Role — pulls images, writes logs, reads secrets
# ECS Execution Role (shared, deprecated) — pulls images, writes logs
#
# This is the shared execution role for all ECS tasks on the platform.
# Individual task roles are created per-app via the service-role module.
# Tasks now use the per-team execution roles below. Individual task roles are
# created per-app via the service-role module.
################################################################################

# Deprecated shared execution role. Kept (image pull + logs only, no secrets)
Expand Down
Loading