Assign a permission set
POST/permission-set-assignments
Grants one permission set to one user or group across one or more AWS accounts. This is the call that actually cuts IAM roles: a permission set on its own is inert, and it is the assignment that turns the definition into real access in a real account.
A 200 is an acceptance, not a durable creation. Everything this call
does before responding is validate the request and write one database row
per account with status: "PROVISIONING". All of the work that matters
(assuming into the member account, creating the IAM role, attaching its
policies, binding the role to the principal in the identity provider)
happens afterwards, in the background, and its outcome is never reported
back through this API. When that background work fails, Prism deletes
the assignment row, so an id handed to you in a 200 can return 404 from
GET /permission-set-assignments/{id} seconds later. Treat that 404 as
"provisioning failed", not as "this never existed". Access is only real
once the assignment reads status: "PROVISIONED".
The response describes only the first of the assignments it created.
data.assignment is a single object (the first row written) even when
you named ten accounts. The ids and account ids of the other nine are
not recoverable from this response at all. If you need them, call
GET /permission-set-assignments afterwards, filtered by
permissionSetId and username, and correlate on accountId.
Accounts that already had this grant are skipped in silence. The 409 below fires only when every account you named was already assigned. Name five accounts of which three already have the grant and you get a 200, two new rows, and nothing anywhere in the body naming the three that were skipped.
Prefer granting to a group over granting to each of its members: a group assignment is one row that tracks the group's membership, while user assignments have to be created and deleted person by person.
Request
Responses
- 200
- 400
- 401
- 403
- 404
- 409
- 500
At least one assignment row was created and its provisioning has been started. Read the warnings above before treating this as done. In particular, this status does not mean any IAM role exists yet, and the assignment it names may not survive.
The request was refused and nothing was created. Either the body was
not valid JSON, or principalType was neither USER nor GROUP, or
the named user or group exists in the directory but has no usable id,
or one of the requested accounts is not onboarded into Prism.
The account check is fail-fast across the whole request: the first account that is not onboarded fails the call, and no assignment is created for any of the others either.
Authentication failed: the X-API-Token header was missing, malformed,
expired or not recognised.
This response is text/plain, not JSON. It is written by
http.Error in the authentication middleware, which runs before any
handler and therefore before anything that would build a JSON envelope.
A client that unconditionally JSON-parses response bodies will fail on
this one, so check the status code first.
The token is valid, but it is not allowed to act on this tenant.
An API token is minted inside one tenant and stays bound to it for life.
Sending it to a path whose tenant segment names a different tenant is
refused here, in middleware, before the operation runs, so this says
nothing about the resource you asked for, only about which tenant the
path named. Check the tenant server variable against the console the
token was created in.
Something the request named does not exist in your tenant, and
nothing was created. It is one of: the tenant itself, the
permissionSetId (which is also what an omitted or empty
permissionSetId reports), the username on a USER assignment, or
the groupName on a GROUP assignment. Read message to tell them
apart.
Every account named in the request already had this exact grant, so nothing was created.
This is an all-or-nothing signal, not a per-account one: if even one account still needed the assignment, the call returns 200 instead and the already-assigned accounts are skipped without comment. Replaying an identical successful request is therefore the usual way to see this status.
The response carries no data; it does not list which accounts were
already assigned.
No assignment could be created. Nothing was written, and no background provisioning was started.
This status covers several causes that would elsewhere be a 4xx:
neither accountId nor accountIds was supplied, so there was
nothing to create; the onboarding check could not be run; or the
database write failed. Read error to tell them apart.
An omitted or empty groupName on a GROUP assignment is not
one of them. The group lookup is an exact name match, so an empty
name matches nothing and the request is refused with 404 before
any write is attempted.