
Oracle Idcs Org Provisioning
- 10 installs
- 22 repo stars
- Updated May 28, 2026
- acedergren/agentic-tools
oracle-idcs-org-provisioning is a Claude Code skill that maps IDCS claims to org membership and roles via Better Auth session hooks after OAuth login.
About
oracle-idcs-org-provisioning is a Claude Code skill for turning IDCS claims into real org membership after an OAuth login succeeds. It covers the mapProfileToUser and session.create hooks, atomic MERGE INTO upserts into org_members, tenant-to-org mapping, and first-admin bootstrap. A developer uses it when login works but tenant, role, or membership still needs to be resolved and persisted. It bundles scripts to preview group-to-role mapping and org resolution.
- Maps IDCS claims to org membership after OAuth login using Better Auth session hooks
- Enforces atomic MERGE INTO upserts and a strict org-resolution precedence order
- Handles first-admin bootstrap and separates access gating from role mapping
Oracle Idcs Org Provisioning by the numbers
- 10 all-time installs (skills.sh)
- Ranked #3,590 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
oracle-idcs-org-provisioning capabilities & compatibility
Free skill; requires Oracle IDCS config and a database with an org_members table.
- Capabilities
- org provisioning · role mapping · access gating · admin bootstrap
- Works with
- oracle
- Use cases
- api development · security audit
- Pricing
- Free
What oracle-idcs-org-provisioning says it does
Use when mapping IDCS claims to org membership after OAuth login succeeds.
Never `SELECT` then `INSERT` into `org_members` — use atomic `MERGE INTO` or concurrent logins corrupt membership
npx skills add https://github.com/acedergren/agentic-tools --skill oracle-idcs-org-provisioningAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 10 |
|---|---|
| repo stars | ★ 22 |
| Last updated | May 28, 2026 |
| Repository | acedergren/agentic-tools ↗ |
What it does
Map Oracle IDCS group claims to org membership and roles via Better Auth session hooks after OAuth login.
Who is it for?
Provisioning tenant, role, and org_members membership from IDCS group claims after login succeeds.
Skip if: Base OIDC setup, callback URLs, Fastify header bridging, or renaming IDCS concepts across a codebase.
When should I use this skill?
Login succeeds but tenant, role, or org membership still has to become real in Oracle.
What you get
Correct, atomic org_members provisioning with proper access gating, role mapping, and first-admin bootstrap.
- org_members provisioning logic
- group-to-role mapping
- first-admin bootstrap gate
By the numbers
- Three-stage claim-to-membership flow
- Four-level org-resolution precedence
- ~30s claims cache TTL
Files
Oracle IDCS Org Provisioning
Use when login succeeds but tenant, role, or org membership still has to become real in Oracle.
Do NOT load when
- problem is Fastify header bridging or cookie/session forwarding
- problem is base OIDC setup, callback URLs, or trusted origins
- task is renaming IDCS concepts across an existing codebase
Three-stage flow
1. Capture IDCS claims during OAuth profile mapping (mapProfileToUser) 2. Gate session in session.create.before when explicit allow-rules exist 3. Resolve org and upsert org_members in session.create.after
NEVER
- Never combine access gating with role mapping — they are separate decisions with separate failure modes
- Never
SELECTthenINSERTintoorg_members— use atomicMERGE INTOor concurrent logins corrupt membership - Never consume cached claims in
beforeand expect them still available inafter— use stash/peek/consume pattern - Never bypass existing membership precedence with a newer fallback — re-login instability follows
- Never assume missing
groupsclaim is a provisioning bug — check scope config and IDCS app first
Expert decision trees
Access gate vs. role mapping
These answer different questions:
- Access gate (
beforehook): can this user enter at all? Controlled by DB-configured allow-groups. Fail closed only when explicit allow-groups exist; fail open otherwise. - Role mapping (
afterhook): which role do they get? Controlled by group→role mapping and env defaults.
Mixing them produces false lockouts: a user passes the access gate but gets the wrong role because the gating logic short-circuited role resolution.
Org resolution precedence
Always use this order — never skip a level for "simplicity": 1. Existing membership in org_members 2. Tenant-name → org map (DB-configured) 3. DB-configured default org 4. Env default org
Changing this order mid-deployment breaks re-login for users who were previously assigned via a higher-precedence rule.
First-admin bootstrap
Fresh installs have zero admin-group config. If an org has no admin yet, promote the first provisioned user to admin once. Without this gate, the system is unbootstrappable — no one can configure allow-groups because no one has admin rights.
Claims cache across hook boundary
Hooks run in separate request lifecycles. The claim set from mapProfileToUser is not available in session.create.after without explicit passing:
stash(sub, claims)in profile mappingpeek(sub)inbefore(read without clearing)consume(sub)inafter(read and clear)
Using a short-lived in-memory cache keyed by sub is the standard pattern. TTL of ~30s is sufficient.
Failure modes by decision point
| Situation | Decision |
|---|---|
No groups claim | Check scope and IDCS app config before touching provisioning code |
| No explicit DB allow-groups | Fail open — no lockout |
| DB lookup or write fails | Fail open for login, log it — lockout must never be the default outcome |
| Org has no admin yet | Promote first provisioned user once |
Scripts
# Preview group → role mapping
node scripts/preview-group-role-mapping.js "PortalAdmins,Developers"
# Preview org resolution
node scripts/verify-org-resolution.js --tenant sandbox --map "sandbox:org-123,prod:org-999" --default-org org-000Arguments
$ARGUMENTS: Optional provisioning focustenant-map— focus on tenant→org resolutionfirst-admin— focus on bootstrap logic- (empty) — evaluate the full IDCS claim → org membership flow
OCI_IAM_ADMIN_GROUPS=PortalAdmins,OCI_Administrators,Administrators
OCI_IAM_DEFAULT_ORG_ID=
OCI_IAM_TENANT_ORG_MAP=
.env
#!/usr/bin/env node
const raw = process.argv[2] || '';
const groups = raw.split(',').map((item) => item.trim()).filter(Boolean);
const adminGroups = (process.env.OCI_IAM_ADMIN_GROUPS || 'PortalAdmins,OCI_Administrators,Administrators')
.split(',')
.map((item) => item.trim().toLowerCase())
.filter(Boolean);
const input = new Set(groups.map((item) => item.toLowerCase()));
const role = adminGroups.some((group) => input.has(group)) ? 'admin' : 'user';
console.log(`Groups: ${groups.join(', ') || '(none)'}`);
console.log(`Admin groups: ${adminGroups.join(', ')}`);
console.log(`Resolved role: ${role}`);
#!/usr/bin/env node
const args = process.argv.slice(2);
const get = (flag) => {
const index = args.indexOf(flag);
return index >= 0 ? args[index + 1] : undefined;
};
const tenant = get('--tenant');
const mapping = get('--map') || process.env.OCI_IAM_TENANT_ORG_MAP || '';
const defaultOrg = get('--default-org') || process.env.OCI_IAM_DEFAULT_ORG_ID;
let resolved;
if (tenant && mapping) {
for (const pair of mapping.split(',')) {
const [left, right] = pair.split(':').map((item) => item && item.trim());
if (left === tenant && right) {
resolved = right;
break;
}
}
}
console.log(`Tenant: ${tenant || '(none)'}`);
console.log(`Tenant map: ${mapping || '(none)'}`);
console.log(`Default org: ${defaultOrg || '(none)'}`);
console.log(`Resolved org: ${resolved || defaultOrg || '(none)'}`);
console.log(`Resolution path: ${resolved ? 'tenant-map' : defaultOrg ? 'default-org' : 'unresolved'}`);
Related skills
FAQ
How should I write org membership on login?
Use an atomic MERGE INTO upsert into org_members; never SELECT then INSERT, because concurrent logins corrupt membership.
What is the org resolution precedence?
Existing membership, then tenant-name to org map, then DB-configured default org, then env default org, in that exact order.