pilotswarm-portal-auth-assignments
Skill14 starsChanged 8 months agoMITView on GitHub
Use when adding or removing users / groups from the 'admin' or 'user' app roles on a PilotSwarm portal Entra app. Wraps deploy/scripts/auth/Set-PortalAuthAssignments.ps1 — idempotent, re-runnable, resolves UPNs / object ids / group display names. Required after `Setup-PortalAuth.ps1 -CreateAppRoles` when admission is role-driven. Other skills/agents that need to grant or revoke portal access should delegate here instead of generating the Graph calls themselves.
- Reads credentials
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Read .github/DEPLOYMENT.md first.
- Very specific: line 53
Default: assign the deploying user (UPN from az account show) to the admin role unless the user overrides the list in the Step 2 defaults …
- Very specific: line 95
If you get Authorization_RequestDenied from Graph, that's the missing permission.
- Very specific: line 105
Always invoke pwsh directly:
- Distinctive: line 142
After invocation the script prints the full current assignment table.
- Distinctive: line 145
No leftover assignments from a prior posture remain
- Very specific: line 149
If a user reports forbidden or sees only user UI when they expect admin, re-run with -List to check assignments before debugging the portal …
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Select the execution path
Read .github/DEPLOYMENT.md first. The commands below are operator-managed
environment recipes. For this repository’s managed environment, local Azure or
Kubernetes mutations are not permitted. Identity setup is a one-time admin
prerequisite; ongoing changes/reset/teardown need an authorized maintenance
Action, which is not currently supplied. Do not run these recipes locally as
a fallback. Preserve the selected auth posture; VPN steps apply only to a
VPN-enabled target.
pilotswarm-portal-auth-assignments
Drives app-role assignment management for a PilotSwarm portal Entra app
registration. This is the operations complement to
pilotswarm-portal-app-reg:
| Skill | Concern |
pilotswarm-portal-app-reg | One-shot: create the app + SP + role definitions |
pilotswarm-portal-auth-assignments (this one) | Ongoing: who is assigned to which role |
Role assignments are independent of app creation. Use this skill any time you need to grant or revoke portal access — initial bring-up, adding a new admin months later, removing an offboarded user, etc.
When to use this skill
| User signal | Use this skill? |
Just ran Setup-PortalAuth.ps1 -CreateAppRoles and need to assign the deploying user as admin | YES |
| "give alice admin access to the portal" / "add bob to the user role" / "remove carol" | YES |
| "list who has access to the portal" | YES (-List) |
| Smoke-testing role-driven authz on a fresh stamp | YES |
PORTAL_AUTH_PROVIDER=none or open-allowlist posture (no app roles) | NO — there's nothing to assign |
| App reg doesn't exist yet | NO — run pilotswarm-portal-app-reg first |
When the deployer agent should invoke this automatically
In the pilotswarm-npm-deployer flow, after Setup-PortalAuth.ps1
finishes with -CreateAppRoles, the deployer must invoke this
skill before declaring auth setup complete. Without at least one admin
assignment, an -AssignmentRequired app is unreachable by anyone (no
one can sign in), and a no--AssignmentRequired app is denied at the
portal engine (deny-by-default since v0.1.33) for every signed-in
user, since none of them carry the admin or user role claim yet.
Default: assign the deploying user (UPN from az account show) to the
admin role unless the user overrides the list in the Step 2 defaults
table.
Underlying tooling
| Script | Path | Purpose |
Set-PortalAuthAssignments.ps1 | deploy/scripts/auth/ | Add / remove / list app-role assignments |
Setup-PortalAuth.ps1 | deploy/scripts/auth/ | Prerequisite — creates app + roles |
README.md | deploy/scripts/auth/ | Operator docs |
The script reads role IDs from the app's appRoles collection, resolves
each identifier via Microsoft Graph, then POSTs to
/servicePrincipals/{spId}/appRoleAssignedTo. Already-assigned
principals are treated as no-ops.
Identifier formats
Each entry in -AdminAssignments / -UserAssignments can be:
- UPN —
alice@contoso.com(User lookup) - Object ID (GUID) — tried as User first, then Group
- Group display name —
"Portal Beta Users"(quote anything with spaces)
Comma-separate multiple values on the command line:
-AdminAssignments alice@contoso.com,bob@contoso.com
-UserAssignments "Portal Beta Users","Portal Pilot"Permissions required
The signed-in az user (the one running the script) must be either:
- An owner of the portal app registration / its service principal, or
- Hold a directory role that permits app-role assignment management: Application Administrator, Cloud Application Administrator, or Privileged Role Administrator.
If you get Authorization_RequestDenied from Graph, that's the
missing permission. Have an owner of the app run the script, or ask
a tenant admin to add the deployer as an SP owner:
az ad app owner add --id <appId> --owner-object-id <user-objectId>Invocation
Always invoke pwsh directly:
# Add (the common case after fresh app creation)
pwsh -NoProfile -ExecutionPolicy Bypass \
-File deploy/scripts/auth/Set-PortalAuthAssignments.ps1 \
-EnvName <stamp> \
-AdminAssignments <upn>[,<upn>...] \
[-UserAssignments <upn-or-group>[,...]]
# List
pwsh -NoProfile -ExecutionPolicy Bypass \
-File deploy/scripts/auth/Set-PortalAuthAssignments.ps1 \
-EnvName <stamp> -List
# Remove
pwsh -NoProfile -ExecutionPolicy Bypass \
-File deploy/scripts/auth/Set-PortalAuthAssignments.ps1 \
-EnvName <stamp> \
-AdminAssignments <upn> -Remove-EnvName auto-resolves -AppId from
deploy/envs/local/<stamp>/entra-app.json (the summary file
Setup-PortalAuth.ps1 writes). Pass -AppId <clientId> directly if
that file isn't available.
-AdminRoleValue / -UserRoleValue override the role value strings
the script looks up — but the portal authz engine matches the JWT
roles claim only against the canonical literal values admin and
user, so overriding the role values here will leave the portal
unable to recognize them. Keep the defaults unless you also plan to
add a new app role and gate-check it explicitly in code; do not try
to alias custom role values onto the built-in admin/user buckets.
Expected outcome
After invocation the script prints the full current assignment table. Confirm:
- The intended admin(s) appear under role
admin - No leftover assignments from a prior posture remain
- The stamp's
.envhasPORTAL_AUTHZ_*_GROUPSempty (roles-mode — seepilotswarm-portal-app-reg)
If a user reports forbidden or sees only user UI when they expect
admin, re-run with -List to check assignments before debugging the
portal or token-claim pipeline.
Failure modes
| Symptom | Likely cause | Fix |
App '...' has no role with value 'admin' | App was created without -CreateAppRoles | Run Setup-PortalAuth.ps1 -CreateAppRoles -ExistingAppId <id> to add roles, then retry |
Could not resolve '<x>' | UPN typo, user not in tenant, or group name doesn't match | Verify with az ad user show --id <upn> or az ad group list --display-name <name> |
Authorization_RequestDenied on POST | Caller lacks app-role assignment permission | See "Permissions required" above |
Could not load service principal for app | App exists but SP was never created | Run az ad sp create --id <appId> then retry |
What this skill is NOT for
- Creating the app or roles → use
pilotswarm-portal-app-reg - Toggling
appRoleAssignmentRequired→ useSetup-PortalAuth.ps1flags - Changing role definitions (renaming
admintosuperadmin, etc.) → manualaz ad app update --app-rolesagainst a JSON file; out of scope here - Email-allowlist mode (
PORTAL_AUTHZ_*_GROUPS) → that's pure.envconfig, no Graph calls needed
In this repository50 other files it gives its agents.
- packages/sdk/examples/repo-workspaces/seed/home/AGENTS.mdAGENTS.md
- .github/copilot-instructions.mdCopilot instructions
- agent-repair-loopSkill
- duroxide-orchestration-versioningSkill
- editorial-standardsSkill
- finance-research-standardsSkill
- valuation-methodsSkill
- pilotswarm-architectureSkill
- deployment-safetySkill
- incident-responseSkill
- add-activitySkill
- add-eventSkill
- add-testSkill
- add-toolSkill
- agent-versioningSkill
- azure-ps-test-runner-vmSkill
- debug-orchestrationSkill
- debug-testSkill
- horizondb-idiosyncrasiesSkill
- horizon-facts-eval-sweepSkill
- investigate-duroxide-runtimeSkill
- pilotswarm-aks-deploySkill
- pilotswarm-aks-resetSkill
- pilotswarm-new-env-deploySkill
- pilotswarm-perfSkill
- pilotswarm-portal-app-regSkill
- pilotswarm-releaseSkill
- pilotswarm-tuiSkill
- pilotswarm-vpn-client-profileSkill
- schema-migrationSkill
- notesSkill
- share-a-fileSkill
- cost-latency-analysisSkill
- graph-debugSkill
- orchestration-session-lifecycleSkill
- resourcemgrSkill
- sweeperSkill
- canvas-appsSkill
- html-visualsSkill
- pilotswarm-agent-versioningSkill
- pilotswarm-aks-identitySkill
- pilotswarm-azure-deployerSkill
- pilotswarm-azure-lessonsSkill
- pilotswarm-cli-builderSkill
- pilotswarm-duroxide-versioningSkill
- pilotswarm-hybrid-datastoreSkill
- pilotswarm-knowledge-harvesterSkill
- pilotswarm-portal-builderSkill
- pilotswarm-sdk-builderSkill
- pilotswarm-three-tierSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

