octomy::crypt::NodeSecretSeal
A secret encrypted to one node, stored as an ordinary string.
| Declared in | src/libs/libcrypt/crypt/seal/NodeSecretSeal.hpp |
| Group | crypt |
Detailed description
An API token, an image registry password, a cloud provider key: each must be stored, and none may be readable by another node or by anyone who copies the settings file. This seals a secret with key material only the local node holds, and binds the result to that node's id and to a purpose.
The format
encrypted-by-<nodeId>:<base64(nonce || ciphertext || tag)>
The prefix lets a reader tell a sealed value from a cleartext one without trying to open it. The node id is in the clear so a value sealed by another node is reported as that, by name, instead of as corruption.
The construction
- The key is HKDF-SHA256 of the node's key material, with the purpose as the info string. Two purposes never share a key.
- The cipher is XChaCha20-Poly1305 with a random 24-byte nonce. The nonce is large enough that random choice never repeats in practice.
- The node id and the purpose are the associated data. Editing the node id in a stored value, or reading a value under the wrong purpose, fails authentication rather than decrypting.
Why it exists here
Lifted from LLMCredentialHelper (fleet §FLV-5), which is now a caller. That helper sat in libllm, which links Qt Widgets, so a cloud client could not reach it. It also used AES-CBC with no authentication, so a wrong key produced either an error or, about once in 256 tries, garbage that passed the padding check. And it returned the cleartext when encryption failed, which stores the secret unencrypted and says nothing. This class fails loudly instead, and never hands back a value it did not authenticate.