Source: projects/identity-management/ad-shop-seeding/README.md
> Source: projects/identity-management/ad-shop-seeding/README.md
AD Shop Seeding — Plan v0.3
Seed sandbox.local with a versatile, OIM-shop-typical catalog of AD groups
and OUs so the IT-Shop has plenty of orderable entitlements. Groups are
empty containers for demo purposes — no real applications, SSO, or
provisioning logic behind them.
Author: Claude + Codex · Status: v0.6 · AD entitlements seeded; ready for OneIM sync
Review artifact: OIM IT Shop Entitlement AD Group Catalog Proposal
IT Shop structure proposal: ITSHOP-STRUCTURE-PROPOSAL.md
IT Shop structure seed SQL: sql/seed-itshop-structure.sql
AD seeder: scripts/sandbox/seed/Invoke-AdShopSeed.ps1
1. Goals
- A realistic-looking entitlement landscape: ~15 fictional applications × 5 standard tiers + cross-cutting business-role and system-role-related entitlements.
- Deterministic, idempotent seeding (re-run-safe; never destructive on its own).
- Naming + OU layout that maps cleanly to OIM ADSGroup sync and auto-derived service items.
- Enough surface area to demo: orderable AD groups, business-role-style request categories, and future OIM system role bundles.
2. Out of scope (for v1)
- Real users, group memberships, manager/owner assignments.
- Real SSO/app integrations behind the groups.
- Approval workflows / risk policy seeding (Phase 2, OIM-side).
- AD object cleanup /
-Resetmode (separate plan; require explicit flag).
3. Scale (target)
| Bucket | Count |
|---|---|
| Fictional apps | 15 |
| Per-app groups | 5 |
| App groups | 75 |
| Business roles | 9 |
| System roles | 10 |
| Distribution lists | 3 |
| Total groups | 97 |
| OUs | ~21 |
4. OU layout
DC=sandbox,DC=local
└── OU=OIM-Managed
├── OU=Resources
│ ├── OU=Applications
│ │ ├── OU=APP-ATLAS
│ │ ├── OU=APP-HELIOS
│ │ └── … (one OU per app, 15 total)
│ └── OU=DistributionLists
└── OU=Roles
├── OU=BusinessRoles
└── OU=SystemRoles
Rationale: Resources = direct orderable/grantable AD entitlements;
Roles = business-role and system-role bundle markers.
Mirrors how OIM Manager UI typically separates "Service Items" from
"Business Roles".
5. Naming conventions
All groups: Global Security, samAccountName uppercase, hyphen-free.
| Bucket | samAccountName | Example |
|---|---|---|
| App entitlement | APP_<CODE>_<TIER> | APP_ATLAS_ADMIN |
| System role | SR_<CODE> | SR_ENG_CORE |
| Distribution | DL_<NAME> | DL_ALLSTAFF |
| Business role | BR_<DEPT> | BR_FINANCE |
Each group's description carries a human-readable label suitable for the
OIM service-item display name (e.g. description="Atlas Office — Admin").
info (notes) carries the application long name + tier rationale so the
OIM-side auto-derivation has rich text to consume.
6. Application catalog (15)
| Code | App name | Domain |
|---|---|---|
| ATLAS | Atlas Office | Productivity |
| HELIOS | Helios Mail | Productivity |
| PULSE | Pulse Chat | Collaboration |
| FORGE | Forge IDE | Engineering |
| PIPE | Pipeline CI | Engineering |
| VAULT | Vault Secrets | Engineering |
| INSIGHT | Insight BI | Data & Analytics |
| LUMEN | Lumen Data Lake | Data & Analytics |
| TEMPO | Tempo HR | HR |
| LEDGER | Ledger Finance | Finance |
| BEACON | Beacon CRM | Sales |
| CITADEL | Citadel VPN | Infrastructure |
| SENT | Sentinel SIEM | Security |
| SPEC | Spectrum DAM | Marketing |
| VOYAGER | Voyager CMS | Marketing |
7. Per-app entitlement template (5 tiers)
Every application gets the same 5 groups for symmetry; OIM-side
service-category metadata can hide tiers that don't apply (none in v1).
| Tier | Group suffix | Description suffix |
|---|---|---|
| Reader | _READER | "<App> — Read-only" |
| User | _USER | "<App> — Standard user" |
| Editor | _EDITOR | "<App> — Content editor" |
| Admin | _ADMIN | "<App> — Administrator" |
| Approver | _APPROVER | "<App> — Request approver" |
Risk, location, and birthright groups are intentionally excluded from this
phase. The live OneIM database already has IT Shop and role-request structures;
this seed focuses on AD entitlements and system-role-related catalog building
blocks.
8. Cross-cutting groups
Business roles (9) — BR_HR, BR_FINANCE, BR_IT, BR_ENGINEERING,
BR_SALES, BR_MARKETING, BR_OPERATIONS, BR_LEGAL, BR_CUSTOMERSUPPORT
System-role-related entitlements (10) — SR_WORKFORCE_BASE,
SR_ENG_CORE, SR_ENG_ADMIN, SR_DATA_ANALYST, SR_FIN_OPERATOR,
SR_HR_OPERATOR, SR_SALES_OPERATOR, SR_MKTG_CREATOR,
SR_SEC_OPERATOR, SR_PRIV_ACCESS
Distribution-list-shaped security groups (3) — DL_ALLSTAFF,
DL_LEADERSHIP, DL_ENGINEERING (mail-enabling deferred; created as
Global Security groups for v1 with [TYPE:DL] in description)
9. Idempotent seeding approach
Single PS1 driven by a project-owned data file (JSON), shape:
{
"rootOu": "OU=OIM-Managed,DC=sandbox,DC=local",
"applications": [
{ "code": "ATLAS", "name": "Atlas Office", "domain": "Productivity" },
…
],
"tiers": [
{ "suffix": "READER", "label": "Read-only" },
…
],
"businessRoles": [ "HR", "FINANCE", … ],
"systemRoles": [
{
"code": "ENG_CORE",
"name": "Engineering Core",
"includes": [ "APP_FORGE_USER", "APP_PIPE_USER", "APP_VAULT_READER" ]
}
],
"distributionLists": [ "ALLSTAFF", "LEADERSHIP", "ENGINEERING" ]
}
Source-of-truth location:
- Catalog data:
projects/identity-management/ad-shop-seeding/data/ad-shop-catalog.json - Seeder implementation:
scripts/sandbox/seed/Invoke-AdShopSeed.ps1 - Default invocation derives the catalog path from the workspace root, while allowing
-CatalogPathoverride for experiments.
Script behavior:
- For every OU and group:
Get-AD…→ if missing,New-AD…; if present, leave alone (orSet-AD…to converge description if drift). - Never deletes.
-WhatIfmode is available for dry-run audit before live runs. - Outputs a structured report per object:
{ name, distinguishedName, kind, action: "created|exists|updated|skipped", error? }. - Support
-Json; JSON is the agent contract and should include_v,catalogVersion,summary, andobjects. - Wrap the whole live run in one
Invoke-WithSandboxLockcall and write one audit record for the run summary, rather than one lock per group. - Validate inputs before mutation: duplicate
samAccountName, length > 20 for legacysAMAccountName, invalid AD name characters, missing parent OU references. - Apply convergent updates only to agent-owned attributes. For OUs this is
description; this AD schema rejectsinfoonorganizationalUnit. For groups this isdescriptionandinfo. Do not overwrite unrelated AD fields.
Execution path (depends on resolution of WinRM blocker):
- Preferred: WinRM
Invoke-Commandagainstim.sandbox.localusingAdAdmincred. This is the right v1 channel because the target is Active Directory, the AD PowerShell module is local to the domain host, and it keeps domain-auth semantics simple. It needs Viktor to addim.sandbox.localto local WinRM TrustedHosts first. - Alternative: direct LDAP from the workstation with
System.DirectoryServices.Protocolsusing the AD admin bind over LDAPS/636. This is a fallback for OU/group CRUD if WinRM remains blocked. - Not recommended for v1: OpenDJ
cn=Directory Manager. That credential targets OpenDJ, not Active Directory, and should not drivesandbox.localgroup seeding. - Fallback: Viktor runs the script locally on the host through RDP or a one-off elevated session.
10. OneIM DB observations
Queried live on 2026-04-26 against OneIM:
| Area | Observation |
|---|---|
| IT Shop nodes | ITShopOrg has 22 rows. Root is Identity & Access Lifecycle. |
| AD group shop structure | Existing shelf/bucket: Identity & Access Lifecycle\Active Directory Groups; group lifecycle bucket also exists. |
| Role request structure | Existing products include Role membership, Role entitlement assignment, and System role entitlement assignment. |
| Service items | AccProduct has 20 rows, including predefined AD group and system-role request products. |
| AD groups | ADSGroup has 287 rows; all currently IsForITShop = 0, IsITShopOnly = 0. |
| System roles | ESet has 0 rows; ESetHasEntitlement has 0 rows. The schema exists but is unused in this sandbox. |
| System role types | ESetType has Common and RessourceSet. |
Implication: AD seeding should create AD groups now. OIM Phase 2 can then
sync them into ADSGroup, publish app groups as service items, and optionally
create ESet system roles that bundle selected ADSGroup entitlements via
ESetHasEntitlement.
11. OIM-side wiring (Phase 2 — separate plan, sketched here)
After AD sync lands the groups in ADSGroup:
1. Sync project: confirm the existing ADS sync project picks up the new OU subtree (OU=OIM-Managed).
2. Service items: enable the supported ADSGroup publication path (QER\ITShop\AutoPublish\ADSGroup in this sandbox) through Designer/configuration tooling and compile the database if the preprocessor-relevant parameter changes.
3. Service categories: use the already seeded coarse AccProductGroup categories: Sandbox Applications, Sandbox Business Roles, Sandbox System Role Bundles, and Sandbox Distribution Lists.
4. Shop assignment: use the already seeded Identity & Access Lifecycle\Sandbox Applications, Sandbox Business Roles, Sandbox System Role Bundles, and Sandbox Distribution Lists shelves for product placement. Keep them as shallow BO shelves; application/domain grouping belongs in AccProduct metadata/categories or portal filtering.
5. System roles: create OIM ESet objects for each SR_* catalog entry and link included ADSGroup objects through ESetHasEntitlement.
6. Role request products: use the existing System role entitlement assignment / Role entitlement assignment IT Shop structure for role-related request demos.
7. Ownership: each app's _ADMIN group can later become the OIM owner candidate for app-category service items.
Implemented on 2026-04-27:
- AD: 22 OUs under
OU=OIM-Managed,DC=sandbox,DC=local. - AD: 97 empty Global Security groups from catalog version
1.1.0. ITShopOrg: 4 project-ownedBOshelves directly underIdentity & Access Lifecycle.AccProductGroup: 4 project-owned service categories.- OneIM IT Shop publication: 97 catalog-backed
AccProductservice items created and linked to the syncedADSGrouprows. - Entitlement flags: all 97 catalog-backed
ADSGrouprows now haveIsForITShop = 1,IsITShopOnly = 0, andUID_AccProductpopulated. - Approval policy: all 97 service items, the four sandbox service categories, and the four sandbox BO shelves use
Approval of AD group membership requests(ADS-625C7339178444AD9FBC0A8A7EC3901B). - Shelf assignment: all 97 groups are assigned to their correct sandbox BO shelf through
BaseTreeHasADSGroup/ITShopOrgHasADSGroup. - Product nodes: DBQueue/product-node processing created 97
ITShopOrgPRnodes: 75 Applications, 9 Business Roles, 10 System Role Bundles, 3 Distribution Lists. - Marker:
[OIM-SANDBOX-SEED:ad-shop-seeding:v1]. - Corrected learning:
ITShopOrgcannot be modeled as a deep nested shelf tree. Existing rows showITShopInfo = SHfor the shop root,BOfor shelves directly below that root,PRfor product nodes, andCUfor customer nodes. OneIM trigger logic rejectsBObelowBO. - Refined learning: the project-owned shelf/category descriptions now state the intended boundary of each object. Do not manually add
PRproduct nodes or rely onAccProductInBaseTreeuntil the supported publication path is validated. - Verification: AD seeder idempotency pass returned
exists = 119,errors = 0; independent AD count returnedOus = 22,Groups = 97,GlobalSecurity = 97. - OneIM publication evidence:
projects/identity-management/oim-kb-update/sandbox-db/2026-04-27-ad-shop-itshop-publication.md. - Generated publication SQL:
projects/identity-management/ad-shop-seeding/output/publish-ad-groups-itshop.sql, built byscripts/research/Build-OimAdShopItShopPublishSql.ps1. - Scope not yet implemented: native
ESetsystem roles and end-to-end web portal cart/order testing for the published products.
12. Codex critique decisions
1. OU split — keep the Resources vs Roles split. It is worth the slightly deeper LDAP filter because it cleanly separates requestable entitlements from modeling groups and maps better to OIM shop concepts. Sync can target OU=OIM-Managed recursively.
2. Group scope — keep Global Security for v1. This is a single-domain sandbox and Global groups are the expected source entitlement shape for AD resource assignment. Revisit Universal only if the sandbox gets a multi-domain forest or cross-domain mail/distribution scenarios.
3. Risk, location, birthright — removed from v1 per Viktor direction.
4. Distribution lists — keep DL_* as Global Security groups in v1 with [TYPE:DL] in the description. Do not mail-enable yet. They are useful demo objects without adding Exchange/mail dependency.
5. Pre-seeded users — no users in v1. Keep this project entitlement-shaped. Add a separate "demo identities and memberships" phase later, probably sourced from HRSystem, so AD users, Person records, and memberships stay coherent.
6. Execution channel — WinRM-first after TrustedHosts is fixed. It uses the domain host's AD module and avoids LDAP write edge cases. Add direct AD LDAPS as fallback only; do not use OpenDJ credentials for AD seeding.
7. Naming — keep uppercase prefixes and underscores. They are readable in ADUC and stable for OIM filters. Keep app codes at 7 characters or fewer so APP_<CODE>_APPROVER stays inside the 20-character sAMAccountName limit; add a preflight length/duplicate check.
8. Catalog stability — project data belongs under projects/identity-management/ad-shop-seeding/data/; executable helpers belong under scripts/sandbox/seed/. This keeps research/project intent separate from reusable automation.
Additional Codex recommendations:
- Keep five app tiers in v1 for demo symmetry, but allow the JSON catalog to disable tiers per app later (
enabledTiers) without changing the script. - Add
metadata.owner = "ad-shop-seeding"andmetadata.catalogVersionin the JSON so future cleanup/reset plans can identify agent-owned objects without guessing. - Mark created OUs/groups with a stable
infomarker such as[OIM-SANDBOX-SEED:ad-shop-seeding:v1]. - Prefer fictional but domain-recognizable app names as drafted; no app swaps needed for v1.
13. What I'd like back from Codex
Resolved in §11. Next step: reconcile to v1 and implement the JSON catalog plus scripts/sandbox/seed/Invoke-AdShopSeed.ps1.