Auths
Auths manages authentication providers for your Glow instance — the SSO configurations, login methods, and access controls that determine how TAs and administrators sign in. It supports full CRUD operations with a draft system for safe, staged edits.
Auth artifacts configure the SSO/IdP providers. For the runtime auth flow (login, tokens, sessions), see Authentication.
What auth artifacts configure
An auth row is an identity-provider (IdP) configuration record — not a runtime session. Each row tells the Glow instance how to wire one external SSO provider (university Shibboleth, Google Workspace, Azure AD, generic OIDC, …) into the embedded Keycloak.
- Provider shape. Each auth carries display fields (
name,description), aflag(enabled/disabled), one or moreprotocol_ids(OIDC, SAML, …), and aslugthat becomes the login-button path. Thedepartment_idsset scopes which orgs see the button. - Encrypted item keys. Sensitive provider config (
client_secret, signing keys, redirect-URI overrides) lives initems, and each item points at one or moreauth_item_key_ids— encrypted-at-rest key resources. List and get responses never return the plaintext; values round-trip throughapp.infra.identity.decrypt.resolve_decrypt, which composes the canonicalget_keys+decrypt_api_keypath and requires the actor’sprofile_id. - Keycloak sync. Creating or saving an auth invalidates the
authscache tag and triggersapp.infra.identity.keycloak_syncon the next sync pass.sync_identity_provider_for_realm_levelandsync_identity_provider_for_orgwalk the auth rows for each realm/department, decrypt the item keys, and upsert matching KeycloakIdentityProviderrecords — so the auth artifact is the source of truth and Keycloak is the projection. - Runtime handoff. Once synced, the actual login dance (PKCE, token exchange, session minting) is handled by the flow documented in Authentication. Auths configure which providers exist;
/authenticationcovers how a request authenticates against them.
What is an Auth?
An auth provider defines a login method for your Glow instance. This could be a university SSO integration, an email-based login, or another authentication protocol. Each auth provider is composed of sections:
- Names and Descriptions — Display identity for the provider
- Flags — Feature toggles (e.g., enabled/disabled)
- Protocols — Authentication protocol configuration
- Slugs — URL-friendly identifiers for login routes
- Items — Individual auth items (e.g., client IDs, secrets, redirect URIs)
Auths uses a composable architecture with full CRUD, duplication, and a draft system with optimistic locking — the same pattern as Settings.
Create an auth provider
Via the CLI
Calls below use
$GLOW_INSTANCE_URL+$GLOW_TOKEN— see Authentication to export them once.
glow auths create --body '{"auths": [{"name": "University SSO", "description": "SAML SSO for university login"}]}'Via the API
curl -X POST $GLOW_INSTANCE_URL/auth/create \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auths": [{
"name": "University SSO",
"description": "SAML-based single sign-on for university TA login"
}]
}'Returns per-item results in results, each carrying the new auth_id and a draft_id ready for protocol wiring.
OIDC / protocol wiring
The protocols section captures which authentication protocol (OIDC, SAML, …) this provider speaks; items carry the encrypted client IDs, secrets, and redirect URIs. Item values are never returned in plaintext from list or get — pull them on demand through the dedicated edit drawer.
glow auths draft --body '{
"input_draft_id": "auth-draft-uuid",
"expected_version": 1,
"protocol_ids": ["protocol-oidc"],
"slug_ids": ["slug-university"],
"item_ids": ["item-client-id", "item-client-secret", "item-redirect-uri"]
}'Adding a new IdP
End-to-end recipe for wiring a fresh SSO provider into Keycloak. The four moves are: create the auth shell, seed the encrypted item keys, attach them in a draft, then let keycloak_sync project the row into the realm.
1. Create the auth shell (returns auth_id + a fresh draft_id):
curl -X POST $GLOW_INSTANCE_URL/auth/create \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auths": [{
"name": "Acme University SSO",
"description": "OIDC login for Acme faculty + TAs",
"protocol": "oidc",
"slug": "acme-sso",
"department_ids": ["dept-acme"]
}]
}'protocol/slug are resolve-or-create — pass a string and the server will reuse an existing resource or mint one. See POST /auth/create for the full request schema, including the items array and per-item auth_item_key_ids for seeding encrypted values up front.
2. Save the draft with the wired items (client ID, secret, redirect URI). Plaintext values you submit go through the encrypted-key pipeline before they land in items; subsequent get/search calls return only the key IDs.
glow auths draft --body '{
"input_draft_id": "<draft-id-from-step-1>",
"expected_version": 1,
"item_ids": ["item-client-id", "item-client-secret", "item-redirect-uri"]
}'3. Promote the draft via POST /auth/update (or the UI’s Save button). The route emits X-Invalidate-Tags: auths and the next keycloak_sync pass picks up the new row, decrypts the item keys, and upserts the matching Keycloak IdentityProvider for each realm the auth’s departments map to.
4. Verify the login button shows up under /login/<slug> and that the round-trip lands a session — that path is covered in Authentication.
The draft cycle
Auths uses a draft system with optimistic locking — the same pattern as Settings. Saving via PATCH /auth/draft returns the new version; pass it as expected_version on the next save so concurrent edits surface a conflict instead of clobbering.
curl -X PATCH $GLOW_INSTANCE_URL/auth/draft \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"input_draft_id": "existing-draft-uuid",
"expected_version": 2,
"name": "Updated University SSO",
"description": "Updated SAML configuration",
"protocol_ids": ["protocol-saml"],
"slug_ids": ["slug-university"],
"department_ids": ["dept-cs"],
"item_ids": ["item-client-id", "item-secret"]
}'Key fields:
input_draft_id— UUID of existing draft (omit for new)expected_version— Optimistic lock versionname,name_id— Name value or resource UUIDdescription,description_id— Description value or resource UUIDflag_id— Feature flag option UUIDprotocol_ids,slug_ids,item_ids,department_ids— Resource assignments
Response: success, draft_id, new_version, message, and form_state.
List your drafts:
curl -X POST $GLOW_INSTANCE_URL/auth/drafts \
-H "Authorization: Bearer $GLOW_TOKEN"Loading a draft:
glow auths get --body '{"auth_id": "auth-uuid", "draft_id": "draft-uuid"}'Search & filter
POST /auth/search returns a paginated list of auth providers:
actor_name— Current user’s display nameauths— Array ofListAuthApiAuthitemsdepartment_filter— Department filter optionstotal_count— Total number of auth providers
Optional filters:
| Filter | Field | Description |
|---|---|---|
| Text search | search | Search across auth provider names |
| Departments | filter_department_ids | Filter by department |
| Department search | department_search | Text search for departments |
| Pagination | page_size, page_offset | Control page size |
curl -X POST $GLOW_INSTANCE_URL/auth/search \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"search": "sso", "filter_department_ids": ["dept-cs"], "page_size": 25}'Bulk operations
Bulk delete and update follow the canonical all-matching shape — explicit IDs, or all: true with flat filter fields plus optional excluded_ids and a patch body. The persona surface is the prove-out; auths follows the same shape.
Delete by explicit IDs:
curl -X POST $GLOW_INSTANCE_URL/auth/delete \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"auth_ids": ["auth-uuid-1", "auth-uuid-2"]}'Delete all matching a filter (with exclusions):
glow auths delete --body '{
"all": true,
"filter_department_ids": ["dept-retired"],
"excluded_ids": ["auth-shared-sso"]
}'Duplicate an auth provider:
curl -X POST $GLOW_INSTANCE_URL/auth/duplicate \
-H "Authorization: Bearer $GLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{"auth_id": "auth-uuid"}'Returns success, auth_id (new UUID), and message.
Common Operations
| Task | CLI | API Endpoint |
|---|---|---|
| List auth providers | glow auths search | POST /auth/search |
| Get auth provider | glow auths get | POST /auth/get |
| Create auth provider | glow auths create | POST /auth/create |
| Update auth provider | glow auths update | POST /auth/update |
| Duplicate auth | — | POST /auth/duplicate |
| Delete auths | glow auths delete | POST /auth/delete |
| Bulk delete (filter) | glow auths delete --body '{"all": true, "filter_…": "…"}' | POST /auth/delete |
| Save draft | glow auths draft | PATCH /auth/draft |
| List drafts | — | POST /auth/drafts |
| Export | glow auths export | POST /auth/export |
| View docs | — | POST /auth/docs |
Related
- Auths API Reference
- Auths CLI Reference
- Settings Guide — instance configuration (links auth providers)