Skip to content

feat: shared cluster in previews-shared scopes secrets per env - #27

Merged
BSick7 merged 4 commits into
masterfrom
feat/shared-env-secrets
Oct 7, 2026
Merged

BSick7 merged 4 commits into
masterfrom
feat/shared-env-secrets

Conversation

@BSick7

@BSick7 BSick7 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Lets one cluster serve every Nullstone preview env while keeping their secrets apart. Nothing changes for a cluster that is not shared.

Shared mode

The cluster decides: aws-ec2-vault-cluster sets shared = data.ns_env.this.type == "PreviewsSharedEnv", exposes it as output shared, and writes SHARED_ENVS into user-data. Everything else reads that one value. When true:

  • Tenant roles are named <env>.<tenant> on the same two AppRole mounts, each bound to an identity entity carrying env and tenant metadata. Provisioning creates the entity and its alias on the role's role_id.
  • Tenant policies are scoped to kv/<family>/envs/{{entity.env}}/customers/{{entity.tenant}}/* with the whole envs/ prefix denied otherwise.
  • Broker policies are scoped to auth/approle-<kind>/role/{{entity.env}}.* with every parameter denied: an app mints logins only for its own env and cannot change a role. The env comes from the entity the cluster function writes on the app role (feat: bind app roles to an env-scoped entity on shared clusters vault-admin#6).
  • Provisioning and apps-auth get narrow identity grants with policies and disabled refused; groups, OIDC, MFA, and merge stay denied.

Unshared clusters render the 0.1.x policies byte for byte. Goldens under testdata/policies/unshared pin that; testdata/policies/shared documents the shared output.

Modules

  • aws-ec2-vault-cluster 0.2.0: output shared, SHARED_ENVS in user-data, pins vault-admin ~> 0.3.0. tofu init on this module fails until vault-admin v0.3.0 is published; the tests here ran against 0.2.2 with the pin swapped locally.
  • aws-vault-access 0.3.0: reads the cluster's shared output (try(..., false), so 0.1.x clusters read as unshared), passes env to the function only when shared, injects VAULT_ENV (always present, empty when unshared).
  • READMEs for both modules. Cluster: where each tenant's secrets live, how tenant tokens are scoped, what apps and humans can do. Access: the two-step login, token lifetimes, gotchas. .gitignore now keeps aws/*/README.md.

CLI

  • tenants create|destroy take --env, required when shared and refused otherwise.
  • tenants list shows the env and flags a role that does not fit the cluster mode.
  • New envs list and envs destroy <env> --yes [--purge-secrets].
  • vault-utils env prints SHARED_ENVS=true for a shared cluster.

Tests

  • Existing Docker tests run unchanged with SharedEnvs=false.
  • New shared tests: same tenant ID in two envs cannot cross, parents and wildcards and traversal denied, broker confined to its env and unable to rewrite a role, provisioning cannot grant entity policies, env destroy with purge leaves the other env intact, a login before the entity existed is relinked.
  • tofu test in both modules covers shared, unshared, and a cluster with no shared output.
  • A spike against Vault proved the templated glob, missing-metadata, and denied_parameters behaviors before the design was committed.

Release order

  1. Tag and publish vault-admin v0.3.0 (feat: bind app roles to an env-scoped entity on shared clusters vault-admin#6).
  2. Merge this. Bake the node AMI. Publish aws-ec2-vault-cluster 0.2.0 with --include='templates/*' and aws-vault-access 0.3.0.

BSick7 added 2 commits October 7, 2026 08:58
SHARED_ENVS=true (set from the cluster's shared output) names every
tenant role env.tenant and binds it to an entity carrying env and tenant
metadata. Tenant policies then scope KV to envs/<env>/customers/<tenant>
and the broker policies to the app's own env, which the cluster function
writes on the app entity. Provisioning and apps-auth gain narrow identity
grants with policies refused. Unshared clusters render the 0.1.x policies
byte for byte (pinned by goldens).

vault-utils: tenants create/destroy take --env (required when shared,
refused otherwise), tenants list shows the env, new envs list/destroy,
and env prints SHARED_ENVS from the workspace output.
aws-ec2-vault-cluster 0.2.0: output shared (env_name == previews-shared),
SHARED_ENVS in user-data, vault-admin ~> 0.3.0.
aws-vault-access 0.3.0: passes the app env to the function and injects
VAULT_ENV when the cluster is shared; empty otherwise.
@BSick7 BSick7 changed the title feat: scope tenants per env on a shared cluster feat: shared cluster in previews-shared scopes secrets per env Oct 7, 2026
BSick7 added 2 commits October 7, 2026 09:13
Cluster: where each tenant's secrets live, how tenant tokens are scoped,
and what apps and humans can do in both modes. Access: the two-step
login, token lifetimes, and gotchas. .gitignore now keeps module READMEs.
shared = data.ns_env.this.type == "PreviewsSharedEnv".
@BSick7
BSick7 merged commit 5f65594 into master Oct 7, 2026
7 checks passed
@BSick7
BSick7 deleted the feat/shared-env-secrets branch October 7, 2026 13:28
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

Successfully merging this pull request may close these issues.

1 participant