provisioning/schemas/security/sops/generator.ncl

69 lines
2.4 KiB
Text

# SOPS YAML Generator - Converts Nickel SOPS config to .sops.yaml format
let contracts = import "contracts.ncl" in
let defaults = import "defaults.ncl" in
{
# Generate a single SOPS rule as YAML-compatible record
rule_to_yaml = fun rule =>
let base = {
age = rule.age,
} in
let with_path = if std.string.is_empty rule.path_regex then base else
base & { path_regex = rule.path_regex } in
let with_regex = if std.record.has_field "encrypted_regex" rule then
with_path & { encrypted_regex = rule.encrypted_regex } else
with_path in
with_regex,
# Generate creation_rules section
generate_creation_rules = fun config =>
{
creation_rules = std.array.map rule_to_yaml config.creation_rules,
},
# Generate full .sops.yaml configuration for an environment
generate_sops_yaml = fun environment =>
let env_config = std.record.get environment defaults in
let rules_section = generate_creation_rules env_config in
rules_section,
# Generate all environment configurations
generate_all_environments = fun =>
{
dev = generate_sops_yaml "dev",
staging = generate_sops_yaml "staging",
prod = generate_sops_yaml "prod",
},
# Helper: Get Age public key from vault-service response
extract_public_key = fun vault_response =>
vault_response.public_key,
# Helper: Update config with actual Age keys from vault-service
inject_vault_keys = fun sops_config vault_keys =>
let update_rule = fun rule environment =>
rule & {
age = std.record.get environment vault_keys,
} in
sops_config,
# Serialize SOPS config to YAML-compatible text
serialize_to_yaml = fun config =>
let serialize_rule = fun rule =>
let parts = [] in
let parts = if std.record.has_field "path_regex" rule then
parts @ [ $" - path_regex: {rule.path_regex}" ] else
parts @ [ " -" ] in
let parts = parts @ [
$" age: '{rule.age}'"
] in
let parts = if std.record.has_field "encrypted_regex" rule then
parts @ [ $" encrypted_regex: '{rule.encrypted_regex}'" ] else
parts in
std.string.join "\n" parts in
let rules_text = std.array.join "\n"
(std.array.map serialize_rule config.creation_rules) in
$"# SOPS creation rules - evaluated sequentially, first match wins\ncreation_rules:\n{rules_text}\n",
}