mintBlue

Derivation profile

The deployment profile every party to a mintBlue deployment uses byte for byte: derivation namespaces, per-curve labels, the key-path vocabulary and the mandate credential type, with what changing each one breaks.

Deployment profile. The open SDX Protocol fixes the shapes, the grammar and the byte lengths of key derivation, and requires every deployment to choose and publish its own concrete strings. This page is mintBlue's profile. Read the specification

The SDX specification does not fix the concrete strings that go into key derivation. It fixes the shapes, the grammar and the byte lengths, and it requires every deployment to choose a derivation profile and publish it: the derivation namespace strings, the per-curve derivation labels, the key-path segment vocabulary, and the mandate credential type identifier.

This page is mintBlue's profile. Every party to a mintBlue deployment uses these strings byte for byte. They are not descriptive names and they are not adjustable settings: each one is an input to a key derivation or a value covered by a signature, so a party that spells one differently derives different keys and cannot read anything the others have written.

Why the strings look the way they do

The spellings carry mintBlue's product history. They were fixed before the specification was generalised, records exist under them, and the audit layer is append-only, so they cannot be tidied up retrospectively. Read them as identifiers, not as documentation. Where a spelling disagrees with current product vocabulary, the current vocabulary is what the prose uses and the string is what the code emits. The clearest case is the level-2 key-path segment, which is spelled machine and denotes what the product now calls the runtime.

Applying the profile

Load every value below from a single named constant per value, and validate each against the specification's grammar rules at load time rather than at first use. A malformed namespace discovered on the first write is discovered too late. Never inline one of these literals a second time: a duplicated constant is the standard way for two copies to drift apart without anyone noticing until a key fails to reproduce.

None of these values may change while records exist under them. A change is not a migration; it re-derives the tree beneath it and orphans everything already written. The only supported path that changes key material is the specification's epoch rotation, which is signed, announced on the audit layer, and preserves the ability to decrypt history under the previous epoch.

1. The parameter table

Every value mintBlue has fixed, each appearing here exactly once. This table is the profile; the sections after it explain the parts that need explaining.

ParameterDeployed value (verbatim)Wire-effectiveWhat changing it breaks
Encryption namespacemintblue machine v2 encryptYESDerived keys. Every symmetric field-encryption key on the secp256k1 tree and every per-Action recipient key identifier on the P-256 tree. All previously encrypted fields become undecryptable
Signing namespacemintblue machine v2 signYESDerived keys and published bytes. Every per-Action signing key on both curves changes, and because the JOSE kid in each envelope signature is the hexadecimal of that derived key, the published signature headers change with it. Existing envelopes fail their identity binding
Delegation namespacemintblue machine v2 delegateYESDerived keys. Determines the counterparty-symmetric delegation key that a runtime and an actor derive independently from opposite sides, and the ephemeral session keypair whose public key is pinned into a grant and anchored. A mismatch between the two sides breaks the symmetry silently: both sides succeed and get different keys
Transport-authentication namespacemintblue machine v2 overlay authYESPublished bytes. Determines the identity key a runtime presents in the transport's mutual-authentication handshake, so a change alters the identity every peer sees and has pinned
Rotation namespacemintblue machine v2 rotationReserved; nothing derives under itNothing today. See section 2
Handoff namespacemintblue machine v2 handoffYESDerived keys. Determines the counterparty-keyed output lock for a cross-domain handoff. The addressed recipient re-derives from the identical string in order to spend, so a changed string produces an output nobody can spend
secp256k1 derivation labelmintblue-v2-secp256k1YES, highest leverageDerived keys. It sits at the root of the whole secp256k1 tree. Every Action whose field keys derived under the previous label becomes undecryptable
P-256 derivation labelmintblue-v2-p256YES, highest leverageDerived keys and published identity. The P-256 tree re-derives, so the runtime's published identity key changes and every party that pinned it, whether in a DID document, a wallet or a token trust anchor, observes what looks like an unannounced rotation. Signatures already issued still verify, because verification uses the root key rather than the label, which makes this failure quieter and therefore worse
Key-path grammaraccount/<acctId>/machine/<mId>/action/<actionId>/field/<fieldName>YESDerived keys. The keyword segments are bytes inside the derivation identifier, so changing any word changes every key at that level and below. See section 3 for the level-3 and level-4 variants
Mandate credential type (vct)urn:mintblue:MachineMandate:v1YESCredential verification. It sits inside the signed credential, and therefore inside the digest anchored with the grant, so external verifiers match it byte for byte
Mandate claim namemandate.machineIdYESCredential verification. Same position: inside the signed payload and inside the anchored digest. Carries the runtime identifier

The two derivation labels deserve separate emphasis. They are hyphenated ASCII and they are not namespaces: HKDF consumes them and imposes no grammar, so they must never be rewritten into the space-form the namespaces use. They are also the highest-leverage values here, sitting at the root of both trees, where a single edited character re-derives every key the deployment has ever produced. Treat them the way you would treat a root certificate.

Changing either credential value invalidates every credential already issued, and the two travel together: a deployment's claim vocabulary belongs with its credential type identifier.

2. The rotation namespace is reserved, not live

It is registered but not exercised. A rotation Action's two signatures are produced and verified under the signing namespace with the ordinary per-Action key path, exactly like any other Action; that is what a verifier's identity binding checks. Signing a rotation envelope under the rotation namespace produces an Action that will be rejected.

The entry is kept so the string stays reserved and cannot be reused for something else, which the specification permits: a profile may reserve namespaces it does not yet derive under, and verifiers bind to the namespace actually used for signing. Either retire this one or start using it, but do not assume from its name that it is live.

3. Key-path vocabulary in full

The grammar row in section 1 shows the common level-1 to level-4 path. The remaining keywords complete the vocabulary; all of them are bytes inside the derivation identifier and therefore wire-effective for the same reason.

PositionKeywords (verbatim)Shape after the level-2 prefix
Level 3 variant, sessionssession.../session/<sessionId>
Level 3 variant, delegationdelegation, actor.../delegation/<delId>/actor/<actorPubKey>
Level 4 purposesfield, handoff, topup.../action/<actionId>/<purpose>/<id>

The angle-bracketed components are values, not literals. The two opaque identifiers in the grammar are base58check encodings of 128 bits of CSPRNG output, and they are deliberately not derived from any public key or from anything visible on the audit layer.

The level-4 purpose set is closed. A purpose outside it is rejected at the derivation boundary. Generate the accepted set from one shared constant on both the deriving and the validating side, so that a purpose added on one side and not the other fails loudly rather than producing keys the other side will not recognise.

One spelling surprises people every time: the level-2 segment is machine, and it denotes what the product now calls the runtime.

4. Values that are not part of the profile

These are fixed by the specification, not chosen by mintBlue, and they are listed so the boundary is unambiguous. Do not treat any of them as a local setting.

ValueStatus
Security level 2 in the derivation identifierSpecification; a property of the derivation standard's counterparty semantics
Derivation identifier shape <securityLevel>-<namespace>-<keyPath> and its literal hyphensSpecification
Five-level nesting, one keyword per level, / separatorSpecification
Namespace grammar: lowercase letters, digits and spaces; 5 to 280 characters; no consecutive spaces; not ending in the word protocolSpecification; a profile value must satisfy it
Key path length limit of 1033 bytesSpecification
System Action names _grantDelegation, _revokeDelegation, _rotationSpecification
Grant, revoke and rotation argument keys; envelope header field namesSpecification
HKDF-SHA-256 with empty salt and 32-byte output; AES-256-GCM; ES256 with P1363 encoding; SHA-256; the browser PBKDF2 parametersSpecification
Curve orders; the 64-byte root; the 33-byte, 32-byte and 16-byte field widthsSpecification
did:key and did:web handling and the multicodec code pointsExternal standards
Dead-letter categories and typed sub-reasonsSpecification; deliberately stable across deployments so tooling is portable

5. Local names that carry no wire weight

Rename these freely. They appear in local storage and in code, never in a derivation and never in a published byte. They are listed only so nobody assumes they are load-bearing and freezes them unnecessarily.

NameWhere it livesWhy it is free
machineId in the delegations projection rowLocal projectionThe projection is a rebuildable cache of on-chain state. No byte of it is published, signed or derived from
machineIdentityPubKey as a variable in derivation codeCodeThe derivation consumes the key's bytes, not the variable's name. The HTTP surface separately exposes a field literally named machineIdentityPubKey_p256, which is an interoperability name and belongs to the API documentation, not here
derivation_registry column names, including machine_id_hashLocal at-rest schemaNever crosses a boundary. The additional-authenticated-data construction over the selector columns is security-relevant and must be preserved, but the column names themselves are free
keyring table column namesLocal at-rest schemaLocal storage only

6. Checklist before a deployment goes live

  • Every value in the section 1 parameter table, and every keyword in section 3, is loaded from exactly one named constant.
  • Each is validated against the specification's grammar and length rules at load time.
  • The six namespaces are mutually distinct, and the two per-curve labels are mutually distinct.
  • Known-answer test vectors have been generated under this profile and are pinned in the test suite. Vectors from another profile will not reproduce, and that is correct behaviour rather than a bug.
  • This page has been shared with every party to the deployment, and each has confirmed the values they loaded match it.

On this page