@hasna/skills 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -324,6 +324,116 @@ are explicitly changed or a new session starts.
324
324
 
325
325
  ## Executable skills
326
326
 
327
+ Selected local executables declaring `runtime.env` use shared execution grants
328
+ by default. An owner or admin reviews a policy containing exact skill versions
329
+ and bundle digests, actor IDs, station IDs, canonical workspace directories, a
330
+ Secrets authority and vault reference names. Actual secret values stay in Secrets.
331
+ Policy documents are private workspace data stored by the Skills service, with
332
+ immutable revision history in SQLite or PostgreSQL; S3 is optional.
333
+
334
+ For example, keep this policy input in private configuration outside the repository
335
+ and skill bundles, replacing the example identifiers and digest with reviewed values:
336
+
337
+ ```json
338
+ {
339
+ "grants": [{
340
+ "id": "provider-access",
341
+ "target": "local",
342
+ "selection": {
343
+ "slug": "your-skill",
344
+ "version": "1.0.0",
345
+ "bundleDigest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
346
+ },
347
+ "actors": ["user-example"],
348
+ "consumers": [{"stationId": "workstation", "workspaceDirectory": "/workspace/project"}],
349
+ "secretsAuthority": "https://vault.example.com/v1",
350
+ "bindings": {"PROVIDER_TOKEN": "my/provider/key"}
351
+ }]
352
+ }
353
+ ```
354
+
355
+ ```bash
356
+ skills grants set default --file ./policy.json --json
357
+ skills grants show default --json --save ./policy-snapshot.json
358
+ skills run --target local --selection-profile default \
359
+ --input '{"requested":"work"}' --json your-skill@1.0.0
360
+ # Updates and revocation require the current policy revision, not the profile revision:
361
+ skills grants set default --file ./reviewed-policy.json --if-match <policy-revision>
362
+ skills grants show default --revision <prior-policy-revision> --json
363
+ ```
364
+
365
+ Updating a policy appends a revision and atomically changes its current pointer.
366
+ An empty `grants` array revokes shared execution access. Historical policies remain
367
+ readable and can be submitted as a new reviewed revision for rollback; they cannot
368
+ authorize an execution directly. Unrelated selection-profile edits do not require
369
+ rewriting the policy. A changed executable version or digest needs a new grant.
370
+
371
+ Each run resolves current authorization through the Skills API before reading
372
+ Secrets. Missing, expired, ambiguous or revoked grants, changed selections and API
373
+ failures stop execution without using a cached grant. Optional `expiresAt` is an
374
+ ISO timestamp; `includeDescendants: true` permits canonical directories beneath a
375
+ consumer's workspace root. Station and path conditions describe client context;
376
+ they are not cryptographic machine attestation. Revocation applies to subsequent
377
+ authorization requests, not already running processes.
378
+
379
+ Grant writers need an owner/admin role and `execution-grants:write` (or
380
+ `execution-grants:*`/`*`); `skills:*` alone cannot grant access. Policy and history
381
+ reads need `execution-grants:read`. Execution resolution accepts `skills:read` or
382
+ `execution-grants:resolve`. Each client still needs independent Secrets access
383
+ to the reviewed references. Managed MCP `run_skill` and SDK `executeSelectedLocal`
384
+ use the same fresh authorization path. `--cached` cannot consume shared grants.
385
+
386
+ Explicit local binding files remain available for callers that manage their own
387
+ authorization. These caller-supplied grants are independent of shared-policy
388
+ revocation. Prepare a template using the configured Skills and Secrets clients:
389
+
390
+ ```bash
391
+ skills run --target local --selection-profile default \
392
+ --secret-bindings-template --json your-skill@1.0.0 > bindings.json
393
+ # Fill each empty entry in bindings with its reviewed vault key, never its value.
394
+ skills run --target local --selection-profile default \
395
+ --secret-bindings ./bindings.json --input '{"requested":"work"}' \
396
+ --json your-skill@1.0.0
397
+ ```
398
+
399
+ The template contains no credential values and does not execute the skill or
400
+ read the declared secrets. Keep the reviewed file in your private configuration,
401
+ outside the skill bundle and agent discovery directories. It uses
402
+ `hasna.skills-secret-bindings.v1` and binds the exact Skills authority, workspace,
403
+ profile ID and revision, canonical skill name, version and bundle digest, plus
404
+ the current station ID (`HASNA_STATION`, otherwise the hostname), canonical
405
+ working directory and independently configured Secrets `/v1` authority. Its
406
+ `bindings` object maps each declared environment name to one vault key. Changing
407
+ any bound field requires reviewing a fresh template. These are explicit local
408
+ execution grants; selection sync does not distribute or implicitly approve them.
409
+
410
+ The CLI validates the complete binding before fetching values through
411
+ `@hasna/secrets`. It resolves current values for each run, checks returned keys
412
+ and expiry, and injects only the declared variables into the child process.
413
+ Missing, extra, stale or mismatched bindings refuse execution; a failing vault
414
+ read never falls back to an ambient value or a local vault. Wrapping `skills run`
415
+ in `secrets exec` alone does not bind a declared variable. Runtime controls such
416
+ as `PATH`, `NODE_OPTIONS` and `SKILLS_INPUT_JSON` cannot be credential names.
417
+ Bindings require an explicit local target and a fresh API selection; they cannot
418
+ be used with cached, cloud or legacy remote execution. No S3 deployment is required.
419
+
420
+ Run receipts retain references and scope, never resolved values or captured
421
+ output. Returned child output redacts literal, JSON-escaped, base64 and URL-encoded
422
+ forms of injected values. This limits accidental disclosure; local execution
423
+ has the calling user's filesystem and network access and is not a sandbox for
424
+ hostile code. Review the exact executable and grant only the credentials its
425
+ effects require. Cloud admission and cloud credential delivery remain separate.
426
+ SDK callers use `resolveSelectedRun`, `prepareSelectedSecretBindings` and
427
+ `executeSelectedLocal(selected, { secretBindings })` through `@hasna/skills/sdk`.
428
+ The same SDK exports `readExecutionGrantPolicy`, `saveExecutionGrantPolicy` and
429
+ `resolveExecutionGrant`. The HTTP contract is GET/PUT
430
+ `/v1/execution-grants/:profile`, GET
431
+ `/v1/execution-grants/:profile/versions/:revision`, and POST
432
+ `/v1/execution-grants/:profile/resolve`. Writes use `If-None-Match: *` to create or
433
+ the quoted policy revision in `If-Match` to update. The API advertises
434
+ `executionGrants: true` and grant permissions in `/v1/capabilities` when supported.
435
+ Upgrade the API and apply its database migrations before enabling shared grants.
436
+
327
437
  ```bash
328
438
  skills capabilities --json
329
439
  skills run --target cloud --selection-profile default \