pub enum SecretError {
NotFound {
path: PathBuf,
},
ClusterNotImplemented,
ClusterNotFound {
name: String,
},
Forbidden {
name: String,
},
ClusterDecrypt {
name: String,
},
ClusterUnavailable {
name: String,
},
Kek {
reason: String,
},
Io {
op: &'static str,
path: PathBuf,
source: Error,
},
}Expand description
Errors returned by SecretResolver::resolve.
Variants§
NotFound
The referenced secret file does not exist in the yubaba secret store.
ClusterNotImplemented
SecretRef::Cluster reached a resolver that has no cluster backing —
e.g. the per-machine LocalFileResolver, which cannot decrypt cluster
secrets. The fleet resolver (yubaba’s ClusterResolver) handles the
Cluster arm; this error means the wrong resolver was used.
ClusterNotFound
The referenced cluster secret is not present in the local raft replica (never written, or deleted). Fails closed — nothing is served.
Forbidden
The cluster secret exists but its SecretAccess rule does not admit
the requesting workload (R706 / W294).
The #[error(...)] text is a deliberate byte-for-byte duplicate of
SecretError::ClusterNotFound’s. Yubaba surfaces the Display form
of this error in the deploy rejection body, so a distinguishable message
would turn any workload spec into an oracle for the cluster’s secret
namespace: deploy a throwaway spec naming a guessed secret and read off
“forbidden” (it exists) versus “not found” (it doesn’t). The variants
stay separate internally — the node logs which one it was, and
secrets_forbidden_is_externally_indistinguishable pins the equality so
a future edit to either message can’t silently reopen the oracle.
ClusterDecrypt
Decryption or authentication of a cluster secret failed — a wrong
node-local KEK, a truncated/tampered record, a malformed nonce, or
(R911-F4) a record whose name or access rule is not the one it was
sealed under (secret_aad): a widened rule or a ciphertext copied to
another name. Fails closed; the message carries only the logical name,
never key or ciphertext bytes.
The cluster secret store could not answer for name — the fleet object
store is unreachable, returned a malformed record, refused the name as a
key, or this node has no store configured at all (R911-F1).
Deliberately distinct from SecretError::ClusterNotFound. A
caller that treats absence as a decision — headscale minting a fresh
noise identity when the store holds none — must not reach that decision
because a bucket blipped. The message carries only the logical name; the
node logs the underlying store error. It is not a namespace oracle: an
outage answers the same for every name.
Kek
The node-local cluster KEK could not be loaded (missing, unreadable, or
not exactly 32 bytes). Fails closed; reason is a generic diagnostic
and never contains key material.
Io
I/O error on a secret file. op is the operation that failed, as a
present participle ("reading", "writing", "creating", …).
R848: the message used to hardcode “reading” while yubaba’s writer
(deploy::secret_mount::write_secret_file) reused the variant for its
writes. Yubaba surfaces this Display form in the 422 deploy-rejection
body, so an EACCES writing the tmpfs file read as a resolver failure and
sent the operator to the cluster KEK instead of to the file being
written two lines down. Naming the operation is the whole fix.
Trait Implementations§
Source§impl Debug for SecretError
impl Debug for SecretError
Source§impl Display for SecretError
impl Display for SecretError
Source§impl Error for SecretError
impl Error for SecretError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()