aic-exec — varwof-exec-v1 (EN)EN
The varwof/exec-v1 capability scheme
A CLC-v1 capability scheme for command execution. It defines how a shell-free
command vector (argv) is turned into a CLC operation and authorized
against the AIC grant set. Policy lives entirely in CLC; the scheme supplies
the identifier grammar and the projection rules only.
Status: design + reference implementation (local, uncommitted). Grounded in
the behaviour of github.com/varwof/register/semantics (CLC-v1), verified by
probe, not by reading.
1. Capability identifier
varwof/exec-v1:<tool>:<action>
<tool>— the executable family (git,ls,mysql,kubectl, …). It is the grantable unit.<action>— the verb derived fromargv(the subcommand), or the tool's fixed action. Segment charset[A-Za-z0-9._-]+.
A grant may use a trailing wildcard on the action:
| Grant | Covers |
|---|---|
varwof/exec-v1:git:* |
every action of git |
varwof/exec-v1:git:status |
exactly git status |
There is no cross-tool wildcard (verified)
CLC's namespace is parts[0]+":"+parts[1] of the identifier, so
varwof/exec-v1:* has namespace varwof/exec-v1:* and does not match
varwof/exec-v1:git:status (namespace varwof/exec-v1:git) — the verdict is
deny / different_namespace. Mid-segment wildcards (varwof/exec-v1:*:status)
are unsupported_wildcard.
Consequences, by design:
- Authority is granted per tool. There is no single "allow all exec" grant; an agent trusted for everything carries one grant per tool.
- This is the least-privilege default and is intentional. Do not try to synthesize a global wildcard; enumerate grants.
2. Operation projection
The projector is deterministic and fail-closed: an argv it cannot fully
classify is a deny (a projection failure, not a policy verdict).
argv[0] basename ──must be in the tool table──▶ <tool>
remaining tokens ──parsed by the tool's action kind──▶ <action>
every other token ──consumed by param rules or──▶ projection error
Action kinds
| Kind | Action | Non-flag tokens |
|---|---|---|
subcommand |
the first non-flag token (must match the action charset) | the rest are positionals |
fixed |
the constant value |
all are positionals |
Examples: git status → action status; ls -la /tmp (tool ls,
fixed action list) → action list, positional /tmp.
Parameters
A tool declares a fixed parameter schema. Key closure in CLC requires the operation's param key set to equal the covering grant's param key set, so the projector always emits every declared key (with a zero value when absent).
| Kind | Emitted value | CLC meaning |
|---|---|---|
flags |
sorted, deduped list of tokens starting with - |
array = allowed set |
positionals |
remaining non-flag tokens | array = allowed set |
string |
value of --name=…, else "" |
exact match |
number |
parsed value of --name=…, else 0 |
upper bound |
Only flags is universal; the others are declared per tool.
3. Authorization (CLC decides)
op := semantics.Operation{ID: "varwof/exec-v1:<tool>:<action>", Params: <projected params>}
dec, err := aicverifier.AuthorizeOperation(ac.AIC, nil, op.ID, op.Params)
The verdict is one of:
allow— run the command.deny+ normative reason — do not run. Reasons observed:capability_not_authorized,params_exceed_grant,params_missing,undeclared_param: <k>,not_in_enum,different_namespace,wildcard_requires_trailing_segment.allow_unresolved+unresolved[]— the grant carried recognized-but-unevaluated constraints. The executor must evaluate each before acting, else deny.
Constraints available to an exec grant
CLC-v1 recognizes exactly three constraint identities (unknown_constraint
otherwise — a custom type requires extending register/semantics, a
cross-repo change):
| Constraint | Core-evaluated | Effect |
|---|---|---|
varwof/constraint-v1:max_rows:N |
yes | op max_rows must be present and ≤ N; else max_rows:violated |
varwof/constraint-v1:time:window:[{"start":"09:00","end":"17:00"}] |
no | allow_unresolved; executor checks the clock |
varwof/constraint-v1:network:cidr:["10.0.0.0/8"] |
no | allow_unresolved; executor checks the peer address |
Everything else an exec policy needs must be expressed through the capability
id + params (action granularity, flags/positionals enums, numeric bounds).
4. Example grants
// all git, nothing else
{"scheme":"varwof/exec-v1","id":"git:*"}
// git read verbs, but only the listed flags
{"scheme":"varwof/exec-v1","id":"git:status",
"params":{"flags":["--short","--branch"]}}
// a query tool capped and time-boxed
{"scheme":"varwof/exec-v1","id":"mysql:query",
"params":{"flags":[],"max_rows":10},
"constraints":["varwof/constraint-v1:time:window:[{\"start\":\"09:00\",\"end\":\"17:00\"}]"]}
Note on params: because of key closure, a grant with params must declare
exactly the tool's declared keys (flags plus any tool-specific keys).
5. What the scheme does not do
- It does not authenticate — AIC + aic-verifier do (CLC consumes grants).
- It does not execute or enforce timeouts —
execerdoes. - It does not constrain argv order (arrays are sets in CLC), so positional sequences must be decomposed into the id or left unconstrained.
- It does not allow arbitrary path/ref arguments under a constrained grant; use exact strings, or wrap the command behind a narrower tool.