On this page
Bearers a host holds
Bearers a host holds
Every bearer file Stado writes onto a host is recorded on that host's registry entry as targets[].bearers, a list of {"consumer", "file"} with the file's absolute path: sync records the destination file of each delivery (token_synced or token_unchanged; a --check records nothing), and mint --token-file-name records the owner file it writes on the vault owner. stado registry host show <TARGET> (or --path bearers) therefore says which of the fleet's credentials sit on a host, which matters most on a shared host, a person's own computer. A delivery whose record could not be written is reported as <target> holds the bearer of <consumer> at <file>, but the registry does not record it; run the same command again to record it, and running it again records it without rewriting the file.
stado credentials token remove <CONSUMER> --host <TARGET> --token-file <TARGET-PATH> [--json] takes a bearer file off a host once the grant it opened is gone, and takes its record out of targets[].bearers. The path takes the forms sync --token-file takes: a bare name under ~/.stado, a ~/ path, or an absolute path inside the host account's home. It reads the grant list of the vault owner the service directory places skarbiec on, then removes the file over the host channel with a fixed program, and prints <target>: removed <path>, the bearer of <consumer>, whose grant <owner> no longer records ("status": "token_removed"), or <target>: <path> is already absent ("status": "token_absent") when there is nothing left to remove.
How sync and remove refuse
token sync and token remove refuse with the causes of
stado.credentials.token (stado errors show stado.credentials.token prints
each with its fix):
| cause | when | exit |
|---|---|---|
file-unnamed |
--source-token-file or --token-file names no file |
2 |
shared-vault-unrouted |
sync --shared-vault while the directory does not place skarbiec on the source or the destination declares no skarbiec adapter |
1 |
channel-failed |
the host channel did not run the custody or the removal | 69 |
custody-refused |
the host's Stado refused the custody export, install or check | 1 |
delivery-answer-invalid |
the destination answered something other than this Stado's report | 69 |
record-refused |
the registry's entry cannot carry the bearer record, or give it up | 1 |
skarbiec-unplaced |
remove while the directory places skarbiec on no host |
1 |
grant-list-invalid |
the vault owner did not answer its grants as a list | 69 |
grant-stands |
remove while the vault owner still records a grant for the consumer |
1 |
bearer-path-invalid |
the file is outside the account's home, a relative path with directories, or has an empty, . or .. component |
2 |
bearer-of-another |
the registry records the file as another consumer's | 1 |
configuration-unreadable |
the host answered its configuration read with something that is not JSON | 69 |
configuration-reads-it |
a *token_file of the host's own configuration names the file |
1 |
removal-refused |
on the host, the file is a link, not a regular file this account owns, outside the home, or still there | 1 |
A consumer outside the vault's characters is stado.credentials.names.word-invalid
(exit 2), the same cause every credential command gives a vault word out of
form. tests/credentials/token.rs provokes it and file-unnamed through the
real binary.
A removal whose registry record could not be taken away is reported as <path> is off <target>, but the registry still records it; run the same command again to take the record away.
On each host, the half sync runs there, stado credentials token custody OPERATION VAULT CONSUMER FILE, refuses with the causes of
stado.credentials.token.custody; the source's refusal reaches the operator
as custody-refused, quoting the host's own cause line:
| cause | when | exit |
|---|---|---|
path-invalid |
FILE is a relative path with directories, or ends in no name | 2 |
outside-home |
FILE's directory resolves outside the account's home | 1 |
file-exposed |
the bearer file is a link, another account's, or readable by others | 1 |
token-malformed |
it holds nothing, whitespace inside the token, or bytes that are not UTF-8 | 1 |
source-absent |
export of a file that does not exist |
1 |
vault-not-json |
the declared vault is not JSON | 69 |
vault-ownerless |
it names no owner | 1 |
grant-absent |
it records no grant for the consumer | 1 |
grant-expired |
the grant has expired or records no expiry | 1 |
grant-shapeless |
the grant records no capability list | 69 |
token-mismatch |
the bearer does not hash to the grant; its SHA-256 is the observation | 1 |
input-invalid |
install or check with standard input that is not an export |
1 |
grant-differs |
the destination's vault differs from the source's in owner or grant | 1 |
destination-stale |
check of a destination that is missing or holds another bearer |
1 |
grant-moved |
the destination grant changed during or after the delivery | 69 |
delivered-vanished |
the delivered file was gone when it was read back | 69 |
tests/credentials/custody/ provokes thirteen of them on a vault document
and bearer files of its own.
How mint --token-item registers on the vault owner
stado credentials token mint --token-item <ITEM> --token-field <FIELD>
runs stado credentials token register SKARBIEC ITEM FIELD -- grant issue …
on the vault owner with that host's installed Stado. It reads ITEM#FIELD with
skarbiec get, hands the value to skarbiec grant issue through an
owner-only file it removes again, and, when STADO_TOKEN_DESTINATION names a
path, keeps the same bearer there. Everything that would refuse that file (a
link, another bearer already in it) is checked before the grant is issued, so
a refusal never leaves a grant bound to a bearer no file holds. Its refusals
are the causes of stado.credentials.token.register
(stado errors show stado.credentials.token.register):
| cause | when | exit |
|---|---|---|
issue-only |
the arguments after -- are not grant issue … |
2 |
destination-unreadable |
STADO_TOKEN_DESTINATION is not UTF-8 |
1 |
destination-link |
STADO_TOKEN_DESTINATION is a symbolic link |
1 |
skarbiec-unstarted |
SKARBIEC names nothing, or nothing that can be started | 1 |
skarbiec-refused |
Skarbiec ran and refused get or grant issue; its words are the observation |
1 |
answer-not-json |
the program succeeded without printing JSON: it is not a Skarbiec this Stado reads | 69 |
field-not-bearer |
the field is absent, empty, padded with whitespace or not text (its value is never shown) | 1 |
destination-holds-another |
the file already holds another bearer; nothing is registered | 1 |
issue-unreported |
grant issue exited 0 without ok: true |
69 |
copy-left |
the bearer is kept and registered, but its pending copy could not be removed | 1 |
An item or field outside the vault's characters is
stado.credentials.names.word-invalid (exit 2), refused before Skarbiec is
asked; a file the system refuses is a cause of stado.files.
tests/credentials/register.rs provokes issue-only, word-invalid,
destination-unreadable, destination-link, skarbiec-unstarted,
skarbiec-refused and answer-not-json through the real binary.
How token mint and grant add refuse
stado credentials token mint judges its invocation before the vault owner
is asked, with the causes of stado.credentials.token.mint:
| cause | when | exit |
|---|---|---|
consumer-retired |
the consumer is a retired agent identity (stado-local-agent, stado-azure-agent, stado-control-plane) |
2 |
raw-with-json |
--raw-token with --json |
2 |
capabilities-invalid |
--capabilities holds a character outside letters, digits and ., _, -, /, ,, :, # |
2 |
ttl-zero |
--ttl-seconds 0 |
2 |
bearer-unreturned |
Skarbiec's grant issue answered without the bearer it minted; the observation lists its fields, never a value |
69 |
The other flag pairs (--raw-token with --token-item or
--token-file-name, --store-item with any of the three) are refused by the
parser. stado credentials grant add judges its consumer, field and bearer
file before it asks for the vault's items, with the causes of
stado.credentials.grant.add: token-file-blank (exit 2) and
ensure-refused (Skarbiec's own words, exit 1); a role nothing plays is
stado.credentials.items.role-unplayed. A command that settles its own reads
on the vault owner (fleet key generate, dns list) refuses with the same
causes. tests/credentials/mint.rs and tests/credentials/grant_add.rs
provoke the four usage causes of mint and token-file-blank through the
real binary.
How items are stored and summarized
Every command that stores an item in the owner vault (item put, fleet key rotate, credentials signing, the publisher declaration) or finds the item
that plays a role meets the causes of stado.credentials.items
(stado errors show stado.credentials.items). The payload is judged before
any host is asked:
| cause | when | exit |
|---|---|---|
payload-size |
the payload is empty or longer than 65535 bytes | 2 |
payload-not-json |
the payload is not one JSON document | 2 |
payload-kind-absent |
the payload names no string kind |
2 |
payload-kind-mismatch |
its kind is not the --type named |
2 |
role-shared |
two or more items carry stado:role:<ROLE>; the refusal lists them |
1 |
role-unplayed |
no live item carries stado:role:<ROLE> (grant add) |
1 |
vault-absent |
no regular file is at the vault the host declares | 1 |
vault-damaged |
the vault file is not JSON | 69 |
write-verb-unknown |
the host's Skarbiec lists neither set nor set-json |
69 |
write-refused |
Skarbiec refused the write; its words are the observation | 1 |
write-unanswered |
Skarbiec did not say whether it created the item | 69 |
write-invisible |
the item was reported created but the vault does not show it active at a new revision | 69 |
item put adds stado.credentials.item.put.payload-unreadable (exit 2) for
standard input that is not UTF-8. stado credentials item summarize, the
host half of item show, refuses with stado.credentials.item.summarize:
input-unreadable (not UTF-8), not-json, fields-absent and
context-absent (exit 1, the observation lists the document's keys, never a
value). tests/credentials/items.rs provokes the four payload causes,
payload-unreadable and all four of summarize through the real binary.
How grant rebind refuses
stado credentials grant rebind --host <OWNER> --token-file <PATH> reads
the whole stado grant before it verifies anything: every capability must
name its action and item, and the grant its audience and a whole-number
expiry, or it is refused as stado.credentials.grants.grant-malformed with
the row the vault answered. Its own refusals are the causes of
stado.credentials.grant.rebind
(stado errors show stado.credentials.grant.rebind):
| cause | when | exit |
|---|---|---|
file-relative |
--token-file is not an absolute path on the vault host |
2 |
capabilities-none |
the grant lists no capability, so no bearer can be verified against it | 1 |
verdict-invalid |
grant verify answered without a boolean allowed |
69 |
already-bound |
the file already opens the grant; nothing is changed | 1 |
grant-expired |
the grant has expired; rebinding never renews it | 1 |
rebind-unconfirmed |
the grant was re-issued but the file still does not open it | 69 |
A vault owner with no stado grant is stado.credentials.grants.grant-absent.
tests/credentials/rebind.rs provokes file-relative through the real binary.
How Skarbiec on the vault owner and scopes sync refuse
Every credential command runs Skarbiec on the vault owner over the host
channel, with that host's own Skarbiec, vault and keyring; what it answers
is a cause of stado.credentials.remote:
| cause | when | exit |
|---|---|---|
refused |
Skarbiec, or the owner's Stado for mint --token-item, refused the command; the observation is its whole answer, and the refusal names a --until-revoked request a Skarbiec may predate and where a bearer stays for the next run |
1 |
answer-not-json |
the command succeeded without printing JSON | 69 |
bearer-file-unprepared |
mint --token-file-name: the owner will not prepare the file (a link, an empty or irregular file, or one created by a concurrent run) |
1 |
stado credentials scopes sync --host <TARGET> <SOURCE> refuses with
stado.credentials.scopes: catalog-not-regular (a link, a directory or a
device, exit 2), catalog-name-hidden (a name starting with ., exit 2) and
catalog-name-missing (a path ending in no name, exit 2) before any host is
asked; registering the catalog an installed release carries refuses with
catalog-not-shipped (exit 1) and catalog-unstaged (exit 69). Registering
on the host refuses, naming where the catalog landed and that nothing was
registered, with scope-file-missing (the Skarbiec program, the vault, the
workload key or the catalog is not there), openssl-missing,
scratch-unmade, key-ungenerated, key-underived, lifetime-unread
(the catalog copy or the vault's grant list could not be read, so the
current lifetime could not be kept) and
registration-refused; key-unplaced says the catalog is registered with a
new workload key that could not take its place, and catalog-vanished that
the catalog was gone when its roles were settled. Keeping a declared item as
the role's one holder refuses with
stado.credentials.items.named-role-elsewhere and role-tag-refused.
--ttl-seconds 0, here and on token mint, is a usage error at parse (exit
2, naming the value and the range it is not in): a zero lifetime would hand
Skarbiec a grant that ends as it is made, so the lifetime is at least one second.
tests/credentials/scopes.rs provokes the first two through the real binary,
and the refusal of --ttl-seconds stated together with --until-revoked.
How reading a host's vault and syncing it refuse
| functionality | cause | when | exit |
|---|---|---|---|
stado.credentials.item.show |
item-absent |
the vault the host declares holds no item of that id | 1 |
summarizer-missing |
the host's Stado has no credentials item summarize |
1 | |
summary-failed |
Skarbiec or the host's Stado refused the summary; every line it wrote is the observation | 1 | |
summary-unread |
the summary is not the document this Stado reads | 69 | |
field-absent |
--field names no field of the item; the observation lists the fields it holds |
1 | |
stado.credentials.grant.show |
(the grant causes) | a grant list, grant or capability out of shape, or no grant for the consumer | 1 / 69 |
stado.credentials.vault.list |
configuration-unanswered |
a host's Stado did not answer stado config show |
69 |
configuration-not-json |
it answered no JSON | 69 | |
authority-undeclared |
the host declares neither secrets.skarbiec.vault_file nor the owner's Skarbiec URL |
1 | |
stado.credentials.vault.sync |
mirror-row-incomplete |
a listed item has no id, revision or update time | 69 |
push-not-owner |
--push from a host the service directory does not place skarbiec on |
1 | |
mirror-refused |
Skarbiec refused the pull or push; a pull names the live items the mirror lacks | 1 |
An encrypted vault the host declares but does not hold, or one that is not
JSON, is stado.credentials.items.vault-absent or vault-damaged.
How changing an item in place refuses
item retag, item rename and item upgrade first meet what a change needs
of the host's Skarbiec, stado.credentials.item.change:
skarbiec-program-absent (no executable where its release puts it, exit 1),
build-unreadable (strings could not read it, exit 69),
build-answer-unknown (the probe answered neither, exit 69) and
build-predates (its skarbiec help lists no such command, or, for a build that lists none, it lacks the operation's old usage line, exit 1). Then:
| functionality | cause | when | exit |
|---|---|---|---|
stado.credentials.item.retag |
retag-refused |
Skarbiec refused the new tag list; the tags are as they were | 1 |
stado.credentials.item.rename |
source-absent |
the vault holds no item of the old id | 1 |
target-held |
the vault already holds an item of the new id; a rename never replaces one | 1 | |
rename-refused |
Skarbiec refused the rename | 1 | |
rename-unconfirmed |
after Skarbiec answered, the vault does not hold the new id in place of the old | 69 | |
stado.credentials.item.upgrade |
upgrade-refused |
Skarbiec refused duplicates or the pass; an unknown command is a build that predates it |
1 |
upgrade-answer-invalid |
it succeeded without printing JSON | 69 |
item delete, item restore and item reclaim start
stado.credentials.item.lifecycle: each is one Skarbiec command on the vault
owner, refused with the item's vault word and Skarbiec's own answer
(stado.credentials.remote.refused).
How signing profiles and host document render refuse
stado credentials signing profile ensure --provider apple refuses with the
causes of stado.credentials.signing.profile:
| cause | when | exit |
|---|---|---|
api-key-field-absent |
the --credentials item holds no key_id, issuer_id or private_key |
1 |
api-key-invalid |
private_key is not the .p8 file's PEM text, or not a P-256 PKCS#8 key |
1 |
provider-declaration-invalid |
the built-in provider/app-store-connect.json is not JSON or names no whole-number bearer lifetime |
1 |
bearer-unsigned |
the system's signer refused the key | 69 |
provider-unreachable |
a request to App Store Connect got no whole answer | 69 |
provider-refused |
Apple answered an error status; its status and body are the observation | 1 |
provider-answer-invalid |
Apple answered something that is not JSON, or a next page off its API | 69 |
bundle-unregistered |
the team never registered the bundle id | 1 |
certificate-absent |
the team holds no certificate of --certificate-type |
1 |
profile-empty |
Apple created the profile and answered without its content | 69 |
stado host document render <TARGET> <SOURCE> delivers a checked-in renderer,
runs it against the host's live vault and prints only the public document it
builds; it refuses with stado.host.document.render: renderer-not-regular
(the source is a link, a directory or a device, exit 2, before delivery),
environment-unread, environment-no-vault, node-missing,
render-file-missing, render-failed, render-not-json and
render-private (the document carries a private key, which never leaves the
host; nothing is printed). Every refusal on the host removes the delivered
renderer. tests/credentials/render.rs provokes renderer-not-regular
through the real binary.
How the backup audit's host half refuses
stado credentials backup audit runs stado host local audit on the host,
which prints the marker lines the report is folded from and refuses with a
cause of stado.host.local:
| cause | when | exit |
|---|---|---|
list-invalid |
an --objects-hex or --inventory-namespaces-hex entry is not hex-encoded UTF-8 |
2 |
root-unresolved |
the backup or the primary root is absent, or behind a link that does not resolve; nothing is read | 1 |
roots-overlap |
the two roots are one tree or one lies inside the other, so every object would be its own twin; nothing is read | 1 |
incomplete |
part of what the pass walked could not be read; each STADO_BACKUP_AUDIT_UNAVAILABLE line names a path and its error, no completion marker is printed, and nothing unproven is deleted |
69 |
tests/host_local/audit.rs provokes all four through the real binary.
Source: this website