qhermes-kernel
Part of QHermes 26 by Copertino.
Thank you for choosing QHermes 26.
ML-DSA-65 key derivation, credential issuance, permission encoding, caveat evaluation, and wire serialization. No allocator dependency. No unsafe code. All operations over caller-supplied byte slices.
Signatures: ML-DSA-65 (FIPS 204). Key derivation: HKDF-SHA3-512.
Design
The signing key is a trait, not a type. IdentitySigner defines the signing interface. IdentityIsland is one implementation — deterministic derivation from a master seed. The trait may be implemented directly for HSM, TPM, enclave, or any hardware-backed key store. The kernel has no dependency on where the key material resides.
Derived identities are one-way. IdentityIsland::derive accepts a master seed, a deployment string, and a context string. The HKDF info parameter is deployment:context. Two islands derived from the same master under different parameters have no mathematical relationship. The master and all sibling islands remain unrecoverable from a compromised island.
All buffers are caller-owned. Every function writes into slices or fixed-size arrays supplied by the caller. No allocations are performed internally. Maximum output buffer sizes are exported as constants to permit static allocation at all call sites.
Scope subset enforcement is exact. Resource and verb fields are opaque byte strings compared for equality. The only wildcard is b"*", which matches any single field. A resource string such as b"src/**" is treated as a fixed identifier, not a glob pattern. Pattern interpretation is the responsibility of the application layer. The kernel enforces containment mechanically on the bytes supplied.
Timestamps are seconds, not milliseconds. Every Timestamp value is seconds since the Unix epoch. Supplying milliseconds produces incorrect caveat evaluation without error — the caveat will appear to expire far in the future. The kernel has no access to a system clock and performs no validation of timestamp units.
Wire format is anti-malleable. Trailing bytes following expected fields in any payload return WireInvalid. A credential count of zero is rejected. The first byte of every chain is a version tag. These properties make it structurally difficult to construct inputs that parse as valid but carry unintended semantics.
Errors are #[non_exhaustive]. New variants may be added in minor releases. Match arms must include a wildcard.
Architecture
Four layers, each calling only downward.
Crypto — key derivation from a master seed and ML-DSA-65 sign/verify.
Policy — permission TLV encoding, scope subset enforcement, caveat evaluation.
Delegation — credential issuance and chain verification against a trust anchor.
Wire — credential chain serialization and deserialization.
Usage
use ;
// Derive an identity from a master seed.
let identity = derive?;
// Build a scope.
let mut scope_buf = ;
let scope_len = perm_tlv?;
let expiry_bytes = not_after;
// Issue a credential to a child public key.
let manifest = DelegationManifest ;
let mut payload_buf = ;
let mut sig_buf = ;
let n = issue_credential?;
// Verify a delegation chain.
verify_delegation?;
Wire format
A credential chain begins with a version byte (0x01) and a 4-byte little-endian credential count, followed by the credential records.
Each record: issuer public key (PK_SIZE bytes), ML-DSA-65 signature (SIG_SIZE bytes), payload length (4 bytes, little-endian), payload bytes.
Each payload: child public key (PK_SIZE bytes), role byte (0x00 for Leaf, 0x01 for Node), depth (4 bytes, little-endian), scope length (4 bytes), scope bytes, caveat length (4 bytes), caveat bytes.
Permission encoding
Each permission: 1-byte resource length, resource bytes, 1-byte verb length, verb bytes. b"*" in either field matches any value during scope subset checks. All other values are compared for exact byte equality.
Caveat encoding
Each caveat: 1-byte tag, 8-byte little-endian Unix timestamp in seconds.
Tag 0x01 (not_before) — invalid if now < ts. Tag 0x02 (not_after) — invalid if now > ts.
Constants
| Name | Value | Description |
|---|---|---|
PK_SIZE |
1952 | ML-DSA-65 public key, bytes |
SIG_SIZE |
3309 | ML-DSA-65 signature, bytes |
SEED_SIZE |
32 | Master seed, bytes |
MAX_DEPTH |
16 | Maximum delegation chain depth |
MAX_SCOPE_PERMS |
64 | Maximum permissions per credential |
MAX_CAVEATS |
64 | Maximum caveats per credential |
PERM_TLV_MAX |
512 | Maximum encoded scope bytes |
CAVEAT_SIZE |
9 | Fixed caveat record size, bytes |
License
Copertino Source License 1.0. Change Date: 2036-01-01. Change License: Apache-2.0. See LICENSE.
Copyright © 2026 Copertino. All rights reserved.