palisade-config
Security-focused configuration and policy management for deception, honeypot, and high-scrutiny telemetry deployments.
Abstract
palisade-config is a deliberately narrow crate for loading, validating,
normalizing, and operationalizing sensitive configuration inputs in hostile or
high-observation environments. The design target is not generic application
configuration. It is the smaller and more demanding class of systems in which
configuration files themselves influence the attack surface: honeypots, decoy
infrastructure, deception agents, and tightly monitored detection pipelines.
The crate centers its public operational surface on two types:
ConfigApifor infrastructure mechanicsPolicyApifor detection and response policy
Those APIs embed validation into their load paths, support caller-selected
timing floors, and optionally route audit persistence through the encrypted log
path provided by palisade-errors.
Positioning
This crate is a good fit when the following properties matter:
- configuration files contain security-sensitive material
- public-path timing behavior should be normalized to a minimum floor
- runtime hot paths should avoid heap allocation after startup conversion
- diffing and hot-reload review should expose structural changes without leaking secrets
- encrypted error and audit persistence should remain explicit and opt-in
It is a poor fit when the following priorities dominate:
- generic application settings with low security sensitivity
- derive-heavy integration with broad configuration ecosystems
- ergonomic error chaining across many third-party libraries
- unrestricted dynamic runtime structures with no fixed-capacity boundaries
Public Interface
The preferred operational entry points are:
ConfigApi::new()PolicyApi::new()ConfigApi::load_runtime_file(...)/load_runtime_str(...)for hardened, fixed-capacity admission directly into runtime configPolicyApi::load_runtime_file(...)/load_runtime_str(...)for hardened, fixed-capacity admission directly into runtime policy
The underlying typed models remain public for serialization, inspection, and direct manipulation:
ConfigPolicyConfigRuntimeConfigRuntimePolicyRootTag
The intended usage model is:
- In high-risk production, load directly through the hardened runtime methods
- Otherwise, load through
ConfigApi/PolicyApi - Convert once to
RuntimeConfig/RuntimePolicy - Operate on the runtime forms in hot paths
Security Properties
1. Restricted Input Handling
On Unix platforms, configuration and policy files are opened through a restricted loader that:
- rejects symlink inputs
- requires a regular file
- enforces owner-only permissions (
0o600minimum policy) - performs permission validation before content is admitted into the crate
On non-Unix platforms, the crate now fails closed for on-disk restricted file
admission. In a hardened deployment, load_file(...) is therefore a Unix-only
path unless the crate is redesigned around a platform-native trust model.
2. Embedded Validation
ConfigApi and PolicyApi embed validation into their load methods. In normal
use, a successful load already means parse plus validation succeeded.
Validation covers:
- schema/version compatibility
- required-field presence
- absolute-path requirements where applicable
- root-tag entropy heuristics
- range and capacity checks
- pre-registration of custom policy conditions
3. Runtime No-Allocation Path
load_runtime_*() and to_runtime() convert configuration into fixed-capacity
runtime types backed by heapless. After conversion, the hot-path primitives
are designed to avoid heap allocation and to avoid cloning long-lived secret
state.
The operational diff APIs also follow this model. ConfigApi::diff(...) and
PolicyApi::diff(...) now return borrowed, fixed-capacity reports instead of
allocating owned change sets.
For the compatibility loaders returning Config and PolicyConfig, this
guarantee does not apply to the load, deserialize, or validation stages because
those paths still materialize owned models.
For the hardened runtime loaders, the crate uses bounded file admission plus fixed-capacity admitted types before moving directly into runtime structures.
4. Timing-Floor Normalization
Security-sensitive public operations use minimum execution floors to reduce coarse timing discrimination.
The crate exposes:
DEFAULT_TIMING_FLOORset_timing_floor(...)get_timing_floor()ConfigApi::with_timing_floor(...)PolicyApi::with_timing_floor(...)
These floors reduce observable timing skew. They do not constitute a complete side-channel proof.
5. Encrypted Log Persistence
When feature = "log" is enabled, this crate does not implement a separate log
encryption scheme of its own. Instead, it delegates persistence to
palisade-errors::AgentError::log(...).
That matters operationally:
- persisted records are encrypted through the same hardened path used by
palisade-errors - the cryptographic implementation is inherited from that crate
- the underlying encrypted sink uses
crypto_bastion 0.4.0throughpalisade-errors
In other words: yes, encrypted log persistence is applied, but it is applied by delegation rather than by duplicating the encryption stack in this crate.
Installation
[]
= "2.0.0"
Enable encrypted log persistence and action logging:
[]
= { = "2.0.0", = ["log"] }
Quick Start
1. Provision a Root Tag
The root_tag field is a 64-character hex-encoded 256-bit secret.
Treat the resulting value as high-sensitivity material.
2. Load Config and Policy
use ;
async
3. Hardened Production Load
use ;
async
4. Convert Once for Runtime Use
use ;
5. Configure Timing Floors
use ;
use Duration;
6. Enable Encrypted Audit Persistence
use ;
use Path;
let config_api = new
.with_log_path
.log_errors
.log_loads
.log_validations
.log_runtime_builds
.log_diffs;
let policy_api = new
.with_log_path
.log_errors
.log_loads
.log_validations
.log_runtime_builds
.log_diffs
.log_checks;
Notes:
- log paths should be absolute
- encrypted persistence is delegated to
AgentError::log(...) - enabled encrypted audit persistence fails closed across the operational API surface if the write cannot be completed
- action logging is opt-in per action category
- error logging is enabled automatically by
with_log_path(...) - the hardened runtime loaders are the recommended production path when you need bounded admission before runtime construction
Validation Modes
ValidationMode::Standard
- parse and structural validation
- no extra filesystem assertions beyond loading the file itself
- suitable for CI, test harnesses, or incomplete staging layouts
ValidationMode::Strict
- all Standard checks
- existence checks for monitored filesystem targets
- parent-directory checks for writable logging destinations
- appropriate for production deployments with known-good filesystem layouts
Architecture
Config vs Policy
| Surface | Primary Concern | Example Contents |
|---|---|---|
Config |
infrastructure mechanics | working directories, watch paths, root tag, logging path |
PolicyConfig |
detection and response logic | thresholds, suspicious processes, response rules |
Runtime Model
The crate distinguishes between admission-time and runtime-time structures:
- admission-time: flexible deserialized models
- runtime-time: fixed-capacity, no-allocation operational structures
This separation keeps the operational hot path narrow and bounded without forcing the loading path to become artificially inflexible.
Tag Derivation
root_tag (256-bit secret)
-> host_tag = SHA3-512(root_tag || hostname)
-> artifact_tag = SHA3-512(host_tag || artifact_id)
The design goal is stable per-host derivation with correlation resistance across unrelated artifacts and straightforward invalidation through root-tag rotation.
Operational Guidance
Recommended Deployment Posture
For a high-risk honeypot deployment:
- use
ValidationMode::Strict - treat config and policy files as privileged assets
- keep files owner-only on Unix
- convert to runtime forms at startup, not lazily
- enable encrypted error and audit logging explicitly
- enable action logging only for the events you genuinely need to retain
- benchmark timing-floor choices against your real event volume
Recommended Verification Workflow
For higher assurance, add:
- reproducible CI builds
- scheduled dependency and supply-chain review
- fuzzing for parse and validation boundaries
- deployment-environment benchmarking for timing floors
Smoke-test fuzzing with:
Limitations
This crate should be adopted with the following limits in mind:
- timing floors reduce coarse timing leakage only
- hardened on-disk restricted loading is Unix-only and now fails closed on non-Unix platforms
- encrypted log persistence is delegated, not independently reimplemented here
- the crate does not protect against root-level host compromise
- plaintext config files still contain the serialized
root_tag - the compatibility loaders returning
ConfigandPolicyConfigstill use owned deserialized models - the hardened runtime loaders close that boundary for production runtime admission, but they require the stricter fixed-capacity schema shape
- a strict no-trust posture still depends on operator controls, dependency review, and host hardening outside this crate
Examples
Runnable examples are available under examples/:
basicstoml_loadinghot_pathsderivationdiffingadvanced_policytimingfull
Run them with:
Related Documents
License
Apache-2.0