On this page

Provision a machine's vault

A fleet machine needs a secret for every role its configuration declares: the roles of agent.skarbiec.roles and the role of each agent.skarbiec.secret_fields entry (role#field). One item in the fleet vault plays each role, the one tagged stado:role:<role>. Where the machine reads those roles depends on what it declares:

The machine declares It reads its roles from Who supplies a missing role
secrets.skarbiec.vault_file its own vault stado credentials vault provision, below
no vault file, and a Skarbiec address (agent.skarbiec.url, else secrets.skarbiec.url) the fleet vault, through that address; it holds no vault by design stado credentials item put on the vault owner, which stores the item there
neither nothing declare its vault first (stado host config set <machine> secrets.skarbiec.vault_file <path>, then skarbiec init <uid> there)

A machine whose roles have no item declines every job that reads them, and when the role is one its own Stado reads to publish, it publishes nothing at all.

Seeing what is missing

stado host gates <machine> judges the declared roles against the vault they are read from. When one has no item it lists the blocker vault_roles_missing and prints a vault: line naming the roles, the cause and the repair. --json carries the same under vault_roles: declared, judged_against (which vault was read: the machine's own vault, the fleet vault it reads through its address, or no Skarbiec when it declares none), missing, cause, repair, and repairs, one per missing role. A vault that cannot be read at all is reported as the observation vault_roles and never as a verdict.

stado credentials vault roles --host <machine> [--apply] makes the repairs that change no secret: a declaration naming an item that plays other roles is changed to the role that item plays, and an item a role names that plays no role is tagged with it. A role only a new secret supplies is refused naming its put (stado.credentials.vault.roles.roles-unsettled).

Giving a machine's own vault its items

stado credentials vault provision --host <machine> [--owner <vault-owner-host>] [--apply] [--json]

The fleet vault is read on the host the service directory places Skarbiec on: the vault owner stado credentials vault move makes. --owner is needed only when the directory places Skarbiec on no host. The command is refused, before anything is read from a vault:

  • when --owner names another host than the directory does (stado.credentials.vault.provision.owner-elsewhere, exit 2): drop --owner, or make that host the vault owner first with stado credentials vault move --to <host> --owner-uid <uid>;
  • when --owner names the machine itself (stado.credentials.vault.provision.owner-is-receiver, exit 2): the vault owner already holds every item;
  • when the directory places Skarbiec on no host and no --owner names one (stado.credentials.vault.provision.owner-unknown): stado service directory show prints the directory;
  • when the machine's Stado configuration is not JSON (stado.credentials.vault.provision.receiver-config).

Without --apply nothing changes. Each declared role is reported under roles:

State Meaning
held The machine holds the owner's item for the role. Whether it holds the owner's current content is what --apply answers.
absent The machine holds no item for the role.
refused The role cannot be provisioned as things stand; why says what to do.

A role is refused when the owner holds no live item carrying its tag (why ends with the stado credentials item put that stores it on the owner), when two items on either side carry the tag, when the machine holds another item in the role (why names the stado credentials item retag or delete that clears it), and when the owner's item carries managed:weles, the tag Skarbiec reserves for items a Weles workflow manages, which Skarbiec's import refuses on every receiving vault (why offers reading the role through the vault owner's Skarbiec instead). The command exits non-zero while any role is refused (stado.credentials.vault.provision.roles-refused).

With --apply it first reads skarbiec version on the vault owner and on the machine. Both must answer sealed_stream: true, the declaration of a Skarbiec that carries export - and import -: an older export - writes a file named - into its working directory and an older import - cannot read standard input. An end that does not declare it is refused before anything is registered or sealed (stado.credentials.host-vault.vault-unsealed); stado release status shows the release each host runs.

Then it makes the machine's vault owner a recipient of the fleet vault (the key skarbiec owner key show gives on the machine, registered on the owner with skarbiec recipient add; a uid the owner already holds with another key is refused naming skarbiec recipient rekey, stado.credentials.host-vault.recipient-rekeyed) and carries every held and absent role through Skarbiec's sealed stream over the host channel:

# on the vault owner                                                              # on the machine
skarbiec export - --canonical --encrypt-to <machine owner> --tag stado:role:<role> | skarbiec import - --format canonical --conflict replace

The package is sealed to the machine's own key before it leaves the owner and travels on standard input, so no value is ever in argv, in a file, or in plaintext on the way. Each carried role is then reported from the machine's import of the owner's item:

State Meaning
current The import answered unchanged: the machine already held the owner's content, and nothing was written.
provisioned The import answered imported or updated: the role was missing, or the machine held content from before a rotation.

Currency is Skarbiec's own comparison of the item's content, never the two vaults' write times: Skarbiec stamps updated_at on every write of an item, a share or a set of the same value included, so a time comparison would call a machine out of date that holds exactly the owner's value. delivered carries each import report. The machine's vault is then read again, and the run fails unless it holds the owner's item for every carried role (stado.credentials.vault.provision.roles-unimported).

A machine that declares no vault of its own is refused rather than provisioned. One reading Skarbiec through an address holds no vault by design and is never told to create one (stado.credentials.vault.provision.receiver-client): the refusal says it declares no secrets.skarbiec.vault_file and ends with a stado credentials item put on the vault owner for each role it declares, to be run for the roles that vault holds no item for (a second item in one role is refused wherever it is read). What else it says depends on how the vault owner was told:

The vault owner is The refusal says
the host the service directory places Skarbiec on its roles are answered by the fleet vault there, and stado host gates <machine> names each role that vault holds no item for, with the put of the first one as its repair
named only by --owner nothing checked that the machine's address reads the vault on that host, and stado host gates <machine> judges its roles only once the directory places Skarbiec on the vault owner (stado service directory show prints the directory)

One declaring neither is told to declare secrets.skarbiec.vault_file and create the vault with skarbiec init (stado.credentials.vault.provision.receiver-unread).

Run again, the same command carries every rotation, so a Stado schedule pinned to the vault owner keeps the machine current:

stado schedule create --pinned-host <vault-owner-host> --cron '<when>' 'stado credentials vault provision --host <machine> --apply'

Stado Desktop's credential operations offer the same command as Give the selected host's vault the items its declared roles need, with the optional owner and --apply.

Source: this website