Application permission and organization consent
IAM asks users what an application may access before asking which organizations to share. Applications receive only app-bound short-lived login tokens. They never receive IAM credentials, session tokens, or verification codes.
Browser flow
- Authenticate the Carbon in IAM and identify the requested application or bundle.
- Display the complete effective permission list, with descriptions, external providers, and critical labels. Obtain explicit consent. The IAM backend's
consent_requiredvalue determines whether this step is required. - Show the user's active organizations. Select at least one, or explicitly select all current organizations. Applications cannot supply organization scope through a login URL.
- Submit the exact approved scope names and scope version with selected organization IDs.
- Return a two-minute single-use SLT, or an array of individually bound SLTs for batch and bundle login.
Identity and profile are default application permissions. Additional self, directory, organization, and external permissions must be declared. Critical scope approval by IAM or an external provider is separate from the user's consent; both must be satisfied.
Direct IAM clients
A Carbon or Silicon holding a direct IAM bearer reads:
GET /api/v1/app-auth/organizations?app_id=acme%3Ebilling
Authorization: Bearer <direct IAM access token>
The response includes application identity, items with organization choices and existing authorization flags, scopes with descriptions and critical labels, scope_version, and consent_required. Present the returned current values to the user, then submit:
{
"app_id": "acme>billing",
"org_ids": ["customer"],
"approved_scopes": ["self.identity.read", "self.profile.read"],
"scope_version": 1
}
Use POST /api/v1/app-auth/short-lived-tokens with an idempotency key. The example version is illustrative: send the value just read. External scope names flatten to obo:{app_id}:{endpoint_id}. IAM rejects an incomplete, extra, or outdated scope set. Reload choices and obtain fresh consent after a version change.
Application Basic credentials and application OAuth bearers cannot obtain SLTs or approve their own additional access. A trusted IAM client such as the CLI may submit choices using the user's direct session, after receiving the user's explicit choices.
Scope and organization boundaries
Consent is bound to the parent IAM session and target application. Additional organization choices preserve grants already approved on that session; they do not select organizations joined later. An application's owning organization does not define the user's available organizations. Tokens authorize only currently active selected memberships and currently effective consented scopes.
Introspection and application reads enforce these limits synchronously. Webhook projections obey the same field restrictions and only subscribe through webhook_scope. Removing a scope or membership takes effect without waiting for a webhook to arrive. Null or absent fields are undisclosed information, not permissive defaults.
Batch and bundle consent
Batch login carries each application's approved_scopes and scope_version in its selection. Validation and issuance occur in one transaction; a failure leaves no partial new consent or tokens.
Bundles display one bundle identity and combine member permissions for consent, then use one organization picker. The request still records every member's exact scope version and returns individual app-bound SLTs. A changed member list cannot silently add an application to a submitted login.
All routes keep these same rules inside a testing environment, with test credentials and the selected environment key.