Attach a policy
Deployed and supported. The fields and commands described here are stable within version v1alpha1.
A policy does nothing until it is attached to a subject. sng tenant policy attach binds a policy (yours or a managed policy) to users, roles, machines; detach undoes the link. It is also how you add someone to your tenant.
sng tenant policy attach readonly --user bob --with-assume
policy "readonly" bound to user:bob (pending: applied in a few minutes)
policy "assume-role" bound to user:bob (pending: applied in a few minutes)
Bob can now run sng tenant use acme (thanks to assume-role) and read (thanks to readonly), a few minutes later.
Prerequisites
- A session on the tenant:
sng tenant use acme. - The action
policy:adminon the target policy (managed policyadmin). - For
--oidc-trust, a declared trust (Secretless CI).
Steps
1. Choose the subject
| Flag (repeatable) | Subject | Expected form | Resolved principal |
|---|---|---|---|
--user | a StackNGO user | bob, stackngo/bob or bob@example.com | user:<sub> (stable even if the user is renamed) |
--role | a role carried by StackNGO users | org/NAME, e.g. stackngo/sre | role:org/NAME |
--app | a machine application (client_credentials) | full name of the application, given by status.provider.name (sng kind get IAMApplication NAME --json) | app:<name> |
--oidc-trust | the CI jobs federated by a trust of the tenant | gitlab-deploy (name only, without /) | oidc:acme/gitlab-deploy |
Rules:
- at least one subject; empty values and the
*wildcard are refused ("a group of users is a role"); --rolerequires theorg/NAMEform;--appexpects the full name of the application (sng-<fingerprint>-app-<name>), read fromstatus.provider.nameof theIAMApplication(see Machine identities).
Being rolled out. The interface described here is the one of the next release: it may still change, and may not be enabled on your tenant yet.
The --oidc-trust flag is being enabled gradually with CI federation.
2. Attach
sng tenant policy attach NAME [sujets...] [--with-assume] [-t TENANT]
--with-assumeadditionally attaches the managed policyassume-roleto the same subjects: without it, a user or a machine application cannot open a session on the tenant. CI jobs federated by a trust of the tenant do not need it.-t TENANTtargets a tenant other than the current one:sngopens a session on that tenant for the command (you neediam:AssumeRolethere).- Attaching is cumulative: subjects are added to those already bound.
Examples:
# a whole role in read-write, with entry into the tenant
sng tenant policy attach readwrite --role stackngo/dev --with-assume
# a federated GitLab CI: publishes the CDN, nothing else
sng tenant policy attach cdn-publisher --oidc-trust gitlab-deploy
# a machine application reads secrets
sng tenant policy attach ops-read --app sng-1a2b3c4d-5e6f7a8b-app-ci-deployer --with-assume
3. Detach
sng tenant policy detach readonly --user bob --with-assume
policy "readonly" unbound from user:bob (pending: applied in a few minutes)
policy "assume-role" unbound from user:bob (pending: applied in a few minutes)
With detach, --with-assume also removes assume-role. Detaching the last subject deletes the binding.
Verification
sng tenant policy principals readonly
STATE KIND ID
applied user 7f3e2c1a-…
requested user bob
applied: principals actually in force, identifiers resolved (a user appears by theirsub);requested: subjects as you requested them, pending or already applied.
As long as a subject only appears in requested, it is not in force yet (a few minutes). sng tenant list, on the user's side, shows the tenants where they hold a policy.
The declarative equivalent: IAMPolicyBinding
Each attach writes a binding named bind-<policy> to your tenant's desired state:
apiVersion: iam.stackngo.io/v1alpha1
kind: IAMPolicyBinding
metadata:
name: bind-readonly
spec:
policyRef:
name: readonly
subjects:
users: [bob]
roles: [stackngo/dev]
applications: [sng-1a2b3c4d-5e6f7a8b-app-ci-deployer]
oidcTrusts: [gitlab-deploy]
You do not write this file: sng tenant policy attach/detach maintain it, and sng tenant policy principals reads it. See IAMPolicyBinding.
Common errors
| Message | Cause | Fix |
|---|---|---|
at least one --user, --role, … is required | no subject | add a subject flag |
--role "dev": expected org/NAME | role without an organization | --role stackngo/dev |
subjects must be explicit (no empty value, no global *) | wildcard | name each subject, or create a role |
not found | the policy does not exist in the tenant | sng tenant policy list |
forbidden (no policy of this tenant allows it: see sng tenant policy list) | no policy:admin | ask for the admin policy |
policies: reserved … | tenant reserved for the platform | target your own tenant |
Going further
- The attachments created with the tenant (the creator on
assume-roleandadmin) belong to the platform; yourattachcalls on these policies create a secondbind-<policy>binding next to it. A principal is only detached from a policy if no binding carries it anymore. - A renamed user keeps their rights: the binding is resolved to
sub. A deleted user no longer has any effect (InvalidReference); remove them from the binding. - Deleting an OIDC trust leaves its bindings in place, without effect: no identity can carry them anymore.