Troubleshooting: ScaiKey sync issues
403 Platform token requires admin:read or admin:write scope#
The credentials the backend is using don't have admin scope on ScaiKey, so it can't reach applications.get_effective_users.
The sync falls back automatically to a member-walk over groups.list_members. Slower (O(N_groups × N_members) instead of O(N_users)) but works with tenant-tier scopes.
Confirm the fallback kicked in: POST /v1/admin/sync and check users_method in the response. Should be "member_walk" (vs "effective_users" when admin scope is available).
If you'd rather use the fast path: re-issue your backend's ScaiKey credentials with admin:read and admin:write scopes. The scaiflow scaikey-register CLI does this in one shot.
groups_seen: 0 after sync#
No groups were enumerated. Likely causes:
- The ScaiKey credentials don't have
groups:readscope. - The tenant genuinely has no groups (unusual).
groups.listreturns paginated results and the SDK pagination isn't completing — file a bug with the sync response.
Fix: Add groups:read to the credentials. Re-run sync.
"Sync complete but no super_admin elected"#
After a sync, the log warns:
1 2 3 | |
Pick one:
- Manual bootstrap: Grant yourself via the admin CLI on the backend host. Survives all future syncs (
admin_role_source = manual). - Group-derived: Create a ScaiKey group named (or with id)
<your-admin-group>, add yourself, setSCAIFLOW_SUPER_ADMIN_GROUPS=<group_id_or_name>on the backend, restart, sync. Members of that group auto-elevate.
The latter scales better across tenants — onboard new admins by adding them to the group in ScaiKey, no ScaiFlow ops needed.
Webhooks not arriving#
Symptoms: changes in ScaiKey (user joins, group memberships) take an hour to show up in ScaiFlow.
- Confirm
SCAIFLOW_SCAIKEY_WEBHOOK_SECRETis set on the backend (unset → endpoint returns 503 fail-closed). - Check the webhook configuration in ScaiKey points at the right URL:
https://scaiflow.example/api/v1/webhooks/scaikey. - Check the secret in ScaiKey matches
SCAIFLOW_SCAIKEY_WEBHOOK_SECRET. - Try
POST /v1/admin/syncmanually — if that works but webhooks don't, the issue is delivery, not handling.
ScaiKey doesn't reach localhost. In local dev, tunnel through ngrok / cloudflared, OR rely on the hourly background sync + manual POST /v1/admin/sync for testing.
"User in ScaiKey but not in ScaiFlow"#
POST /v1/admin/sync should pick up new users on the next run. If a specific user is missing after sync:
- They might not have ScaiFlow application assignment in ScaiKey (only users assigned to the ScaiFlow app appear in
effective_users). - For the member-walk fallback: they have to be in at least one group the ScaiKey credentials can see.
Confirm by listing users via GET /v1/admin/users and grep for the email.
"I added myself to a super_admin group but I'm not super_admin"#
SCAIFLOW_SUPER_ADMIN_GROUPS is only consulted at sync time. Trigger a sync to apply: POST /v1/admin/sync. The reconciliation step runs at the end of sync and promotes/demotes users based on group membership.
Manual grants (admin_role_source = manual) survive group reconciliation. So if you manually granted yourself super_admin and then later got added to a group, your source stays manual.