Permission Manager
sickn33/agentic-awesome-skills
Manage opencode permissions: review always-allow lists, suggest safe read-only commands, configure permission patterns
Audit an existing enterprise permission-group item end-to-end — registry entry, schemas, type, defaults, tolerant parser, admin UI, capability rule, enforcement site, and tests — proving the gate…
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install simstudioai/sim validate-permission-group-item --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .claude/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .claude/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-itemType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install simstudioai/sim validate-permission-group-item --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .agents/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .agents/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install simstudioai/sim validate-permission-group-item --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .cursor/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .cursor/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/simstudioai/sim.git --path .agents/skills/validate-permission-group-item--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install simstudioai/sim validate-permission-group-item --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .gemini/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .gemini/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install simstudioai/sim validate-permission-group-itemInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .github/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .github/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add simstudioai/sim --skill validate-permission-group-item -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install simstudioai/sim validate-permission-group-item --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/simstudioai/sim.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/validate-permission-group-item .opencode/skills/validate-permission-group-item && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "validate-permission-group-item" agent skill from https://github.com/simstudioai/sim/tree/main/.agents/skills/validate-permission-group-item into .opencode/skills/validate-permission-group-item/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "validate-permission-group-item", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
validate-permission-group-itemAudit an existing enterprise permission-group item end-to-end — registry entry, schemas, type, defaults, tolerant parser, admin UI, capability rule, enforcement site, and tests — proving the gate…
Validate Permission Group Item is an agent skill from simstudioai/sim. Audit an existing enterprise permission-group item end-to-end — registry entry, schemas, type, defaults, tolerant parser, admin UI, capability rule, enforcement site, and tests — proving the gate actually refuses rather than assuming it. Use when checking a key in PERMISSIONGROUPFIELDS or a capability in CAPABILITYRULES.
Its SKILL.md is about 5.9k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: Sim is the collaborative workspace to build, deploy, and monitor AI agents and workflows. Used by 100,000+ builders. The licence is Apache-2.0.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 546d4e7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
bungitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Validate Permission Group Item loads about 5.9k tokens when it runs. Until then it costs about 90 tokens; SKILL.md has 2,940 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from simstudioai/sim at commit 546d4e7, republished under its Apache-2.0 licence (© simstudioai). 2,940 words, ~5,882 tokens.
.claude/skills/validate-permission-group-item/SKILL.md (or your agent's skills folder).The question is not "does this key exist in the right places" — the registry makes most of that compiler-enforced. It is:
If an organization admin sets this, what refuses, and can I make that refusal happen?
A key with an admin checkbox but no server gate passes every structural audit. Assume nothing enforces until you have found the throw.
add-permission-group-item owns the procedure and the rationale for every invariant named below. Read it for why; this skill is the checklist. Its "Read the system first" list is the same one — start there.
lib/permission-groups/fields.ts)Record the builder, the enforcement, and the position.
false / null / [], so the risk is a name that inverts the meaning — an allowX boolean. The checkbox renders checked={!editingConfig[feature.configKey]} (ticked = allowed), so a positively-named boolean renders backwards.git log -p shows the key was ever moved rather than appended, every open editor reads as unsaved (group-detail.tsx dirty-checks stringified configs).{ limited, empty } and a denylist's string are read by getActivePermissionGroupRestrictions in features.ts and surface to users through the Copilot workspace VFS and the enterprise platform context. Confirm empty says "none allowed", not "unrestricted".hint tell the truth? Highest-value read in this step. A 'capability' key refuses at the API, so a hint saying it hides a tab, module, or nav item "from the sidebar" is a lie an admin acts on — they believe they are tidying chrome while withholding a module. The same string is reused as the prose for an active restriction, where "hide" is simply false. Any surviving "Hide the …" hint on a 'capability' key is a finding, not a nit; check label and category the same way (a "Sidebar" or "Settings Tabs" section makes the claim structurally).All derived by collectFieldProperty from the same registry. Do not hand-verify them. Verify nothing bypasses the derivation:
grep -rn "<configKey>" apps/sim --include='*.ts' --include='*.tsx' \
| grep -vE 'lib/permission-groups/(fields|resolve\.server|config-scope\.server)\.ts'Only the registry and the resolvers are excluded, so capabilities.ts stays in the output — its CAPABILITY_RULES entry and deniedBy are the authoritative reads this step exists to check. Every hit should be a rule's deniedBy, an enforcement site, a UI binding, or a test. A route restating the key, a client re-deriving a default, or a second coercion path is a leak. Specifically:
z.array(...).catch(...) anywhere on this key's path — whole-value tolerant, so one bad member discards every good one, and on an allowlist the null fallback means unrestricted. That is fail-open. tolerantArray filters element-wise. Rank a regression here with the enforcement findings.?? [] applied to an allowlist — collapses "allows everything" into "allows nothing".allowedIntegrations and the deployment's ALLOWED_INTEGRATIONS are written independently, so one names slack where the other names slack_v2; anything folding only case intersects them to nothing and hides an integration both allow. Both halves must canonicalize through integration-allowlist.ts (intersectAccessControlAllowlists / toAccessControlAllowlist / resolveAccessControlBlockType) before intersecting, with the checked type resolved the same way. That module reads block-successors.generated.ts through Object.hasOwn — a bare bracket lookup answers an admin-supplied constructor with an inherited function and 500s every path reading that group; check:block-successors catches the map going stale.parsePermissionGroupConfig or a resolvePermissionGroupConfig caller.Two structural guards must still be present:
parsePermissionGroupConfig still tests Array.isArray(config). typeof [] === 'object', the column is jsonb so a row genuinely can hold [], and z.object().parse([]) throws — the guard is what returns defaults instead of a 500. tolerantArray carries the mirror image.CAPABILITY_RULES still uses satisfies, not an annotation. An annotation collapses StaticPermissionGroupCapability to never, silently disabling the type system around capabilities with nothing wrong at runtime. AssertsStaticCapabilityResolves catches it; any weakening is a top-tier finding.Confirm the assertions at the bottom of fields.ts still name a field of this kind (AssertsAllowlistStaysPrecise, AssertsDenylistStaysPrecise, AssertsRestrictionStaysPrecise, AssertsAuthTypesStayPrecise, AssertsParserReturnsTheConfig) — a zod generic degrading to unknown is invisible at runtime and quietly loses every call site's narrowing.
ee/access-control/components/group-detail.tsx)PLATFORM_FEATURES. Confirm its category is in PLATFORM_CATEGORY_ORDER; an unlisted one renders after every ordered section.featureExtras map — keyed by the parent boolean's feature id, not the config key. No picker there means no admin can ever set it. Report it. Top-level lists — allowedIntegrations, allowedModelProviders, deniedModels, deniedTools — are not in featureExtras and must not be reported for it; they render from the dedicated Providers and Blocks sections, so check them there.if (values.length === 0) return) and collapses a full one back to null (otherwise the allowlist freezes at today's members). A denylist picker must do neither: clearing every entry is how an admin denies nothing, and a full selection is a real state that denies everything.allowedKnowledgeConnectors under hide-knowledge-base, not disable-knowledge-base-creation).A 'capability' key must appear in some rule's configKeys — the audit asserts this (D) and the converse (E): a key declared 'executor' or 'ui-only' that a rule reads is flagged, so a key cannot gain enforcement while staying documented as weaker. Then check what the audit cannot:
configKeys lists every key deniedBy reads. The audit parses it textually and never reads the closure; a key read but unlisted is invisible to D and E.kind is right. A rule needing a request value must be 'parameterized' — and a parameterized rule named on an operation cannot have run in production (defineWorkspaceOperation throws at definition time), so something else is wrong.knowledge.create / knowledge.upload both read hideKnowledgeBaseTab, without which a group withholding the whole module could still create a KB through the API. Check git log for a re-pointed capability: and verify the narrower rule grew the broader key in the same commit.detailCode matches the remedy — FORBIDDEN_DETAIL_CODES is closed over remedies, not causes; otherwise PERMISSION_GROUP_CAPABILITY_BLOCKED. Any code in use needs a TSDoc-documented entry in FORBIDDEN_DETAIL_CODES, published to OpenAPI as the V2ForbiddenDetailCode enum.describe reads correctly as the subject of "<describe> is not available under your organization's permission group" — a singular noun or gerund agreeing with "is". Exactly two functions build that sentence, both defined in capabilities.ts (refuseCapability throws it, capabilityRefusal returns it); any call site writing it out is a drift finding.The step the skill exists for. Find the actual refusal, name file and line, and say what a caller sees.
grep -rn "'<capability-id>'" apps/sim --include='*.ts' --include='*.tsx'
grep -rn "permission-group-enforced: <capability-id>" apps/simThe second grep misses a gate whose annotation sits in a TSDoc block above the enclosing statement — read the surrounding function.
Classify into exactly one of:
requireCurrentHumanAccess → requireCapability. Verify the set is complete: enumerate every route and tool reaching the same behavior. One declaring capability: 'none' is the hole.// permission-group-enforced: <id> — <reason> annotation. Verify it goes through capability-assertions.ts (assertWorkspaceCapability, isWorkspaceCapabilityWithheld, isOrganizationCapabilityWithheld, capabilityDeniedBy), through isCapabilityWithheldForUser (lib/permission-groups/user-scope.server.ts — workspace group first, else the organization's default, for a user-level act that may or may not name a workspace; outside capability-assertions.ts on purpose because it reads org membership through the billing graph, a guarded root of check:application-graph; app/api/cli/auth/approve/route.ts is the shape), or a direct CAPABILITY_RULES['<id>'].deniedBy(...) rather than reading config.disableX inline, and that it raises through refuseCapability / renders capabilityRefusal(cap) rather than building its own ForbiddenOperationError with a hand-written message — the easy half to miss, because the decision looks right. Use-case shape: validatePublicFileSharing, validateChatDeployAuth (ee/access-control/utils/permission-check.ts), assertConnectorTypeAllowed (lib/knowledge/application/connectors.ts). Raw-route shape: app/api/logs/stats/route.ts, app/api/table/[tableId]/export/route.ts. A raw route should render through capabilityRefusalResponse (lib/permission-groups/capability-response.ts), which reads details.code off the rule — a hand-rolled NextResponse.json({ error: capabilityRefusal(cap) }, { status: 403 }) drops it, reporting the four specifically-coded capabilities (deploy.chat.auth_mode, file_share.publish, file_share.auth_mode, personal_api_key.use) as the generic block. Convergence is partial: grep -rln "capabilityRefusal(" apps/sim/app --include=route.ts lists the raw routes that still hand-roll it (ignore *.test.ts, app/api/v1/middleware.ts, app/api/table/utils.ts, and the v2 envelope, which are not raw-route responses). A raw route you add or touch renders through capabilityRefusalResponse; report an untouched hand-rolled one as a finding when its capability carries a specific code, otherwise as a note. v1 is deliberately not converged on it (resolveCapabilityRefusal in app/api/v1/middleware.ts).assertPermissionsAllowed, per block / tool / model, matching through the shared primitives in lib/permission-groups/ — block-access.ts, operation-access.ts, model-access.ts, integration-allowlist.ts — which the editor and Copilot projections read too, so a second copy of a match rule is a finding. Verify the branch throws a real error and that the id it compares against is the vocabulary the admin UI writes — deniedTools holds block tools.access ids verbatim, version suffix included. allowedIntegrations is also enforced off the run, by assertSelectorIntegrationAllowed (lib/selectors/server/integration-access.ts), so an executor key's coverage is not complete until every non-run path that reaches the third party is checked too.logs.trace_spans and logs.cost withhold fields, so the logs routes correctly declare capability: 'none'. Single owner: lib/logs/log-projection.ts (resolveLogFieldProjection, projectExecutionData, projectCostTotal), which carries both annotations. A second implementation of the same redaction is the finding — as is a query that lets a caller filter or sort on a withheld field, which turns the projection into an oracle.Ahead of all five: the principal-wide capabilities (personal_api_key.use, oauth_apps.use; PRINCIPAL_WIDE_CAPABILITIES in lib/core/application/operation.ts) fit none of them. They withhold a principal kind across every operation — the funnel's personal_api_key / oauth_access_token branches (lib/core/application/workspace-authorization.ts) and app/api/v1/middleware.ts — and declaring one on an operation throws, so their absence from every capability: field is correct, not a hole.
Then make the refusal happen: write a failing case, or remove the gate (the capability: field, the deniedBy body, the assertion call) and confirm an existing test goes red. A test that still passes with the gate removed proves nothing. Restore afterward. Check the fixture's workspaceOrganizationId first: requireCapability short-circuits when it is null (requireCapability in lib/core/application/workspace-authorization.ts), so a context that leaves it unset passes either way and the existing test proves nothing even before you touch it.
For an allowlist the three states must be tested separately — null permits every member, a populated list only the named ones, [] permits none. capabilities.test.ts pins all three for knowledge.connectors; less than that elsewhere is a gap.
Read the subject, not the nearest user id. Every capability sink must take its subject from the capabilityGoverned* helper for the identity the surface holds — capabilityGovernedPrincipalUserId for a Principal (lib/core/application), capabilityGovernedUserId for a v1 RateLimitResult or a TableAccessPrincipal, capabilityGovernedAuthUserId for a checkSessionOrInternalAuth result. Each returns null where no group governs, and null is a pass. Reading rateLimit.userId, auth.userId, subjectUserId or triggeredByUserId into a sink is the finding: for a workspace key the first is the key's creator, for an internal JWT the second is the run's actor, and the last is a billing attribution. check-capability-subject.ts audits v1 only, so every other surface is on you. Where the subject is persisted and read back later (capabilityGovernedUserId on table_run_dispatches / table_row_executions), it must be declared required as string | null — an optional field with a fallback is exactly how producers re-inherited triggeredByUserId, so a proposal to make it optional is a finding.
/api/v1 authorizes in app/api/v1/middleware.ts, not through authorizeWorkspaceOperation; capabilityGovernedUserId(rateLimit) branches on keyType, never on the presence of a user id. Each route also threads a required, spelled-out V1RouteCapability.tables.use in checkAccess (app/api/table/utils.ts) via a TableAccessPrincipal union — { kind: 'user'; userId } or { kind: 'workspace_api_key'; keyCreatorUserId } — so a bare id does not type-check. tableAccessPrincipal(rateLimit) is the one place v1 builds it.undefined guard on defineWorkspaceOperation is not redundant even though capability is required on the ApplicationOperation base type (the capability field in lib/core/application/operation.ts, not merely on the builder — which is what stops a bare-literal factory from compiling): apps/sim/tsconfig.json excludes *.test.ts / *.test.tsx and the enforcement audit walks past test files, so a fixture is the one construction site no static check reads. Without it a capability-less operation defines cleanly and then throws Cannot read properties of undefined inside capabilityDeniedBy only for tenants that actually have a permission group, passing CI and every personal workspace. A proposal to drop it is a finding.fields.test.ts — the key must be in both the input and expected halves of the 'a fully populated config' fixture; that corpus is pinned so a changed row is defended rather than slipping through. The rest of the file derives from DEFAULT_PERMISSION_GROUP_CONFIG and needs no per-key edit.capabilities.test.ts — a case for any rule with logic beyond reading one key: subsumption, allowlist three-state, auth-mode membership.features.test.ts — no edit for a boolean; a non-boolean key's limited / empty prose should be pinned here.config-scope.server.test.ts — the per-request memo. A gate resolving the config outside resolvePermissionGroupConfig is a Step 2 finding, not one here.bun run check:permission-group-enforcement
bun run check:application-graph
bun run check:capability-subject
cd apps/sim && bun run type-check
bun run --cwd apps/sim test lib/permission-groupsAll three are inside check:audits, which derives its list from the check:* scripts in package.json — a new audit is opted out deliberately. Read the output, not the exit codes. Success-line shapes (the counts must include the item under audit):
✓ permission-group enforcement: <N> operations declare a capability, <M> capabilities all enforced
✅ Application graph clean: <N> roots reach none of <M> forbidden module trees
check:capability-subject — <N> v1 files, <M> capability subjects resolved through capabilityGovernedUserId.| Audit | What it catches |
|---|---|
check:permission-group-enforcement | Every operation declares a capability and every capability is enforced. All-or-nothing — no migration mode exits 0 with work outstanding, so do not go looking for a pending enforcement: list |
check:application-graph | The funnel roots (lib/core/application/index.ts, capabilities.ts, capability-assertions.ts, config-scope.server.ts) and with-route-handler.ts reach no heavy module tree at runtime (import type is erased and allowed). A gate that imports a resolver into a guarded root is a finding even if the gate is correct; such an edge can also make unrelated tests fail on partial mocks |
check:capability-subject | Every v1 capability sink takes its subject from capabilityGovernedUserId, no v1 file outside the middleware imports the permission-group modules, and at least one governed sink was found at all |
Two ways the enforcement audit passes without proving what you want:
id, fails a file that mints an operation but parses to zero declarations, and flags any exported *Operations registry member it read no operation from. If one fires the audit is broken, not the code — fix the parsers rather than leaving it green. (That last guard is what catches an operation minted by a factory that never calls the builder, which bypasses the required type and the audit.)The audits prove reachability, never correctness — that a capability is named, a key is read by some rule, a subject came from the right helper. Step 5 is what covers the rest.
Each is deliberate and documented in the code; add-permission-group-item carries the full reasoning.
operation.capability does not apply; the same reasoning shapes TableAccessPrincipal, capabilityGovernedUserId and the log projection. Substituting the key's creator would apply a bystander's group to every caller of a shared key and break the key when that person left. Minting a workspace key is itself capability-gated.executor principal with a sim_user subject goes through requireCurrentHumanRole only. A capability names what a person may reach; applying it to a run makes "hide Tables" a kill-switch for every workflow with a Table block.mode: 'deployment' with no resolvable subject acts with the workspace's authority; denying would 403 every scheduled run, webhook and public-API call. What such a run does is still governed by assertPermissionsAllowed, which is why the four run-scoped keys carry enforcement: 'executor'.sim_user subject whose serviceId is anything other than executor takes the full requireCurrentHumanAccess. Copilot acts as the person. A proposal to exempt it is a finding.NoWorkspaceAccessError is concealed as a 404 by the v2 surface, so refusing on capability first would hand a non-member an oracle for what the organization withholds. The v1 middleware states the same ordering in its TSDoc. Not a bug.allowedEgressHosts does not exist — there is no network-egress allowlist. Requests for one are a feature, not missing wiring.ui-only — the union member has no user; an absent ui-only key is not a gap.detailCode, message). Or: it is a projection, and here is its single owner. Or: nothing refuses..catch() on an array, a dropped Array.isArray guard, CAPABILITY_RULES annotated instead of satisfies) > incomplete operation coverage > allowlist three-state confusion > admin copy that misstates the enforcement > duplicated projection logic > missing admin UI > missing test > cosmetic.A hint saying "hide" for a key that 403s is not cosmetic — it is the one defect an admin acts on directly: they tick it believing they hid a link, and members lose the module. Rank it with the enforcement findings.
© simstudioai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/validate-permission-group-item of simstudioai/sim.
Open the folder on GitHubat commit 546d4e7
Validate Permission Group Item next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Validate Permission Group Item this skillsimstudioai/sim | 30k | — | ~5.9k | Automated safety check: Pass | Apache-2.0 | |
| Permission Managersickn33/agentic-awesome-skills | 47k | 1 repos | ~595 | Automated safety check: Pass | MIT | |
| Groupsparcadei/Continuous-Claude-v3 | 3.9k | 1 repos | ~956 | Automated safety check: Notes | MIT | |
| Cognee Permissionstopoteretes/cognee | 32k | — | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Action Items List Managerasgeirtj/system_prompts_leaks | 69k | — | ~4.9k | Automated safety check: Pass | CC0-1.0 | |
| Fewer Permission Promptsasgeirtj/system_prompts_leaks | 69k | — | ~1.9k | Automated safety check: Pass | CC0-1.0 |
sickn33/agentic-awesome-skills
Manage opencode permissions: review always-allow lists, suggest safe read-only commands, configure permission patterns
parcadei/Continuous-Claude-v3
Problem-solving strategies for groups in abstract algebra. An agent skill from parcadei/Continuous-Claude-v3.
topoteretes/cognee
A skill your agent uses when working with cognee's users, permissions, and multi-tenancy — creating users, tenants and roles, sharing datasets (read/write/delete/share grants), acting as a specific…
asgeirtj/system_prompts_leaks
Maintains a private to-do list stored as a JSON file in the assistant's notes: adding tasks, recording what is awaited, tracking blockers and closing finished items.
asgeirtj/system_prompts_leaks
Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing HTTP response headers for defense-in-depth security hardening on any web application.
simstudioai/sim
Install, upgrade, and operate the Sim Helm chart on Kubernetes.
simstudioai/sim
Add a new table column type to Sim — registry entry, icon, storage shape, coercion, and the behavioral hooks the grid and API read.
simstudioai/sim
Add a code-defined table enrichment (registry entry) under apps/sim/enrichments/ backed by an ordered provider cascade, ensuring every provider tool it calls has hosted-key support.
simstudioai/sim
Add hosted API key support to a tool so Sim provides the key (metered and billed to the workspace) when a user has not brought their own.
simstudioai/sim
Add or upgrade a curated, immutable managed CLI for Sim Function sandboxes, including client-safe catalog metadata, a pinned server-only installation recipe, checksum and executable verification…
simstudioai/sim
Add or update a Sim dynamic selector using the shared manifest, server attachment, and selectors.execute path.
Audit an existing enterprise permission-group item end-to-end — registry entry, schemas, type, defaults, tolerant parser, admin UI, capability rule, enforcement site, and tests — proving the gate…. Validate Permission Group Item is an agent skill from simstudioai/sim. Audit an existing enterprise permission-group item end-to-end — registry entry, schemas, type, defaults, tolerant parser, admin UI, capability rule, enforcement site, and tests — proving the gate actually refuses rather than assuming it.
Validate Permission Group Item fits situations like: checking a key in PERMISSIONGROUPFIELDS; A capability in CAPABILITYRULES.
Run `npx skills add simstudioai/sim --skill validate-permission-group-item -a claude-code`. Or copy the skill folder (.agents/skills/validate-permission-group-item in simstudioai/sim) into .claude/skills/validate-permission-group-item in your project. Claude Code loads it when a task matches its description.
Run `npx skills add simstudioai/sim --skill validate-permission-group-item -a codex`. Or copy the skill folder (.agents/skills/validate-permission-group-item in simstudioai/sim) into .agents/skills/validate-permission-group-item in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add simstudioai/sim --skill validate-permission-group-item -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/validate-permission-group-item, .gemini/skills/validate-permission-group-item, .github/skills/validate-permission-group-item and .opencode/skills/validate-permission-group-item in your project.
Going by SKILL.md and its folder, Validate Permission Group Item needs the command-line tools its instructions call (bun and git).
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Validate Permission Group Item is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.9k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Validate Permission Group Item: Permission Manager (sickn33/agentic-awesome-skills, 47k stars), Groups (parcadei/Continuous-Claude-v3, 3.9k stars), Cognee Permissions (topoteretes/cognee, 32k stars) and Action Items List Manager (asgeirtj/system_prompts_leaks, 69k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
simstudioai (a GitHub organization) maintains it in simstudioai/sim, which has 29,785 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 7, 2026.
Source: simstudioai/sim on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.