diff --git a/.github/scripts/check-malformed-fences.nu b/.github/scripts/check-malformed-fences.nu new file mode 100755 index 0000000..831ad68 --- /dev/null +++ b/.github/scripts/check-malformed-fences.nu @@ -0,0 +1,74 @@ +#!/usr/bin/env nu +# Check for malformed closing code fences in markdown files +# CommonMark spec violation: Closing fences should be ``` without language specifiers + +def main [] { + # Find all markdown files (excluding ignored directories) + let md_files = ( + glob **/*.md + | where {|f| not ($f | str contains ".git") } + | where {|f| not ($f | str contains "target") } + | where {|f| not ($f | str contains "node_modules") } + | where {|f| not ($f | str contains ".coder") } + | where {|f| not ($f | str contains ".claude") } + | where {|f| not ($f | str contains ".wrks") } + ) + + mut total_issues = 0 + mut files_with_issues = [] + + for file in $md_files { + let issues = (check_file $file) + if ($issues | length) > 0 { + $total_issues = $total_issues + ($issues | length) + $files_with_issues = ($files_with_issues | append {file: $file, issues: $issues}) + } + } + + if $total_issues > 0 { + print $"❌ Found ($total_issues) malformed closing fence\(s\) in ($files_with_issues | length) file\(s\):\n" + + for item in $files_with_issues { + print $" ($item.file):" + for issue in $item.issues { + print $" Line ($issue.line): ($issue.content)" + } + } + + print "\nFix: Remove language specifiers from closing fences (should be just ```)" + exit 1 + } else { + print "✅ No malformed closing fences found" + exit 0 + } +} + +def check_file [file: string] { + mut issues = [] + mut in_code_block = false + mut line_num = 0 + + for line in (open $file | lines) { + $line_num = $line_num + 1 + + # Check if line is a code fence + let fence_match = ($line | parse --regex '^```(?P\w+)?\s*$') + + if ($fence_match | length) > 0 { + if not $in_code_block { + # Opening fence + $in_code_block = true + } else { + # Closing fence + let lang = ($fence_match | get 0.lang? | default "") + if ($lang | str length) > 0 { + # Malformed: has language on closing fence + $issues = ($issues | append {line: $line_num, content: $line}) + } + $in_code_block = false + } + } + } + + $issues +} diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..5f9de62 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,103 @@ +// Markdownlint-cli2 Configuration for SecretumVault +// Documentation quality enforcement for security-focused project +// See: https://github.com/igorshubovych/markdownlint-cli2 + +{ + "config": { + "default": true, + + // Headings - enforce proper hierarchy + "MD001": false, // heading-increment (relaxed - allow flexibility) + "MD026": { "punctuation": ".,;:!?" }, // heading-punctuation + + // Lists - enforce consistency + "MD004": { "style": "consistent" }, // ul-style (consistent list markers) + "MD005": false, // inconsistent-indentation (relaxed) + "MD007": { "indent": 2 }, // ul-indent + "MD029": false, // ol-prefix (allow flexible list numbering) + "MD030": { "ul_single": 1, "ol_single": 1, "ul_multi": 1, "ol_multi": 1 }, + + // Code blocks - fenced only + "MD046": { "style": "fenced" }, // code-block-style + // NOTE: MD040 only checks for missing language on opening fence. + // It does NOT catch malformed closing fences with language specifiers (e.g., ```plaintext). + // Custom pre-commit hook required to enforce proper closing fence syntax. + + // Formatting - strict whitespace + "MD009": true, // no-hard-tabs + "MD010": true, // hard-tabs + "MD011": true, // reversed-link-syntax + "MD018": true, // no-missing-space-atx + "MD019": true, // no-multiple-space-atx + "MD020": true, // no-missing-space-closed-atx + "MD021": true, // no-multiple-space-closed-atx + "MD023": true, // heading-starts-line + "MD027": true, // no-multiple-spaces-blockquote + "MD037": true, // no-space-in-emphasis + "MD039": true, // no-space-in-links + + // Trailing content + "MD012": false, // no-multiple-blanks (relaxed - allow formatting space) + "MD024": false, // no-duplicate-heading (too strict for docs) + "MD028": false, // no-blanks-blockquote (relaxed) + "MD031": false, // blanks-around-fences (too strict for technical docs) + "MD047": true, // single-trailing-newline + + // Links and references + "MD034": true, // no-bare-urls (links must be formatted) + "MD040": true, // fenced-code-language (code blocks need language) + "MD042": true, // no-empty-links + "MD051": false, // link-fragments (often false positives for valid internal links) + + // HTML - allow for documentation formatting and images + "MD033": { "allowed_elements": ["br", "hr", "details", "summary", "p", "img", "div"] }, + + // Line length - relaxed for technical documentation + "MD013": { + "line_length": 150, + "heading_line_length": 150, + "code_block_line_length": 150, + "code_blocks": true, + "tables": true, + "headers": true, + "headers_line_length": 150, + "strict": false, + "stern": false + }, + + // Images + "MD045": true, // image-alt-text + + // Disable rules that conflict with relaxed style + "MD003": false, // consistent-indentation + "MD041": false, // first-line-heading + "MD025": false, // single-h1 / multiple-top-level-headings + "MD022": false, // blanks-around-headings (flexible spacing) + "MD032": false, // blanks-around-lists (flexible spacing) + "MD035": false, // hr-style (consistent) + "MD036": false, // no-emphasis-as-heading + "MD044": false, // proper-names + "MD060": true // table-column-style (enforce proper table formatting) + }, + + // Documentation patterns + "globs": [ + "*.md", + "docs/**/*.md", + "!docs/node_modules/**", + "!docs/build/**" + ], + + // Ignore build artifacts, external content, and operational directories + "ignores": [ + "node_modules/**", + "target/**", + ".git/**", + "build/**", + "dist/**", + ".coder/**", + ".claude/**", + ".wrks/**", + ".vale/**" + ] +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c15a01c..ea75002 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -87,16 +87,24 @@ repos: # stages: [commit] # ============================================================================ - # Markdown Hooks (optional - enable if using Markdown) + # Markdown Hooks # ============================================================================ - # - repo: local - # hooks: - # - id: markdownlint - # name: Markdown linting (markdownlint-cli2) - # entry: markdownlint-cli2 - # language: system - # types: [markdown] - # stages: [commit] + - repo: local + hooks: + - id: markdownlint + name: Markdown linting (markdownlint-cli2) + entry: markdownlint-cli2 + language: system + types: [markdown] + stages: [commit] + + - id: check-malformed-fences + name: Check malformed closing fences + entry: bash -c 'nu .github/scripts/check-malformed-fences.nu' + language: system + types: [markdown] + pass_filenames: false + stages: [commit] # ============================================================================ # General Pre-commit Hooks diff --git a/.typedialog/ci/README.md b/.typedialog/ci/README.md index c51e5ad..532a4a8 100644 --- a/.typedialog/ci/README.md +++ b/.typedialog/ci/README.md @@ -89,7 +89,7 @@ vim .typedialog/ci/config.ncl **This project uses Nickel format by default** for all configuration files. -### Why Nickel? +### Why Nickel - ✅ **Typed configuration** - Static type checking with `nickel typecheck` - ✅ **Documentation** - Generate docs with `nickel doc config.ncl` @@ -201,7 +201,7 @@ Resources are searched in priority order: ### Affected Resources | Resource | Local Path | Tools Path | -|----------|------------|------------| +| ---------- | ------------ | ------------ | | Fragments | `.typedialog/ci/fragments/` | `$TOOLS_PATH/dev-system/ci/forms/fragments/` | | Schemas | `.typedialog/ci/schemas/` | `$TOOLS_PATH/dev-system/ci/schemas/` | | Validators | `.typedialog/ci/validators/` | `$TOOLS_PATH/dev-system/ci/validators/` | @@ -312,7 +312,7 @@ Edit `config.ncl` and add under `ci.tools`: enable_pre_commit = false ``` -## Need Help? +## Need Help For detailed documentation, see: - $env.TOOLS_PATH/dev-system/ci/docs/configuration-guide.md diff --git a/.typedialog/ci/config.ncl b/.typedialog/ci/config.ncl index 8752436..e83e36f 100644 --- a/.typedialog/ci/config.ncl +++ b/.typedialog/ci/config.ncl @@ -48,7 +48,7 @@ # Clippy - Rust linting tool clippy = { enabled = true, - install_method = "builtin", + install_method = "cargo", deny_warnings = true, }, # Cargo Audit - Security vulnerability scanner @@ -67,7 +67,7 @@ install_method = "cargo", }, # LLVM Coverage - Code coverage tool - llvm_cov = { + llvm-cov = { enabled = true, install_method = "cargo", }, diff --git a/.typedialog/ci/config.ncl.20251229_163955.bak b/.typedialog/ci/config.ncl.20251229_163955.bak new file mode 100644 index 0000000..e83e36f --- /dev/null +++ b/.typedialog/ci/config.ncl.20251229_163955.bak @@ -0,0 +1,138 @@ +# CI Configuration - Nickel Format +# Auto-generated by dev-system CI installer +# +# This file is managed by TypeDialog using nickel-roundtrip. +# Edit via: .typedialog/ci/configure.sh +# Or manually edit and validate with: nickel typecheck config.ncl +# +# Documentation: nickel doc config.ncl + +{ + # CI namespace - all configuration lives under 'ci' + ci = { + # Project Information + # Detected languages and primary language for this project + project = { + # Project name + name = "SecretumVault", + # Project description + description = "Secretum Vault", + # Project website or documentation site URL + site_url = "https://secretumvault.dev", + # Project repository URL (GitHub, GitLab, etc.) + repo_url = "https://repo.jesusperez.pro/jesus/secretumvault.git", + # Languages detected in codebase (auto-detected by installer) + detected_languages = [ + "rust", + "nickel", + "bash", + "markdown" + ], + # Primary language (determines default tooling) + primary_language = "rust", + }, + + # CI Tools Configuration + # Each tool can be enabled/disabled and configured here + tools = { + # Taplo - TOML formatter and linter + taplo = { + enabled = true, + install_method = "cargo", + }, + # YAMLlint - YAML formatter and linter + yamllint = { + enabled = true, + install_method = "brew", + }, + # Clippy - Rust linting tool + clippy = { + enabled = true, + install_method = "cargo", + deny_warnings = true, + }, + # Cargo Audit - Security vulnerability scanner + audit = { + enabled = true, + install_method = "cargo", + }, + # Cargo Deny - Dependency checker + deny = { + enabled = true, + install_method = "cargo", + }, + # Cargo SBOM - Software Bill of Materials + sbom = { + enabled = true, + install_method = "cargo", + }, + # LLVM Coverage - Code coverage tool + llvm-cov = { + enabled = true, + install_method = "cargo", + }, + # Shellcheck - Bash/shell script linter + shellcheck = { + enabled = true, + install_method = "brew", + }, + # Shfmt - Shell script formatter + shfmt = { + enabled = true, + install_method = "brew", + }, + # Markdownlint - Markdown linter + markdownlint = { + enabled = true, + install_method = "npm", + }, + # Vale - Prose linter + vale = { + enabled = true, + install_method = "brew", + }, + # Nickel - Configuration language type checker + nickel = { + enabled = true, + install_method = "brew", + check_all = true, + }, + }, + + # CI Features + # High-level feature flags for CI behavior + features = { + enable_ci_cd = true, + enable_pre_commit = true, + generate_taplo_config = true, + generate_contributing = true, + generate_security = true, + generate_code_of_conduct = true, + generate_dockerfiles = true, + enable_cross_compilation = true, + }, + + # CI Provider Configurations + # Settings for GitHub Actions, Woodpecker, GitLab CI, etc. + ci_providers = { + # GitHub Actions + github_actions = { + enabled = true, + branches_push = "main,develop", + branches_pr = "main", + }, + # Woodpecker CI + woodpecker = { + enabled = true, + }, + }, + + # CI Settings + settings = { + parallel_jobs = 1, + job_timeout_minutes = 1, + require_status_checks = true, + run_on_draft_prs = true, + }, + }, +} diff --git a/.woodpecker/README.md b/.woodpecker/README.md index 58b4853..b1e92ec 100644 --- a/.woodpecker/README.md +++ b/.woodpecker/README.md @@ -65,12 +65,12 @@ git push origin main ## Viewing Results - **Gitea/Forgejo**: Repository → Actions → Pipeline runs -- **Woodpecker UI**: https://your-woodpecker.instance/repos/{user}/{repo} +- **Woodpecker UI**: <<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>/repos/{user}/{repo}> ## Differences from GitHub Actions | Feature | GitHub Actions | Woodpecker CI | -|---------|---------------|---------------| +| --------- | --------------- | --------------- | | Matrix builds | ✅ 3 OS | ❌ Linux only* | | Caching | ✅ Built-in | ⚠️ Server-side** | diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index ef8db03..e72b844 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,7 +2,8 @@ ## Our Pledge -We, as members, contributors, and leaders, pledge to make participation in our project and community a harassment-free experience for everyone, regardless of: +We, as members, contributors, and leaders, pledge to make participation in our project and community +a harassment-free experience for everyone, regardless of: - Age - Body size @@ -44,7 +45,8 @@ Examples of unacceptable behavior include: ## Enforcement Responsibilities -Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate corrective action in response to unacceptable behavior. +Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior +and will take appropriate corrective action in response to unacceptable behavior. Maintainers have the right and responsibility to: @@ -94,7 +96,7 @@ All complaints will be reviewed and investigated promptly and fairly. This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1. -For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. +For answers to common questions about this code of conduct, see the FAQ at . --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 030c6d6..222ea85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,8 @@ Thank you for your interest in contributing! This document provides guidelines a ## Code of Conduct -This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for details. +This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. +Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for details. ## Getting Started @@ -120,7 +121,7 @@ Maintainers handle releases following semantic versioning: - MINOR: New features (backward compatible) - PATCH: Bug fixes -## Questions? +## Questions - Check existing documentation and issues - Ask in discussions or open an issue diff --git a/README.md b/README.md index 8945246..36e42fe 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ **Post-quantum cryptographic secrets vault for modern infrastructure** -SecretumVault is a Rust-native secrets vault combining post-quantum cryptography (ML-KEM-768, ML-DSA-65) with classical crypto, multiple secrets engines, cedar-based policy authorization, and flexible storage backends. +SecretumVault is a Rust-native secrets vault combining post-quantum cryptography (ML-KEM-768, ML-DSA-65) with classical crypto, +multiple secrets engines, cedar-based policy authorization, and flexible storage backends. ## Features @@ -175,7 +176,7 @@ Tokens have: ## Architecture Overview -``` +```text ┌─────────────────────────────────────────────────────────────┐ │ API Layer (Axum) │ │ /v1/secret/* | /v1/transit/* | /v1/pki/* | /v1/database/* │ @@ -432,7 +433,7 @@ Full guide: `docs/HOWOTO.md` ## Project Structure -``` +```text secretumvault/ ├── src/ │ ├── main.rs # Server binary entry point diff --git a/SECURITY.md b/SECURITY.md index e49aa37..d087ee2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,10 +4,10 @@ This project provides security updates for the following versions: -| Version | Supported | -|---------|-----------| -| 1.x | ✅ Yes | -| 0.x | ❌ No | +| Version | Supported | +| ------- | ----------- | +| 1.x | ✅ Yes | +| 0.x | ❌ No | Only the latest major version receives security patches. Users are encouraged to upgrade to the latest version. @@ -93,6 +93,6 @@ Security fixes are highlighted in CHANGELOG.md with [SECURITY] prefix. - [Rust Security](https://www.rust-lang.org/governance/security-disclosures) - [npm Security](https://docs.npmjs.com/about-npm/security) -## Questions? +## Questions If you have security questions (not vulnerabilities), open a discussion or issue with the `security` label. diff --git a/deploy/docker/config/svault.toml b/deploy/docker/config/svault.toml index 9a5c4b0..2aea9ad 100644 --- a/deploy/docker/config/svault.toml +++ b/deploy/docker/config/svault.toml @@ -58,8 +58,8 @@ versioned = false level = "info" # Output format: text or json format = "json" -# Optional file output -output = null +# Optional file output (commented: would go to stdout if set) +# output = "/var/log/secretumvault.log" # Enable ANSI colors in stdout ansi = true diff --git a/docs/README.md b/docs/README.md index ee200cf..2128744 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,7 +28,7 @@ Complete documentation for SecretumVault secrets management system. ## Quick Navigation -### I want to... +### I want to **Deploy SecretumVault** → Start with [Deployment Guide](operations/deployment.md) @@ -49,7 +49,8 @@ Complete documentation for SecretumVault secrets management system. → See [How-To: Kubernetes Integration](user-guide/howto.md#integrate-with-kubernetes) **Enable post-quantum cryptography** -→ Read [PQC Support Guide](development/pqc-support.md), [Configuration: Crypto Backends](user-guide/configuration.md#crypto-backends), or [Build Features: PQC](development/build-features.md#post-quantum-cryptography) +→ Read [PQC Support Guide](development/pqc-support.md), [Configuration: Crypto Backends](user-guide/configuration.md#crypto-backends), +or [Build Features: PQC](development/build-features.md#post-quantum-cryptography) **Rotate secrets automatically** → Check [How-To: Secret Rotation](user-guide/howto.md#secret-rotation) @@ -64,7 +65,7 @@ Complete documentation for SecretumVault secrets management system. ## Documentation Structure -``` +```text docs/ ├── README.md # This file ├── index.md # mdBook introduction @@ -109,7 +110,7 @@ No recompilation needed—just update the TOML file. Backend selection uses type-safe registry pattern: -``` +```text Config String → Registry Dispatch → Concrete Backend "etcd" → StorageRegistry → etcdBackend "openssl" → CryptoRegistry → OpenSSLBackend @@ -120,7 +121,7 @@ Config String → Registry Dispatch → Concrete Backend All I/O is non-blocking using Tokio: -``` +```text HTTP Request → Axum Router → Engine → Storage Backend (async/await) → Crypto Backend (async/await) → Policy Engine (sync) @@ -148,7 +149,7 @@ Tokens include: ### Cryptography | Feature | Status | Notes | -|---------|--------|-------| +| --------- | -------- | ------- | | OpenSSL backend (RSA, ECDSA) | ✅ Complete | Stable, widely supported | | AWS-LC backend (RSA, ECDSA) | ✅ Complete | Post-quantum ready | | ML-KEM-768 (Key encapsulation) | ✅ Feature-gated | Post-quantum, feature: `pqc` | @@ -159,7 +160,7 @@ Tokens include: ### Secrets Engines | Engine | Status | Features | -|--------|--------|----------| +| -------- | -------- | ---------- | | KV (Key-Value) | ✅ Complete | Versioned storage, encryption at rest | | Transit (Encryption) | ✅ Complete | Encrypt/decrypt without storage | | PKI (Certificates) | ✅ Complete | CA, certificate issuance, CRL | @@ -170,7 +171,7 @@ Tokens include: ### Storage Backends | Backend | Status | Use Case | -|---------|--------|----------| +| --------- | -------- | ---------- | | etcd | ✅ Complete | Distributed HA (production) | | SurrealDB | ✅ Complete | Document queries (testing) | | PostgreSQL | ✅ Complete | Relational (production) | @@ -181,7 +182,7 @@ Tokens include: ### Authorization | Feature | Status | Notes | -|---------|--------|-------| +| --------- | -------- | ------- | | Cedar policies | ✅ Complete | AWS open-source ABAC language | | Token management | ✅ Complete | TTL, renewal, revocation | | Audit logging | ✅ Complete | Full request/response audit | @@ -191,7 +192,7 @@ Tokens include: ### Deployment | Format | Status | Features | -|--------|--------|----------| +| -------- | -------- | ---------- | | Docker | ✅ Complete | Multi-stage build, minimal image | | Docker Compose | ✅ Complete | Full dev stack (6 services) | | Kubernetes | ✅ Complete | Manifests + RBAC + StatefulSet | @@ -201,7 +202,7 @@ Tokens include: ### Observability | Feature | Status | Features | -|---------|--------|----------| +| --------- | -------- | ---------- | | Prometheus metrics | ✅ Complete | 13+ metrics, text format | | Structured logging | ✅ Complete | JSON or human-readable | | Audit logging | ✅ Complete | Encrypted storage + display | diff --git a/docs/architecture/complete-architecture.md b/docs/architecture/complete-architecture.md index 72dd8f9..ca63770 100644 --- a/docs/architecture/complete-architecture.md +++ b/docs/architecture/complete-architecture.md @@ -2,7 +2,7 @@ **Version:** 3.0 **Date:** 2025-12-21 -**Author:** Jesús Pérez +**Author:** Jesús Pérez **Project Name:** `secretumvault` or `svault` ## Executive Summary @@ -46,9 +46,9 @@ ## Core Concepts -### What is SecretumVault? +### What is SecretumVault -``` +```text SecretumVault = Secrets Manager + Encryption Service + Key Management + Cedar Policies + Post-Quantum Crypto ``` @@ -83,7 +83,7 @@ SecretumVault = Secrets Manager + Encryption Service + Key Management ## Architecture -``` +```text ┌─────────────────────────────────────────────────────────────────┐ │ CLIENT LAYER │ ├─────────────────────────────────────────────────────────────────┤ @@ -415,7 +415,7 @@ permit( resource in Project::"kit-digital" ) when { - context.environment == "development" || + context.environment == "development" | | context.environment == "staging" }; @@ -1131,7 +1131,7 @@ prometheus_port = 9090 ## Project Structure -``` +```text secretumvault/ ├── Cargo.toml ├── README.md @@ -1303,10 +1303,10 @@ required-features = ["cli"] --- -## ¿Por qué SecretumVault vs. Solo Crypto Service? +## ¿Por qué SecretumVault vs. Solo Crypto Service | Feature | Crypto Service Solo | SecretumVault Completo | -|---|---|---| +| --- | --- | --- | | Secrets Management | ❌ | ✅ KV + Dynamic | | Encryption as a Service | ⚠️ Básico | ✅ Transit engine completo | | Authorization | ❌ | ✅ Cedar policies | diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index db04181..2d21a2a 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -30,7 +30,7 @@ SecretumVault is a **config-driven, async-first secrets management system** buil ### Design Philosophy -``` +```text ┌─────────────────────────────────────────────────────┐ │ Config-Driven: WHAT to use │ │ (backend selection, engine mounting) │ @@ -141,7 +141,7 @@ impl VaultCore { Axum-based HTTP server with middleware stack. -``` +```text HTTP Request ↓ [Axum Router] @@ -192,7 +192,7 @@ pub fn build_router(vault: Arc) -> Router { ### Secret Read Request -``` +```text 1. Client: curl -H "X-Vault-Token: $TOKEN" \ http://localhost:8200/v1/secret/data/myapp @@ -238,7 +238,7 @@ pub fn build_router(vault: Arc) -> Router { ### Secret Write Request -``` +```text Similar to read, but: 1. Auth → Cedar policy evaluation (write policy) @@ -259,7 +259,7 @@ All runtime behavior determined by `svault.toml`: ### Configuration Hierarchy -``` +```text VaultConfig (root) ├── [vault] section │ ├── crypto_backend = "openssl" @@ -476,7 +476,7 @@ pub trait StorageBackend: Send + Sync { Keys are namespaced by purpose: -``` +```text Direct secret storage: secret:metadata:myapp → Metadata (path, versions, timestamps) secret:v1:myapp → Version 1 (encrypted data) @@ -501,7 +501,7 @@ Internal: Storage operations are atomic but don't use distributed locks: -``` +```text Write Operation: 1. Read current value (with version) 2. Modify in-memory @@ -548,7 +548,7 @@ pub trait CryptoBackend: Send + Sync { All secrets encrypted with master key: -``` +```text Master Key (from Shamir SSS) ↓ Encrypt with NIST SP 800-38D (GCM mode) @@ -607,7 +607,7 @@ pub trait Engine: Send + Sync { ### Engine Request Flow -``` +```text HTTP Request: POST /v1/secret/data/myapp ↓ Router matches /secret/ prefix @@ -698,7 +698,7 @@ permit ( ### Policy Evaluation Flow -``` +```text HTTP Request ↓ Extract principal: X-Vault-Token @@ -722,7 +722,7 @@ Decision: ### Token Lifecycle -``` +```text Create: 1. Generate random token ID (32 bytes) 2. Create metadata: {policies, ttl, created_at, renewable} @@ -751,7 +751,7 @@ Revoke: ### Docker Compose (Local Development) -``` +```text ┌─────────────────────────────────────────────────────┐ │ Docker Compose Network │ │ (vault-network) │ @@ -765,7 +765,7 @@ Revoke: ### Kubernetes Cluster -``` +```text ┌────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ │ │ @@ -793,7 +793,7 @@ Revoke: ### Helm Chart Structure -``` +```text helm/secretumvault/ ├── Chart.yaml # Chart metadata ├── values.yaml # Default values (90+ options) @@ -811,7 +811,7 @@ helm/secretumvault/ ### Secret Storage Flow -``` +```text User Request: {"username": "admin", "password": "secret123"} @@ -862,7 +862,7 @@ Audit logged: ### Secret Retrieval Flow -``` +```text User Request: GET /v1/secret/data/myapp Header: X-Vault-Token: token_abc123 @@ -957,7 +957,7 @@ Minimal contention design: All secrets encrypted at rest: -``` +```text Plaintext → Master Key → AES-256-GCM → Ciphertext (with AAD) ``` @@ -968,7 +968,7 @@ Master key stored encrypted via Shamir SSS (threshold encryption). Complete operation audit: -``` +```text Every operation logged: - Principal (token ID) - Action (read/write/delete) diff --git a/docs/development/build-features.md b/docs/development/build-features.md index 21fc57a..79c47de 100644 --- a/docs/development/build-features.md +++ b/docs/development/build-features.md @@ -235,7 +235,7 @@ default = ["server", "cli"] ## Feature Dependencies -``` +```text [aws-lc] ├── aws-lc-rs crate └── openssl (system dependency) @@ -538,7 +538,7 @@ rustup target add aarch64-unknown-linux-gnu ## Feature Combinations Reference | Build | Command | Binary Size | Use Case | -|-------|---------|-------------|----------| +| ------- | --------- | ------------- | ---------- | | Minimal | `cargo build --release` | ~5 MB | Testing, education | | Standard | `cargo build --release --features postgresql-storage` | ~8 MB | Production standard | | HA | `cargo build --release --features etcd-storage` | ~9 MB | High availability | @@ -551,7 +551,7 @@ rustup target add aarch64-unknown-linux-gnu ### Feature Not Found -``` +```text error: feature `xyz` not found ``` @@ -559,7 +559,7 @@ Solution: Check `Cargo.toml` for correct feature name. ### Dependency Conflict -``` +```text error: conflicting versions for dependency `tokio` ``` @@ -567,7 +567,7 @@ Solution: Run `cargo update` to resolve. ### Compilation Error with Feature -``` +```text error[E0433]: cannot find function `aws_lc_function` in this scope ``` @@ -575,7 +575,7 @@ Solution: Ensure feature is enabled: `cargo build --features aws-lc` ### Linking Error -``` +```text error: linking with `cc` failed ``` diff --git a/docs/development/features-control.md b/docs/development/features-control.md index c568b17..56f18e2 100644 --- a/docs/development/features-control.md +++ b/docs/development/features-control.md @@ -30,7 +30,7 @@ The **Justfile provides recipes** that make feature management simple: ### Architecture -``` +```text Justfile (variables + recipes) ↓ justfiles/build.just (build recipes with features) @@ -52,7 +52,7 @@ just show-features ``` Output: -``` +```text ═══════════════════════════════════════════════════════ CRYPTO BACKENDS ═══════════════════════════════════════════════════════ @@ -84,7 +84,7 @@ just show-config ``` Output: -``` +```text Development (all features): Features: aws-lc,pqc,etcd-storage,surrealdb-storage,postgresql-storage Command: just build::dev @@ -244,7 +244,7 @@ just test::with-features aws-lc,pqc ### Crypto Features | Feature | Type | Default | Description | -|---------|------|---------|-------------| +| --------- | ------ | --------- | ------------- | | `aws-lc` | Backend | No | AWS-LC cryptographic library (PQC-ready) | | `pqc` | Extension | No | Post-quantum algorithms (requires aws-lc) | | `rustcrypto` | Backend | No | Pure Rust crypto (planned) | @@ -257,7 +257,7 @@ just test::with-features aws-lc,pqc ### Storage Features | Feature | Type | Default | Description | -|---------|------|---------|-------------| +| --------- | ------ | --------- | ------------- | | `etcd-storage` | Backend | No | etcd distributed KV store | | `surrealdb-storage` | Backend | No | SurrealDB document database | | `postgresql-storage` | Backend | No | PostgreSQL relational database | @@ -271,7 +271,7 @@ just test::with-features aws-lc,pqc ### Component Features | Feature | Type | Default | Description | -|---------|------|---------|-------------| +| --------- | ------ | --------- | ------------- | | `server` | Component | Yes | HTTP server (Axum) | | `cli` | Component | Yes | Command-line tools | | `cedar` | Component | No | Cedar policy engine | @@ -458,7 +458,7 @@ ls -lh target/release/svault ### Recommended Combinations -``` +```text Development: aws-lc,pqc,etcd-storage,surrealdb-storage,postgresql-storage @@ -477,7 +477,7 @@ Testing: ### Do NOT Combine -``` +```text ✗ Multiple crypto backends (only one can be used) aws-lc + rustcrypto (invalid) openssl + aws-lc (openssl is default, don't add) @@ -492,7 +492,7 @@ Testing: ### "Unknown feature" -``` +```text error: unknown feature `xyz` in `[dependencies.vault]` ``` diff --git a/docs/development/pqc-support.md b/docs/development/pqc-support.md index c6f1052..8d03648 100644 --- a/docs/development/pqc-support.md +++ b/docs/development/pqc-support.md @@ -28,7 +28,7 @@ ## Backend Support Matrix | Feature | OpenSSL | AWS-LC | RustCrypto | -|---------|---------|--------|-----------:| +| --------- | --------- | -------- | -----------: | | **Classical RSA** | ✅ | ✅ | ❌ | | **Classical ECDSA** | ✅ | ✅ | ❌ | | **AES-256-GCM** | ✅ | ✅ | ✅ | @@ -215,20 +215,20 @@ cargo build --release # Uses OpenSSL, no PQC ## Recommendation Matrix -### For Security-Critical Production: +### For Security-Critical Production **Use**: AWS-LC Backend with `--features aws-lc,pqc` - ✅ Production-grade PQC algorithms - ✅ NIST-approved algorithms - ✅ Future-proof cryptography - ✅ Hybrid mode available -### For Testing/Development: +### For Testing/Development **Use**: RustCrypto or OpenSSL Backend - Suitable for non-cryptographic tests - RustCrypto provides correct key structures - OpenSSL sufficient for development -### For Compliance-Heavy Environments: +### For Compliance-Heavy Environments **Use**: AWS-LC Backend with PQC - NIST FIPS 203/204 compliance - Post-quantum ready @@ -238,7 +238,7 @@ cargo build --release # Uses OpenSSL, no PQC ## Configuration Examples -### Development with PQC: +### Development with PQC ```toml [vault] crypto_backend = "aws-lc" @@ -248,13 +248,13 @@ enable_pqc = true hybrid_mode = true ``` -### Production Standard (Classical): +### Production Standard (Classical) ```toml [vault] crypto_backend = "openssl" ``` -### Production Secure (PQC): +### Production Secure (PQC) ```toml [vault] crypto_backend = "aws-lc" @@ -271,7 +271,7 @@ hybrid_mode = true **PQC Support: TWO Backends Available** | Backend | ML-KEM-768 | ML-DSA-65 | Readiness | -|---------|:----------:|:---------:|-----------:| +| --------- | :----------: | :---------: | -----------: | | **AWS-LC** | ✅ | ✅ | 🟢 PRODUCTION | | **RustCrypto** | ✅ | ✅ | 🟡 FALLBACK | | **OpenSSL** | ❌ | ❌ | 🔵 CLASSICAL | diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md index 0c8cbb3..2da703d 100644 --- a/docs/user-guide/configuration.md +++ b/docs/user-guide/configuration.md @@ -55,7 +55,7 @@ crypto_backend = "openssl" ### Options | Option | Type | Default | Description | -|--------|------|---------|-------------| +| -------- | ------ | --------- | ------------- | | `crypto_backend` | string | `"openssl"` | Cryptographic backend for encrypt/decrypt/sign operations | ### Valid Values @@ -98,7 +98,7 @@ port = 8200 ### Options | Option | Type | Default | Description | -|--------|------|---------|-------------| +| -------- | ------ | --------- | ------------- | | `address` | string | `"0.0.0.0"` | IP address to bind to | | `port` | integer | `8200` | Port for HTTP/HTTPS | | `tls_cert` | string | null | Path to TLS certificate file | @@ -296,7 +296,7 @@ threshold = 3 Splits master key into `shares` keys, requiring `threshold` to reconstruct. | Config | Meaning | Example | -|--------|---------|---------| +| -------- | --------- | --------- | | `shares = 5, threshold = 3` | 5 keys generated, need 3 to unseal | Most common | | `shares = 3, threshold = 2` | 3 keys, need 2 (faster unsealing) | Small teams | | `shares = 7, threshold = 4` | 7 keys, need 4 (higher security) | Large organizations | @@ -418,7 +418,7 @@ ansi = true ### Options | Option | Type | Values | Default | -|--------|------|--------|---------| +| -------- | ------ | -------- | --------- | | `level` | string | trace, debug, info, warn, error | `"info"` | | `format` | string | json, pretty | `"json"` | | `output` | string | stdout, stderr, file path | `"stdout"` | @@ -473,7 +473,7 @@ enable_trace = false ### Options | Option | Type | Default | Description | -|--------|------|---------|-------------| +| -------- | ------ | --------- | ------------- | | `prometheus_port` | integer | `9090` | Port for `/metrics` endpoint | | `enable_trace` | bool | `false` | Enable OpenTelemetry tracing (planned) | @@ -522,7 +522,7 @@ default_ttl = 24 ### Options | Option | Type | Default | Description | -|--------|------|---------|-------------| +| -------- | ------ | --------- | ------------- | | `default_ttl` | integer | `24` | Token lifetime in hours | | `cedar_policies_dir` | string | null | Directory containing .cedar policy files | | `cedar_entities_file` | string | null | JSON file with Cedar entities | @@ -691,7 +691,7 @@ cedar_entities_file = "/etc/secretumvault/entities.json" Vault validates configuration at startup: -``` +```text Config Loading ↓ Parse TOML diff --git a/scripts/fix-markdown-errors.nu b/scripts/fix-markdown-errors.nu new file mode 100755 index 0000000..d32e8da --- /dev/null +++ b/scripts/fix-markdown-errors.nu @@ -0,0 +1,182 @@ +#!/usr/bin/env nu +# Fix markdown linting errors in secretumvault + +def main [] { + print "🔧 Fixing markdown errors in secretumvault...\n" + + # Fix malformed closing fences + print "1. Fixing malformed closing code fences..." + fix_malformed_closing_fences + + # Fix MD040 - Add language to code fences + print "2. Fixing MD040 (code blocks missing language)..." + fix_md040 + + # Fix MD060 - Table formatting + print "3. Fixing MD060 (table formatting)..." + fix_md060 + + # Fix MD034 - Bare URLs + print "4. Fixing MD034 (bare URLs)..." + fix_md034 + + # Fix MD026 - Trailing punctuation in headings + print "5. Fixing MD026 (trailing punctuation in headings)..." + fix_md026 + + # Fix MD013 - Line length + print "6. Fixing MD013 (line length)..." + fix_md013 + + # Fix MD033 - Inline HTML + print "7. Fixing MD033 (inline HTML)..." + fix_md033 + + # Fix MD047 - Single trailing newline + print "8. Fixing MD047 (single trailing newline)..." + fix_md047 + + print "\n✅ All fixes applied. Run markdownlint-cli2 to verify." +} + +# Fix malformed closing fences - Remove language specifiers from closing code fences +def fix_malformed_closing_fences [] { + # Use bash with find to process all markdown files with perl + # This is more reliable than trying to loop through files in Nushell + bash -c 'find . -name "*.md" -not -path "*/.git/*" -not -path "*/target/*" -not -path "*/.coder/*" -not -path "*/.claude/*" -not -path "*/.wrks/*" -exec perl -i.bak -f /tmp/fix_fences.pl {} \; -exec rm -f {}.bak \;' + + print " ✓ Malformed closing fences fixed" +} + +# Fix MD040 - Add 'text' language to bare code fences +def fix_md040 [] { + let files = [ + "assets/branding/brand-guidelines.md" + "assets/branding/README.md" + "docs/architecture/complete-architecture.md" + "docs/architecture/overview.md" + "docs/user-guide/configuration.md" + "README.md" + ] + + for file in $files { + if ($file | path exists) { + sed -i.bak 's/^```$/```text/' $file + rm -f $"($file).bak" + } + } +} + +# Fix MD060 - Table formatting (add spaces around pipes) +def fix_md060 [] { + let files = (glob **/*.md + | where {|f| not ($f | str contains ".git") } + | where {|f| not ($f | str contains "target") } + | where {|f| not ($f | str contains ".coder") } + ) + + for file in $files { + # Read file + let content = (open $file) + + # Fix compact table style (missing spaces) + # Pattern: |word| → | word | + let fixed = ($content + | str replace --all --regex '\|([^\s\|][^\|]*[^\s\|])\|' '| $1 |' + | str replace --all --regex '\|([^\s\|])\|' '| $1 |' + ) + + $fixed | save -f $file + } +} + +# Fix MD034 - Bare URLs (wrap in angle brackets) +def fix_md034 [] { + let file = ".woodpecker/README.md" + + if ($file | path exists) { + sed -i.bak 's|https://your-woodpecker\.instance||' $file + rm -f $"($file).bak" + } +} + +# Fix MD026 - Remove trailing punctuation from headings +def fix_md026 [] { + let files = [ + ".typedialog/ci/README.md" + "CONTRIBUTING.md" + "SECURITY.md" + "docs/architecture/complete-architecture.md" + ] + + for file in $files { + if ($file | path exists) { + # Remove ? from headings + sed -i.bak 's/^\(#\+.*\)\?$/\1/' $file + rm -f $"($file).bak" + } + } +} + +# Fix MD013 - Line length (break long lines) +def fix_md013 [] { + # These require manual review - just note them + print " ⚠️ Line length issues require manual review:" + print " - CODE_OF_CONDUCT.md:5, 47" + print " - CONTRIBUTING.md:7" + print " - README.md:9" + print " - assets/branding/brand-guidelines.md:9, 436, 450" +} + +# Fix MD033 - Inline HTML +def fix_md033 [] { + # These are intentional HTML (div for centering) - update config + print " ℹ️ Inline HTML is intentional (centering divs) - updating config..." + + let config_file = ".markdownlint-cli2.jsonc" + + if ($config_file | path exists) { + # Add 'div' to allowed_elements + let content = (open $config_file) + let updated = ($content | str replace + '"allowed_elements": ["br", "hr", "details", "summary", "p", "img"]' + '"allowed_elements": ["br", "hr", "details", "summary", "p", "img", "div"]' + ) + $updated | save -f $config_file + } +} + +# Fix MD047 - Single trailing newline +def fix_md047 [] { + let md_files = [ + "CODE_OF_CONDUCT.md" + "CONTRIBUTING.md" + "README.md" + "SECURITY.md" + "docs/architecture/complete-architecture.md" + "docs/architecture/overview.md" + "docs/architecture/README.md" + "docs/development/build-features.md" + "docs/development/features-control.md" + "docs/development/pqc-support.md" + "docs/development/README.md" + "docs/index.md" + "docs/operations/deployment.md" + "docs/operations/README.md" + "docs/README.md" + "docs/user-guide/configuration.md" + "docs/user-guide/howto.md" + "docs/user-guide/README.md" + ] + + for file in $md_files { + if ($file | path exists) { + let content = (open $file) + # Ensure file ends with exactly one newline + let fixed = ($content | str trim -r) + "\n" + $fixed | save -f $file + } + } + + print " ✓ Single trailing newlines fixed" +} diff --git a/scripts/fix-table-formatting.nu b/scripts/fix-table-formatting.nu new file mode 100755 index 0000000..52dbed1 --- /dev/null +++ b/scripts/fix-table-formatting.nu @@ -0,0 +1,63 @@ +#!/usr/bin/env nu +# Fix MD060 table formatting errors - ensure spaces around pipes + +def main [] { + let files = (glob **/*.md + | where {|f| not ($f | str contains ".git") } + | where {|f| not ($f | str contains "target") } + | where {|f| not ($f | str contains ".coder") } + | where {|f| not ($f | str contains ".claude") } + ) + + print $"Processing ($files | length) markdown files..." + + for file in $files { + fix_tables_in_file $file + } + + print "✅ Table formatting fixed" +} + +def fix_tables_in_file [file: string] { + let content = (open $file --raw) + let lines = ($content | lines) + + mut fixed_lines = [] + + for line in $lines { + if ($line | str contains "|") { + # This is likely a table line + let fixed = (fix_table_line $line) + $fixed_lines = ($fixed_lines | append $fixed) + } else { + $fixed_lines = ($fixed_lines | append $line) + } + } + + $fixed_lines | str join "\n" | save -f $file +} + +def fix_table_line [line: string] { + # Fix table pipes to have spaces: |word| → | word | + mut result = $line + + # Pattern 1: |word| → | word | + # Replace pipes with no spaces around content + $result = ($result + | str replace --all --regex '\|([^\s\|][^\|]*?)\|' '| $1 |' + ) + + # Pattern 2: Fix leading/trailing pipes + $result = ($result + | str replace --all --regex '^\|([^\s])' '| $1' + | str replace --all --regex '([^\s])\|$' '$1 |' + ) + + # Pattern 3: Fix consecutive pipes with content + $result = ($result + | str replace --all --regex '\|([^\s\|])' '| $1' + | str replace --all --regex '([^\s\|])\|' '$1 |' + ) + + $result +}