Preview — pending review
This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.
Grant the member one access row
Adds ONE row. A no-op when the member already holds it or a row of the same role covers it (reported in
dropped). The member's editable rows of the same role the new row covers are removed and returned in
removed (an upgrade to a subscription or to the whole tenant). Single-row errors carry index: 0
and a field without the access.0. prefix.
Rows are checked at their OWN target exactly as on the invite (POST /tenants/{tenantId}/iam/users):
404 SCOPE_NOT_FOUND; 403 INSUFFICIENT_ROLE_FOR_SCOPE / CANNOT_GRANT_ABOVE_OWN /
TENANT_OWNER_REQUIRED; 422 ROLE_NOT_FOUND / ROLE_NOT_ASSIGNABLE_AT_SCOPE; precedence
404 > 403 > 422 with details.errors[{index, field, code, message}].
409 details.reason: LAST_TENANT_OWNER (the change would leave the tenant without an owner) or
SELF_IAM_MANAGE_REMOVAL (the caller would remove one of its own rows that confers iam: manage).
Every added / removed row is one iam.user.access.grant / iam.user.access.revoke Activity Log record
and re-projects the member's OpenStack roles. The answer is the full matrix after the change.
Step-up: granting an owner-ranked role (built-in owner, or a custom role that
ranks as owner) from a console session whose account has two-factor authentication needs the
factor verified in the last 5 minutes, otherwise 403 MFA_STEP_UP_REQUIRED (verify with POST /auth/step-up, then retry). Other roles, and an owner row the member already holds, are not
affected.
bearerTokenAuthorizationBearer <token>An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.
tenantId*stringThe tenant id.
userId*stringThe member (its id is its email).
application/json- body
One row of a member's access matrix -- a role at one scope of the tenant.
scopeKind*RoleAssignmentScopeKindScope kind targeted by a role assignment. A tenant assignment (scope id = the tenant id) covers every subscription of the tenant and every project beneath them, including ones created later.
"tenant""subscription""project"scopeId*stringThe tenant id (tenant), a subscription id (subscription) or a project id (project).
1 <= lengthrole*stringA built-in role id or alias (owner, contributor, reader, billing-ops) or a custom role id (rol_…) of the tenant.
1 <= lengthThe matrix after the change.
application/json- response
A member's access matrix in the tenant.
userId*stringtenantId*stringrows*array<>hiddenCount*integerRows at scopes the caller does not reach (not listed, never changed by its writes).
0 <= valuesummary*What a member can reach in the tenant, for list rows. tenant when it holds any tenant row; scoped when it holds subscription/project rows only; none when it holds no row. The counts are the distinct subscriptions / projects named by its explicit rows (computed over every row, including ones the viewer cannot edit).
dropped*array<>Input rows not written because another row already grants them (writes only).
removed*array<>Rows the write removed (writes only).
curl -X POST "https://example.com/tenants/string/iam/users/string/access" \ -H "Content-Type: application/json" \ -d '{ "scopeKind": "tenant", "scopeId": "string", "role": "string" }'{ "userId": "string", "tenantId": "string", "rows": [ { "assignmentId": "string", "scopeKind": "tenant", "scopeId": "string", "scopeName": "string", "subscriptionId": "string", "role": "string", "roleName": "string", "grantedBy": "string", "createdAt": "2019-08-24T14:15:22Z", "editable": true } ], "hiddenCount": 0, "summary": { "kind": "tenant", "subscriptions": 0, "projects": 0 }, "dropped": [ { "index": 0, "scopeKind": "tenant", "scopeId": "string", "role": "string", "reason": "DUPLICATE", "coveredBy": { "scopeKind": "tenant", "scopeId": "string" } } ], "removed": [ { "assignmentId": "string", "scopeKind": "tenant", "scopeId": "string", "scopeName": "string", "subscriptionId": "string", "role": "string", "roleName": "string", "grantedBy": "string", "createdAt": "2019-08-24T14:15:22Z", "editable": true } ]}