Skip to content
Security Design

Security Design

This document defines the security design principles, architectural guardrails, and cryptographic standards for Keystone Core. These principles are inspired by NIST 800-53 and industry best practices, providing a foundation for security-conscious development.

Core Design Principles

1. Least Privilege

Principle: Every component, process, and user should operate with the minimum privileges necessary to perform its function.

Implementation Guidelines:

  • Agents run as non-root users by default; root access requires explicit configuration
  • API endpoints enforce role-based access control (RBAC) with deny-by-default
  • Module capabilities are explicitly declared and enforced; no implicit permissions
  • Database connections use role-specific credentials (read-only, read-write, admin)
  • NATS subjects use fine-grained publish/subscribe permissions per component

Code Review Checklist:

  • Does this component request only necessary permissions?
  • Are elevated privileges scoped to the minimum required duration?
  • Is there a clear justification for any root/admin access?

2. Defense in Depth

Principle: Security controls should be layered so that compromise of one layer does not immediately compromise the entire system.

Implementation Guidelines:

  • Multiple authentication factors: network (mTLS), identity (SPIFFE/JWT), authorization (OPA/CEL)
  • Input validation at every trust boundary, not just the perimeter
  • Secrets are encrypted at rest AND in transit, with separate key hierarchies
  • Audit logging is independent of application logging with separate retention
  • Network segmentation between control plane, agents, and external services

Code Review Checklist:

  • Are there multiple independent controls protecting sensitive operations?
  • Does failure of one control still leave other protections in place?
  • Is data validated at each trust boundary crossing?

3. Fail Secure

Principle: When a component fails or encounters an error, it should fail to a secure state that denies access rather than granting it.

Implementation Guidelines:

  • Authentication failures result in denial, never default access
  • Policy evaluation errors deny the action (fail closed) — see the audit-mode caveat in Current Security Posture : through v1.0, successful policy evaluations that produce a deny verdict still let the operation proceed (audit-mode); only evaluator errors fail closed
  • Missing or invalid certificates reject the connection
  • Database connection failures prevent operations rather than using cached/stale data
  • Rate limit exhaustion returns 429/503, not success

Code Review Checklist:

  • What happens if this operation times out? Is access denied?
  • If the policy engine is unavailable, are requests denied or queued?
  • Do error handlers maintain security invariants?

4. Explicit Over Implicit

Principle: Security-relevant configuration should be explicit. Avoid hidden defaults that might create security gaps.

Implementation Guidelines:

  • TLS is required by default; insecure mode requires KSCORE_ALLOW_INSECURE_TLS=1
  • CORS origins must be explicitly configured; no wildcard (*) in production
  • Agent registration requires explicit attestation or join token
  • Module trust requires explicit policy configuration
  • Webhook secrets must be explicitly configured per source

Code Review Checklist:

  • Are all security-relevant settings explicitly configured?
  • Is there documentation for every security default?
  • Would a user be surprised by the default behavior?

5. Auditability

Principle: All security-relevant actions must be logged with sufficient detail for forensic analysis and compliance.

Implementation Guidelines:

  • Every API request logs: user, action, resource, result, timestamp, correlation ID
  • Command executions log: initiator, target, command hash, success/failure
  • State changes log: before/after values (with sensitive data redacted)
  • Authentication events log: method, result, source IP, user agent
  • Audit logs are append-only with integrity protection

Code Review Checklist:

  • Would this action be visible in audit logs?
  • Is there enough context to understand what happened?
  • Are sensitive values redacted but action still traceable?

6. Cryptographic Agility

Principle: Cryptographic algorithms should be configurable to allow migration when algorithms are deprecated or compromised.

Implementation Guidelines:

  • TLS cipher suites are configurable (with secure defaults)
  • Hash algorithms for integrity checks are versioned in data format
  • Key derivation functions are abstracted behind interfaces
  • Module signatures support multiple algorithms (RSA, ECDSA, Ed25519)
  • Deprecated algorithms (MD5, SHA1, DES, 3DES) emit warnings when used

Code Review Checklist:

  • Is the cryptographic algorithm configurable or hardcoded?
  • Is there a migration path if this algorithm is deprecated?
  • Are deprecated algorithms logged and warned about?

7. Reproducible Builds

Principle: Builds should be deterministic and verifiable to detect supply chain attacks.

Implementation Guidelines:

  • Go modules use checksummed dependencies (go.sum)
  • Module signatures are verified against SumDB transparency log
  • Docker images use content-addressable digests, not floating tags
  • Build metadata includes Git commit, builder identity, timestamp
  • SBOM (Software Bill of Materials) generated for releases

Code Review Checklist:

  • Are all dependencies pinned to specific versions?
  • Can this build be reproduced from source?
  • Is the build provenance verifiable?

8. Trust Boundary Enforcement

Principle: Data crossing trust boundaries must be validated, authenticated, and authorized.

Implementation Guidelines:

  • External API inputs are validated against schemas before processing
  • Agent commands are authorized by policy engine before execution
  • File paths are validated to prevent directory traversal
  • User-supplied content is never executed or interpreted directly
  • Cross-boundary data carries integrity proofs (signatures, MACs)

Code Review Checklist:

  • What trust boundaries does this data cross?
  • Is the data validated at each boundary?
  • Can an attacker influence data after validation?

Current Security Posture (v0.x → v1.0)

The principles above describe Keystone Core’s target security model. This section documents which pieces are fully enforced today vs. which graduate at later milestones. A public security reviewer auditing v0.x should read this section first.

Policy engine — audit-mode only

Through v1.0, the policy engine evaluates and audits but never blocks. A policy that produces a deny verdict generates an audit record; the operation proceeds. Enforcement (deny-on-violation) graduates in a v1.x release; the migration story is documented in POLICY-AUDIT.md under “Enabling enforcement”.

What this means for a security review:

  • Authorization decisions that route through the policy engine are observable + auditable but not gating. The CLI and gRPC surfaces carry the audit shape; operators who need hard blocks should run a fronting reverse-proxy with its own ACL until v1.x ships enforcement.
  • Authentication is not in audit-mode — failed auth genuinely fails closed at the auth-middleware layer, before the policy engine sees the request.
  • The Fail-Secure principle (§3) applies to policy-evaluation errors (evaluator crash, missing policy, OPA compile failure) — those still fail closed in v0.x.

Production-knob warnings (dev-mode boundaries)

Three configuration knobs are accepted but emit a startup WARN line because they’re safe for development but unsuitable for production deployments:

KnobWhereWarning
Static security.hmacsecretinternal/config/security.goProduction rotates HMAC secrets; static values appear in goreleaser snapshots / config-in-git workflows.
nats.bootstrap.enabled with literal PSKsinternal/config/nats.goProduction PSKs are single-use, short-lived, issued by kscore-identity; persistent PSKs in config indicate manual operator bootstrap that bypasses the identity provider.
secrets.backends[].file.master_key: inline:internal/config/secrets.goInline master keys end up in operator config-management systems; production wraps them via env: or a KMS / Vault reference.

The warning text + rationale + the operator-side fix are in HARDENING-BASELINE.md “Production-warn paths”.

Release model — single-signer through v1.1

v0.xv1.0v1.1 release artifacts are signed by a single signer (the Release Manager, who also acts as Signer + Witness). Multi-party signing with ≥ 3 independent signers + threshold-2 quorum is the target posture and graduates at v1.2. The full process — single-signer ceremony, dual-machine reproducibility check, signing-key handling — is in RELEASE-PLAYBOOK.md “Release lines at a glance” and the per-phase **v1.0 simplification** callouts. The graduation checklist (what must land before multi-party is feasible) is in the same doc’s “v1.2 graduation checklist” section.

What this means for a security review:

  • A compromised Release Manager is the dominant supply-chain threat for v0.x – v1.1 releases. Mitigations (offline workstation, hardware-token signing key, post-release verification re-run on a third machine) are documented in the playbook.
  • The signing key is rotatable; releases under it carry the same verification surface (signed checksums.txt + signed release record) as the eventual multi-party form will.

Runtime hardening

Goroutine, connection, and file-descriptor lifecycle hygiene is audited and gated by tests:

  • Goroutine leaks — every //go:build integration package wraps TestMain with goleakhelper.VerifyTestMain (epic 19 task 6); make goleak-policy (CI lint job) enforces this.
  • Connection lifecycle — NATS, etcd, Postgres, gRPC, HTTP, and SQLite stores each register Stop() / Close() with documented ordering. Audit table in HARDENING-BASELINE.md “Connection lifecycle”.
  • No fd-leak soak ships in v0.x (a long-running agent + lsof delta gate is tracked in the v1.x ROADMAP entry “Soak-test infrastructure for fd / connection / goroutine leaks”).
  • Race detector runs on every test invocation (make race-policy enforces — see TEST-POLICY.md ).

Pre-launch placeholder addresses

Several documents reference *@keystone-core.io mailto addresses (security@, releases@, comms@, etc.). The keystone-core.io domain is not yet registered; these are aspirational placeholders that become real channels at launch (PUBLIC-LAUNCH-CHECKLIST.md Phase B6 + F-phase). A security reviewer attempting disclosure during v0.x pre-launch should reach the maintainer via the contact shown in OWNERSHIP.md / SECURITY.md .


Cryptographic Standards

Approved Algorithms

PurposeRecommendedAcceptableDeprecated
Symmetric EncryptionAES-256-GCMAES-128-GCM, ChaCha20-Poly1305DES, 3DES, AES-ECB
Asymmetric EncryptionRSA-4096, X25519RSA-2048, P-256RSA-1024
Digital SignaturesEd25519, ECDSA P-384RSA-PSS (2048+), ECDSA P-256RSA PKCS#1 v1.5, DSA
Hash FunctionsSHA-256, SHA-384, SHA-512SHA-3, BLAKE2bMD5, SHA-1
Key DerivationArgon2id, scryptPBKDF2-SHA256 (100k+ iterations)PBKDF2-SHA1, bcrypt (low cost)
Message AuthenticationHMAC-SHA256, Poly1305HMAC-SHA384/512HMAC-MD5, HMAC-SHA1

TLS Configuration

Minimum Version: TLS 1.2 (TLS 1.3 preferred)

Recommended Cipher Suites (in priority order):

TLS_AES_256_GCM_SHA384 (TLS 1.3)
TLS_CHACHA20_POLY1305_SHA256 (TLS 1.3)
TLS_AES_128_GCM_SHA256 (TLS 1.3)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (TLS 1.2)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (TLS 1.2)
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (TLS 1.2)
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (TLS 1.2)

Disabled Cipher Suites:

  • All CBC mode ciphers
  • All RC4 ciphers
  • All export-grade ciphers
  • All NULL ciphers
  • All anonymous ciphers

Certificate Requirements:

  • Minimum RSA key size: 2048 bits (4096 recommended)
  • Minimum ECDSA key size: P-256 (P-384 recommended)
  • Maximum certificate validity: 398 days (production), 825 days (development CA)
  • Subject Alternative Name (SAN) required; CN deprecated for hostname matching

Key Sizes

Key TypeMinimumRecommendedNotes
RSA (encryption)2048 bits4096 bitsFor long-term CA keys
RSA (signing)2048 bits3072 bitsFor short-lived certificates
ECDSAP-256P-384For certificates
Ed25519256 bits256 bitsFixed size
AES128 bits256 bitsFor data encryption
HMAC256 bits256 bitsFor message authentication

Random Number Generation

  • Use crypto/rand for all cryptographic operations
  • Never use math/rand for security-sensitive purposes
  • Seed generation must use OS entropy sources

Audit Event Taxonomy

Event Categories

CategoryPrefixDescription
Authenticationauth.*Login, logout, token operations
Authorizationauthz.*Permission checks, policy evaluations
Agentagent.*Registration, heartbeat, status changes
Commandcmd.*Remote command execution
Statestate.*Configuration state operations
Policypolicy.*Policy CRUD and enforcement
Systemsystem.*System-level events (startup, shutdown)
Adminadmin.*Administrative operations

Required Fields

Every audit event MUST include:

FieldTypeDescription
timestampRFC 3339Event occurrence time (UTC)
event_typestringCategory-prefixed event type
correlation_idUUIDRequest correlation identifier
actorobjectWho performed the action
actor.typestringuser, agent, system, service
actor.idstringUnique identifier
resourceobjectWhat was affected
resource.typestringResource type (agent, policy, state)
resource.idstringResource identifier
actionstringAction performed (create, read, update, delete, execute)
outcomestringsuccess, failure, error

Optional Fields

FieldTypeDescription
source_ipstringClient IP address
user_agentstringClient user agent
duration_msintegerOperation duration
error_codestringError code if failed
error_messagestringError description (sanitized)
metadataobjectEvent-specific additional data
previous_valueanyValue before change (redacted)
new_valueanyValue after change (redacted)

Event Types

Authentication Events

  • auth.login.success - Successful authentication
  • auth.login.failure - Failed authentication attempt
  • auth.logout - User logout
  • auth.token.issued - New token issued
  • auth.token.revoked - Token revoked
  • auth.token.expired - Token expired
  • auth.mfa.challenge - MFA challenge issued
  • auth.mfa.success - MFA verification succeeded
  • auth.mfa.failure - MFA verification failed

Authorization Events

  • authz.check.allowed - Permission check allowed
  • authz.check.denied - Permission check denied
  • authz.policy.evaluated - Policy evaluation completed

Agent Events

  • agent.registered - New agent registered
  • agent.deregistered - Agent removed
  • agent.heartbeat.received - Heartbeat received
  • agent.heartbeat.missed - Heartbeat timeout
  • agent.status.changed - Agent status changed
  • agent.certificate.issued - Certificate issued to agent
  • agent.certificate.rotated - Certificate rotated

Command Events

  • cmd.submitted - Command submitted for execution
  • cmd.started - Command execution started
  • cmd.completed - Command execution completed
  • cmd.failed - Command execution failed
  • cmd.cancelled - Command cancelled
  • cmd.timeout - Command timed out

State Events

  • state.applied - State configuration applied
  • state.checked - State drift check performed
  • state.drift.detected - Configuration drift detected
  • state.remediated - Drift remediated

Policy Events

  • policy.created - Policy created
  • policy.updated - Policy updated
  • policy.deleted - Policy deleted
  • policy.activated - Policy activated
  • policy.deactivated - Policy deactivated
  • policy.violation - Policy violation detected

System Events

  • system.startup - System started
  • system.shutdown - System shutdown initiated
  • system.config.changed - Configuration changed
  • system.backup.created - Backup created
  • system.backup.restored - Backup restored

Admin Events

  • admin.user.created - User account created
  • admin.user.updated - User account updated
  • admin.user.deleted - User account deleted
  • admin.role.assigned - Role assigned to user
  • admin.role.revoked - Role revoked from user

Retention Recommendations

Event CategoryMinimum RetentionRecommended RetentionNotes
Authentication90 days1 yearCompliance requirement
Authorization90 days1 yearFor access reviews
Command1 year3 yearsForensics requirement
State1 year3 yearsChange tracking
Policy1 year3 yearsCompliance evidence
System90 days1 yearOperational needs
Admin1 year7 yearsRegulatory compliance

Sensitive Data Handling

The following data MUST be redacted in audit logs:

  • Passwords and secrets (replace with [REDACTED])
  • Private keys and certificates
  • API tokens and bearer tokens
  • Personal identifiable information (PII) where not essential
  • Credit card numbers and financial data

The following MAY be logged with appropriate masking:

  • Email addresses (partial: u***@example.com)
  • IP addresses (may be full for security investigations)
  • Resource identifiers (full, for traceability)

Contributor Security Guidelines

Before Writing Code

  1. Understand the threat model: Review this document (SECURITY-DESIGN.md) and SECURITY.md
  2. Identify trust boundaries: Know which boundaries your code crosses
  3. Plan for failures: Design for graceful degradation

During Development

  1. Validate all input: Use internal/security.Validate* helpers for user input
  2. Handle errors securely: Never expose internal errors to users
  3. Use parameterized queries: Never concatenate SQL strings
  4. Avoid shell injection: Never pass user input to exec.Command without validation
  5. Log securely: Use structured logging with automatic redaction

Code Patterns to Avoid

// BAD: SQL injection vulnerability
query := "SELECT * FROM users WHERE id = '" + userID + "'"

// GOOD: Parameterized query
query := "SELECT * FROM users WHERE id = ?"
db.Query(query, userID)
// BAD: Path traversal vulnerability
filepath := "/data/" + userInput

// GOOD: Validated path
if err := security.ValidatePath(userInput); err != nil {
    return err
}
filepath := filepath.Join("/data", filepath.Clean(userInput))
// BAD: Command injection vulnerability
cmd := exec.Command("sh", "-c", "ls " + userDir)

// GOOD: Direct command with arguments
cmd := exec.Command("ls", userDir)
// BAD: Exposing internal errors
return fmt.Errorf("database error: %v", err)

// GOOD: Generic error to user, detailed log
log.Error("database query failed", "error", err, "query", query)
return ErrInternalServer

Security Review Requirements

PRs that touch these areas require explicit security review:

  • Authentication or authorization logic
  • Cryptographic operations
  • Database queries with user input
  • File operations with user-supplied paths
  • Network protocol handling
  • Credential or secret management
  • Audit logging
  • Trust boundary crossings

Reporting Security Issues

See SECURITY.md for vulnerability reporting procedures.


References