CLI command
skarbiec set-json
Write one canonical item payload supplied on stdin instead of exposing field values in argv.
Invocation#
printf '%s' '<canonical-json-payload>' | skarbiec set-json <id> [--type <canonical-kind>] [--recipients <uid,...>] [--tags <tag,...>] [--if-absent | --if-unchanged]Purpose#
Write one canonical item payload supplied on stdin instead of exposing field values in argv.
Required inputs and options#
- Requires an item id and one JSON payload on stdin with schema, kind, and fields. --type may select the validation kind; absent --recipients and --tags preserve existing metadata. --if-absent writes only when no live item has that id. On a client with secrets.skarbiec.url and no local vault declaration, the same operation runs on that owner; its operator API and this CLI must both carry the owner-item command contract.
Output and state effects#
- Validates, encrypts, and stores a new revision, then prints ok, id, kind and created: true. With --if-absent and an existing item, nothing is written and it prints ok, id and created: false. The absence check and the write share one opened vault, and the save refuses when another writer changed the vault meanwhile, so of two concurrent creators only one writes.
Refusals#
- Refuses non-JSON or non-canonical payloads, invalid schema fields for the kind, the reserved managed:weles tag, a tag the write would introduce under no registered namespace, and direct writes to lifecycle-controlled or externally managed items. Refuses an exact duplicate: a second item holding a payload another active item already holds, naming that item. Refuses a context.identity that names no active identity item in this vault. Without --recipients or --tags, the item's stored list is kept whole: a stored list that is not a list of text is refused as vault item <id> carries <field> … instead of being written back without what could not be read.
Real fleet qualification#
For a read-modify-write, use --if-unchanged and supply {"expected":<complete previously read JSON>,"payload":<complete replacement JSON>} on stdin. Skarbiec compares the existing decrypted payload structurally with expected inside the same opened vault used for the write. A changed payload is refused as item_payload_changed without writing; a writer racing after that comparison is refused by the vault generation check. Missing items, malformed envelopes and combining --if-absent with --if-unchanged are refused. This protects payload identity, not a historical revision that changed and later returned to the same payload. The operator credential set-json API accepts the same if-unchanged flag and envelope; no secrets belong in argv. Run node tests/vault/conditional_payload.mjs with SKARBIEC naming the candidate binary, SKARBIEC_TEST_SOURCE_REVISION its committed revision, and SKARBIEC_TEST_OPERATOR_ENDPOINT the real owner operator endpoint. The journey creates a unique isolated login in the real vault, checks matching and stale CLI writes, invalid option/envelope refusals and operator API success/conflict, then purges only its own fixture. Reports under target/real-tests/conditional-payload retain commands, statuses, responses and candidate identity. Use a dedicated qualification vault, not operator credentials.