About make-app-permission
A skill for implementing and auditing single-app permissions in Make App. It covers IAM permission transport, schema-aware field access, route and action guards, secure mutation payloads, and permission refresh behavior.
Key features
- 01IAM permission endpoint contract
- 02Schema-aware field access
- 03Route and action guards
- 04Mutation payload allowlists
- 05Permission refresh and invalidation
- 06Conformance tests and audits
Use cases
- 01Adding permission checks to an app
- 02Restricting create and edit fields
- 03Testing access denial and refresh
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ qfeius/ make-platform-skills --skill make-app-permissionAfter installing, type/make-app-permissionin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agents/openai.yamlreferences/permission-boundaries.mdscoped-route-feedback.mdservice-principal-permission.mdsystem-field-contract.mdtesting-and-audit.mdui-permission-runtime.mdscripts/audit-make-app-permission.mjscheck-installed-skill-sync.mjspermission-conformance-suite.mjsprincipal-response-conformance-suite.mjsscoped-route-feedback-audit.mjstest-audit-make-app-permission.mjstest-installed-skill-sync.mjstest-permission-conformance-suite.mjstest-scoped-route-feedback.mjsDetails
From the project READMEmake-app-permission
Direct URL and runtime resource denial follow references/scoped-route-feedback.md: App guard outside shell, object/fixed-route guards inside shell. Replace the entire denied business content, not just table rows; keep authorized navigation and the global identity header. Require rendered-tree and zero-denied-request regression tests. React renders the verified package through makeui/references/permission-feedback.md; this Skill decides scope and access lifecycle, not component styling. Read make-app-auth/references/access-help.md for current-App personnel contacts without sending denied business requests.
Use this skill when a request creates, changes, reviews, or debugs Make App single-app permission enforcement. It must be enabled by default for every generated or refactored Make App. Do not omit the IAM proxy, route guards, permission-aware Schema, or permission audits merely because the request focuses on UI, Service, Schema, or runtime work.
This skill owns permission semantics. Use make-app-auth for login/session, make-app-service for Service and Schema transport, makeui for rendering, canvas-table-integration for cell-editor mechanics, and make-app-runtime for packaging/runtime.
Quick start
- Inspect
apps/docs/api.md, Service/UI schema adapters and types, principal-permission code, providers, router, object pages, create/edit forms, submit builders, refresh flow, and tests. - Read
references/permission-boundaries.mdbefore selecting scope, permissionKey, schema collection, or field access state. - Read
references/service-principal-permission.mdbefore changing/principal/permissionor interpreting IAMfieldAccess. - Read
references/ui-permission-runtime.mdbefore changing route/action gates, create/read/update field sets, payload filtering, or refresh. - Read
references/system-field-contract.mdbefore implementing ID/audit create or edit capability. - Read
references/testing-and-audit.mdbefore implementation and before reporting completion. - Implement tests first, then the Service/schema boundary, permission pure model, route/action gates, field-set consumers, submit allowlists, and refresh invalidation.
- Run host tests, the behavioral conformance suite, and
node skills/make-app-permission/scripts/audit-make-app-permission.mjs <project-root>. Wire both permission checks into the host's default test, CI, or publish gate; a one-off local run is not a continuous gate. - When publishing or installing this Skill, run
check-installed-skill-sync.mjswith explicit source and installed directories. When the release changes shared Make response/auth/permission guidance, publish the platform package, runnpx skills update qfeius/make-platform-skills, then run the repository-widecheck-installed-make-platform-skills-sync.mjswith explicit source and installed Skill roots. Keep these local release checks out of portable host CI.
Required contract
本节的 createFields ∩ meta.field.read 规则适用于普通新建。对象有有效 bpmDefinitionKey 时,先按 make-app-approval 选择审批新建分支:UI 和 Service 均以启动配置授权字段为准,不再与普通 IAM 字段集合求交;应用、对象及新建操作权限仍保留。此例外不扩展到普通已有记录编辑,也不把“我的审批”固定导航作为业务对象菜单权限项。详细合同见 审批新建字段。
- Expose
/api/make/app/principal/permission; have Service call/api/make/iam/v1/principal/permissionwith App scope,MakeService.GetResource, and the established login context. This is a direct Make proxy: return every completed IAM response unchanged, including 2xx/4xx/5xx status, Content-Type, and body. Do not request tenant-root scope or upstream platform permission filters. Before strict normalization, classify rows withreferences/permission-boundaries.md: ignore only clearly unrelated rows, and fail closed for every selected or unclassifiable row. - Current-context-based tenant resolution follows
make-app-auth/references/service-fronted-mode.md#current-context-consumption. Only the actual App-scoped IAM response is the principal-permission result, not auth compatibility claims. - The IAM wire success is
{code:200,data:{principal,scope,permissions}}, unlike bare auth identity. Service preserves it; the UI request adapter checks code and unwraps data exactly once before permission normalization. Verify the production UI loader boundary as well as the DTO-only pure model; seereferences/testing-and-audit.md. - Match exact, wildcard, parent, App, entity, IAM namespace-wildcard App resources, and deny correctly. Use the most-specific allow field range; deny wins.
- Keep create, visibility, and editability as separate field-set decisions:
- create form:
createFields ∩ meta.field.read fieldAccess(creatable|readonly|editable|partialMask|fullMask|*); - list/detail/filter:
fields ∩ meta.field.read fieldAccess(readable states); - edit/cell edit: visible
fields ∩ meta.field.update fieldAccess(editable|*).
- create form:
- Keep entity, field and record authorization independent:
meta.entity.readcontrols whether a Schema-present entity appears in navigation and can enter its object route; both the navigation and the dynamic route must reject the entity when this permission is absent.meta.field.readcontrols authorized columns/table headers when business content is rendered;data.record.readcontrols record/detail requests and values. Denied or revoked record read does not remove metadata-authorized navigation or rewrite field grants, but replaces the current record-reading business content as a whole with resource feedback. Unmount its title, toolbar, headers, data and dialogs, skip denied requests, and invalidate cached values and stale work. Do not preserve an empty table shell around the feedback. - Preserve every access state returned for a field. Current IAM responses may use arrays such as
["creatable", "readonly"]or scalar strings; normalize a supported scalar string to a one-element array and authorize a permission dimension when any state is allowed for that dimension. Never coerce an array withString(value)or template interpolation. - Treat missing
createFieldsas empty. Never fall back tofields, and do not consumeeditableFieldsfor current edit behavior. - Gate the create entry and submit operation with
data.record.create; 普通新建 derives fields from the matchedmeta.field.readrow andcreateFields, while 审批新建 uses the authorized 启动配置 fields frommake-app-approval.meta.field.createis not a platform permission point and must not be required, inferred, or emitted. The operation gate never grants field access; ordinary create retains its field intersection, and approval create retains the separate Workflow field authorization. Gate update/delete/bulk-update independently with their own operation keys. - Recompute the latest create/edit allowlist before submit and build payloads from it. Never spread the complete form store into a protected mutation.
- Exclude ID and system audit fields from create capability. Keep existing audit-field edit capability when the field is visible, update-authorized, and supported by the host editor.
- Keep create-only invisible fields available only in create mode. A
creatableaccess state is not readable or editable. - Add App/object/fixed-route guards; hiding menus or buttons is not authorization. Recheck handlers before reads and mutations.
- Refresh permission and permission-trimmed Schema in one access generation before data refresh. Invalidate stale permission, Schema, form, and record work. Record-read denial does not revoke an independent create route's permission; descendants of the replaced business content still unmount. Operation-only refusal preserves allowed inputs.
- Fail closed on permission or Schema failure. Leave row-level
dataConditionenforcement to backend APIs. - Permission and Schema request failures must retain the safe structured
kind/status/title/description/traceIdfrom the shared request adapter through Provider state to the error outlet. Usemake-app-observabilityfor request-error classification and card presentation; do not reduce these failures to a plain string or expose raw upstream errors. A denied permission result is still a forbidden state, not a fabricated request failure. - Add Service/schema, permission-model, route/page, payload, special-field, refresh, and negative audit tests.
Reference map
| Task | Read |
|---|---|
| Platform vs App scope, create/read/update field surfaces, Schema collections, matching | references/permission-boundaries.md |
Service endpoint, IAM request/response, meta.field.read.fieldAccess | references/service-principal-permission.md |
| Providers, helpers, routes, create/edit flow, payload, refresh, Lookup | references/ui-permission-runtime.md |
| Exact ID/audit create exclusions and edit compatibility | references/system-field-contract.md |
| Required tests, audit signals, completion blockers | references/testing-and-audit.md |
| Auth/session | Use make-app-auth |
| Schema/API transport and cache | Use make-app-service |
| Form/empty-state presentation | Use makeui |
| Table/cell-editor mechanics | Use canvas-table-integration |
| Selection, row precheck, batch actions | Use make-app-actions |
| Runtime gateway and packaging | Use make-app-runtime |
Audit
node skills/make-app-permission/scripts/audit-make-app-permission.mjs <project-root>
Treat failures as blockers and warnings as review items. The audit is heuristic and never replaces runtime tests.
It rejects obvious fieldAccess state-array coercion through String(...), text helpers, template interpolation, .toString(), or .join() when the coerced value affects normalization output or permission evaluation, including direct control-flow conditions. Diagnostic-only logging, comments, and string literals inside a named normalization helper must not fail the audit, regardless of whether the parameter uses a generic or fieldAccess-specific name. The executable behavior contract remains authoritative.
Also expose a thin host adapter and run the executable behavior contract:
node skills/make-app-permission/scripts/permission-conformance-suite.mjs <host-adapter-module>
Also run the wire-response contract against a thin adapter to the production UI permission loader:
node skills/make-app-permission/scripts/principal-response-conformance-suite.mjs <host-loader-adapter-module>
This protects business-code validation, one-time unwrap, empty IAM grants and retained denial contacts; the existing pure-model suite does not exercise SDK response decoding. The adapter contract and host-gate instructions are in references/testing-and-audit.md.
If the adapter is TypeScript, run the same command through the host's existing TypeScript runner. Do not add a runtime dependency only for this check. The adapter must delegate to the production permission helpers and create-capability guard; it must not reimplement them in the test. Keep the audit and conformance runner project-local or install them through a versioned dependency before making them a host gate. Do not hardcode another workspace checkout or a developer home-directory Skill path into portable CI.
For local Skill install/release verification, compare the complete source and installed directories:
node skills/make-app-permission/scripts/check-installed-skill-sync.mjs \
skills/make-app-permission <installed-skill-dir>
The checker reports source-only, installed-only, and content-mismatch files. Pass an explicit install directory; do not embed a developer home path in the Skill or in host CI.
For a release that changes the shared Service/auth/permission contract, update the installed platform package first, then verify all affected Make App Skills:
npx skills update qfeius/make-platform-skills
node scripts/check-installed-make-platform-skills-sync.mjs \
skills <installed-skills-dir>
Run this only after the source revision has been published through the platform Skill release flow. It is a local release verification, not portable host CI.