Hearth is the infrastructure home for the letemcook ecosystem. Ported from coherence-mcp/infra: - Terraform modules (VPC, EKS, IAM, NLB, S3, storage) - Kubernetes manifests (Forgejo, ingress, cert-manager, karpenter) - Deployment scripts (phased rollout) Status: Not deployed. EKS cluster needs to be provisioned. Next steps: 1. Bootstrap terraform backend 2. Deploy phase 1 (foundation) 3. Deploy phase 2 (core services including Forgejo) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
212 lines
6.2 KiB
HCL
212 lines
6.2 KiB
HCL
# Vault PKI for S/MIME Certificates
|
|
# RFC 0041: Self-Hosted DNS and Email
|
|
# ADR 0006: Zero-Knowledge Zero-Trust (Layer 3 encryption support)
|
|
#
|
|
# This configuration creates a PKI secrets engine in Vault for issuing
|
|
# S/MIME certificates to users. S/MIME provides end-to-end email encryption
|
|
# (Layer 3) where only the sender and recipient can read the email content.
|
|
|
|
terraform {
|
|
required_providers {
|
|
vault = {
|
|
source = "hashicorp/vault"
|
|
version = "~> 4.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
# =============================================================================
|
|
# ROOT CA (Offline - used only to sign intermediate)
|
|
# =============================================================================
|
|
|
|
resource "vault_mount" "pki_root_smime" {
|
|
path = "pki-smime-root"
|
|
type = "pki"
|
|
description = "S/MIME Root CA - Offline, used only to sign intermediate"
|
|
|
|
# Root CA has a longer lifetime
|
|
default_lease_ttl_seconds = 315360000 # 10 years
|
|
max_lease_ttl_seconds = 315360000 # 10 years
|
|
}
|
|
|
|
resource "vault_pki_secret_backend_root_cert" "smime_root" {
|
|
backend = vault_mount.pki_root_smime.path
|
|
type = "internal"
|
|
common_name = "Alignment S/MIME Root CA"
|
|
ttl = "315360000" # 10 years
|
|
key_type = "rsa"
|
|
key_bits = 4096
|
|
|
|
organization = "Alignment"
|
|
country = "US"
|
|
exclude_cn_from_sans = true
|
|
}
|
|
|
|
# =============================================================================
|
|
# INTERMEDIATE CA (Online - used to issue user certificates)
|
|
# =============================================================================
|
|
|
|
resource "vault_mount" "pki_smime" {
|
|
path = "pki-smime"
|
|
type = "pki"
|
|
description = "S/MIME Intermediate CA - Issues user certificates"
|
|
|
|
# Intermediate has shorter lifetime
|
|
default_lease_ttl_seconds = 31536000 # 1 year
|
|
max_lease_ttl_seconds = 94608000 # 3 years
|
|
}
|
|
|
|
# Generate intermediate CSR
|
|
resource "vault_pki_secret_backend_intermediate_cert_request" "smime_intermediate" {
|
|
backend = vault_mount.pki_smime.path
|
|
type = "internal"
|
|
common_name = "Alignment S/MIME Intermediate CA"
|
|
key_type = "rsa"
|
|
key_bits = 4096
|
|
|
|
organization = "Alignment"
|
|
country = "US"
|
|
}
|
|
|
|
# Sign intermediate with root
|
|
resource "vault_pki_secret_backend_root_sign_intermediate" "smime_intermediate" {
|
|
backend = vault_mount.pki_root_smime.path
|
|
common_name = "Alignment S/MIME Intermediate CA"
|
|
csr = vault_pki_secret_backend_intermediate_cert_request.smime_intermediate.csr
|
|
ttl = "157680000" # 5 years
|
|
|
|
organization = "Alignment"
|
|
country = "US"
|
|
|
|
# Intermediate CA permissions
|
|
permitted_dns_domains = ["alignment.dev"]
|
|
}
|
|
|
|
# Set the signed intermediate certificate
|
|
resource "vault_pki_secret_backend_intermediate_set_signed" "smime_intermediate" {
|
|
backend = vault_mount.pki_smime.path
|
|
certificate = vault_pki_secret_backend_root_sign_intermediate.smime_intermediate.certificate
|
|
}
|
|
|
|
# =============================================================================
|
|
# S/MIME CERTIFICATE ROLE
|
|
# =============================================================================
|
|
|
|
resource "vault_pki_secret_backend_role" "smime_user" {
|
|
backend = vault_mount.pki_smime.path
|
|
name = "smime-user"
|
|
|
|
# Certificate lifetime
|
|
ttl = 31536000 # 1 year
|
|
max_ttl = 63072000 # 2 years
|
|
|
|
# Domain restrictions
|
|
allow_any_name = false
|
|
allowed_domains = ["alignment.dev"]
|
|
allow_subdomains = false
|
|
enforce_hostnames = false
|
|
|
|
# Allow email addresses
|
|
allow_bare_domains = true
|
|
|
|
# Key configuration
|
|
key_type = "rsa"
|
|
key_bits = 4096
|
|
key_usage = ["DigitalSignature", "KeyEncipherment", "ContentCommitment"]
|
|
|
|
# S/MIME specific - Email Protection extended key usage
|
|
ext_key_usage = ["EmailProtection"]
|
|
|
|
# Certificate properties
|
|
require_cn = true
|
|
use_csr_common_name = true
|
|
use_csr_sans = true
|
|
|
|
# Organization defaults
|
|
organization = ["Alignment"]
|
|
country = ["US"]
|
|
|
|
# Don't include SANs automatically
|
|
allow_ip_sans = false
|
|
allow_localhost = false
|
|
allowed_uri_sans = []
|
|
allowed_other_sans = []
|
|
|
|
# Generate certificates (not just sign CSRs)
|
|
generate_lease = true
|
|
no_store = false
|
|
}
|
|
|
|
# =============================================================================
|
|
# POLICY FOR S/MIME CERTIFICATE ISSUANCE
|
|
# =============================================================================
|
|
|
|
resource "vault_policy" "smime_user_issue" {
|
|
name = "smime-user-issue"
|
|
policy = <<-EOT
|
|
# Allow users to issue S/MIME certificates for their own email
|
|
# Users authenticate via OIDC, and their email claim is used to verify
|
|
# they can only request certificates for their own email address.
|
|
|
|
# Issue S/MIME certificate
|
|
path "pki-smime/issue/smime-user" {
|
|
capabilities = ["create", "update"]
|
|
|
|
# Restrict to user's own email
|
|
allowed_parameters = {
|
|
"common_name" = []
|
|
"alt_names" = []
|
|
"ttl" = []
|
|
}
|
|
}
|
|
|
|
# Read certificate chain
|
|
path "pki-smime/ca/pem" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "pki-smime/ca_chain" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
# List own certificates
|
|
path "pki-smime/certs" {
|
|
capabilities = ["list"]
|
|
}
|
|
EOT
|
|
}
|
|
|
|
# =============================================================================
|
|
# CRL CONFIGURATION
|
|
# =============================================================================
|
|
|
|
resource "vault_pki_secret_backend_config_urls" "smime_urls" {
|
|
backend = vault_mount.pki_smime.path
|
|
|
|
issuing_certificates = [
|
|
"https://vault.alignment.dev/v1/pki-smime/ca"
|
|
]
|
|
|
|
crl_distribution_points = [
|
|
"https://vault.alignment.dev/v1/pki-smime/crl"
|
|
]
|
|
|
|
ocsp_servers = [
|
|
"https://vault.alignment.dev/v1/pki-smime/ocsp"
|
|
]
|
|
}
|
|
|
|
# =============================================================================
|
|
# OUTPUTS
|
|
# =============================================================================
|
|
|
|
output "smime_ca_chain" {
|
|
description = "S/MIME CA certificate chain"
|
|
value = vault_pki_secret_backend_intermediate_set_signed.smime_intermediate.certificate
|
|
sensitive = false
|
|
}
|
|
|
|
output "smime_issue_path" {
|
|
description = "Path to issue S/MIME certificates"
|
|
value = "${vault_mount.pki_smime.path}/issue/${vault_pki_secret_backend_role.smime_user.name}"
|
|
}
|