traverse-framework / traverse-framework/registry
Publish capability: core.check-declared-permission (authz from declared roles/permissions)
- Dominant language
- Rust
- Stars
- 1
- Forks
- 1
- Avg merge
- 1h 17m
- Merged PRs (30d)
- 217
Description
## Why
`core.authorize` is a full policy evaluator (RBAC/hybrid rules, tenants, break-glass, obligations). Many agent tool gates only need a **thin check**: does this principal's *declared* roles/permissions satisfy a required permission for an action? That smaller contract is easier for first publishers and for runtime wrappers that already resolved roles upstream.
## One-PR ask
Publish **`core.check-declared-permission@1.0.0`**:
**Inputs:**
- `principal`: `{ "id": string, "roles"?: string[], "permissions"?: string[] }`
- `required`: `{ "permission": string }` OR `{ "any_of": string[], "all_of"?: string[] }` — pick a tight shape; document
- `role_permissions?`: map of role → permission string[] (caller-supplied so evaluation stays pure)
- `action?`: string (echo/trace only)
- `resource?`: `{ "type"?: string, "id"?: string }` (echo/trace only; **no** resource-attribute policy language — that's `core.authorize`)
**Outputs:**
- `decision`: `allow` | `deny`
- `reason_code`: e.g. `permission_granted` | `role_grants_permission` | `missing_permission` | `invalid_principal`
- `matched`: string[] (which permissions/roles satisfied)
- `evaluation_trace`: string[]
**Behavior:** Deterministic set logic. Deny by default. Invalid input → deny + `invalid_*` reason (fail closed). Prefer requiring `role_permissions` when roles are used so the capability never hardcodes a role catalog.
Follow [`CONTRIBUTING.md`](https://github.com/traverse-framework/registry/blob/main/CONTRIBUTING.md) and [`capabilities/README.md`](https://github.com/traverse-framework/registry/blob/main/capabilities/README.md) publish checklist.
- Include `capability-src/` with real Rust tests meeting registry coverage gates (`functions` 100%, lines/regions ≥ 95%)
- Use `traverse-cli capability publish` (or the documented scaffold) so `artifact.digest` / `artifact.url` survive
- Declare `authoring.method` (`human` or `llm-assisted`)
- Ensure every `use_cases[].persona_ref` resolves (scaffold personas if needed)
- Run `bash scripts/ci/pre_pr_check.sh ` before opening
- One capability per PR; branch from `origin/main`, not another `publish/*` branch
**Apps are not ready — publish the capability only.** No app wiring, no demo product surface.
## Out of scope
- Replacing `core.authorize` (no break-glass, no obligations, no tenant isolation rules)
- OIDC/JWT parsing or network calls to an IdP
- Mutating sessions (`identity.*` caps)
## Done when
- CI green; published in next index
- Tests: direct permission allow, role-mapped allow, deny default, invalid principal
- Contract text explicitly distinguishes from `core.authorize`
## Host / deps notes
**Pure WASM.** No connector, no host state, no network. Caller supplies already-declared roles/permissions.
## Labels
`help wanted` · `good first issue` · `enhancement` · `no-spec-needed`
Contributor guide
Research direction
Start with CONTRIBUTING.md and capabilities/README.md, then inspect the documented scaffold or traverse-cli capability publish flow and the capability-src Rust test requirements. Run bash scripts/ci/pre_pr_check.sh against the draft PR body. Done means a pure WASM capability is published with resolved persona references, preserved artifact metadata, passing tests for permission, role, deny, and invalid-principal cases, and contract text distinguishing it from core.authorize.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- authorization, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100