Direct translation of DESIGN-OPS-DB-CHAIN-OF-CUSTODY-0001 §2.2: - AccordBinding: governance context per artifact - GovernedArtifact: registry with JSONB content + content_schema - CustodyTransition: append-only chain of custody - DeploymentState: current deployment per (artifact, target) - VerificationResult: continuous attestation records - ProjectorCheckpoint: Chronicle projector resume state All JSONB fields use Ecto :map type (Postgres JSONB). GIN indexes (jsonb_path_ops) on accord_terms and content columns. Partitioning notes for time-series tables (DBA applies in prod). Migrations renumbered to enforce FK dependency order (accord_bindings → governed_artifacts → dependents). Dev seed data (priv/repo/seeds.exs) creates nine governed artifacts matching the JSONB content examples in the design doc §2.3 (Intune profile, DNS zone, DSC MOF, YANG config, Helm values, JEA role, Conditional Access, TLS cert, OCI image) plus custody transitions, deployment states, and verification results. Verified: mix ecto.create + mix ecto.migrate + mix run seeds all pass; 9 artifacts in governed_artifacts table. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Tyler J King <tking@guildhouse.dev>
238 lines
8.1 KiB
Elixir
238 lines
8.1 KiB
Elixir
# Dev seed data for guildhall_ops_db.
|
|
# Matches the nine JSONB content examples in
|
|
# DESIGN-OPS-DB-CHAIN-OF-CUSTODY-0001 §2.3.
|
|
#
|
|
# Run with: mix run apps/guildhall_ops_db/priv/repo/seeds.exs
|
|
|
|
alias Guildhall.OpsDb.{
|
|
Repo,
|
|
AccordBinding,
|
|
GovernedArtifact,
|
|
CustodyTransition,
|
|
DeploymentState,
|
|
VerificationResult
|
|
}
|
|
|
|
now = DateTime.utc_now()
|
|
|
|
# ────────────────────────────────────────────────────────
|
|
# 1. Accord binding (shared by all artifacts below)
|
|
# ────────────────────────────────────────────────────────
|
|
accord =
|
|
Repo.insert!(%AccordBinding{
|
|
accord_cid: "sha256:dev-accord-example",
|
|
accord_name: "acme-saas-dev",
|
|
member_dids: ["did:web:guildhouse.dev:user:tking"],
|
|
witness_dids: ["did:web:guildhouse.dev:user:tking"],
|
|
ceremony_classes: ["SingleApproval"],
|
|
verification_interval_sec: 300,
|
|
chronicle_retention_days: 90,
|
|
effective_from: now,
|
|
accord_terms: %{
|
|
"name" => "Development Accord",
|
|
"tier_policy" => %{"default" => "a"}
|
|
}
|
|
})
|
|
|
|
# ────────────────────────────────────────────────────────
|
|
# 2. Governed artifacts — nine examples from §2.3
|
|
# ────────────────────────────────────────────────────────
|
|
artifacts = [
|
|
%{
|
|
cid: "sha256:intune-profile-example",
|
|
artifact_type: "intune_config_profile",
|
|
artifact_name: "Production Baseline",
|
|
artifact_runtime: "intune",
|
|
tier: "b",
|
|
content: %{
|
|
"@odata.type" => "#microsoft.graph.windows10GeneralConfiguration",
|
|
"displayName" => "Production Baseline",
|
|
"bitLockerEncryptDevice" => true,
|
|
"defenderRequireRealTimeMonitoring" => true,
|
|
"passwordMinimumLength" => 12,
|
|
"assignments" => [%{"groupId" => "corp-devices"}]
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:dns-zone-example",
|
|
artifact_type: "dns_zone",
|
|
artifact_name: "guildhouse.dev zone",
|
|
artifact_runtime: "zone",
|
|
tier: "c",
|
|
content: %{
|
|
"zone_apex" => "guildhouse.dev.",
|
|
"serial" => 2_026_041_701,
|
|
"records" => [
|
|
%{"name" => "@", "type" => "SOA", "rdata" => "ns1.guildhouse.dev. ..."},
|
|
%{"name" => "@", "type" => "NS", "rdata" => "ns1.guildhouse.dev."},
|
|
%{"name" => "auth", "type" => "A", "rdata" => "10.0.0.10"}
|
|
]
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:dsc-bitlocker-example",
|
|
artifact_type: "dsc_configuration",
|
|
artifact_name: "EnsureBitLockerEnabled",
|
|
artifact_runtime: "mof",
|
|
tier: "b",
|
|
content: %{
|
|
"instances" => [
|
|
%{
|
|
"class" => "MSFT_BitLockerResource",
|
|
"name" => "EnsureBitLockerEnabled",
|
|
"properties" => %{
|
|
"MountPoint" => "C:",
|
|
"PrimaryProtector" => "TpmProtector",
|
|
"AutoUnlock" => true
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:yang-running-config-example",
|
|
artifact_type: "restconf_config",
|
|
artifact_name: "edge-router-1 interfaces",
|
|
artifact_runtime: "json",
|
|
tier: "c",
|
|
content: %{
|
|
"ietf-interfaces:interfaces" => %{
|
|
"interface" => [
|
|
%{
|
|
"name" => "GigabitEthernet0/0",
|
|
"type" => "iana-if-type:ethernetCsmacd",
|
|
"enabled" => true
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:helm-values-example",
|
|
artifact_type: "helm_values",
|
|
artifact_name: "substrate-operator production values",
|
|
artifact_runtime: "values",
|
|
tier: "b",
|
|
content: %{
|
|
"bound_chart_cid" => "sha256:abc...",
|
|
"environment" => "production",
|
|
"image" => %{"digest" => "sha256:def..."},
|
|
"replicas" => 3
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:jea-application-role-example",
|
|
artifact_type: "jea_role_capability",
|
|
artifact_name: "Application-class JEA role",
|
|
artifact_runtime: "psrc",
|
|
tier: "c",
|
|
content: %{
|
|
"visible_cmdlets" => ["Get-Service", "Get-Process", "Test-DscConfiguration"],
|
|
"visible_providers" => ["FileSystem"],
|
|
"language_mode" => "ConstrainedLanguage",
|
|
"session_type" => "RestrictedRemoteServer"
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:conditional-access-example",
|
|
artifact_type: "entra_conditional_access",
|
|
artifact_name: "Require compliant device",
|
|
artifact_runtime: "json",
|
|
tier: "c",
|
|
content: %{
|
|
"displayName" => "Require compliant device for corp resources",
|
|
"conditions" => %{"users" => %{"includeGroups" => ["all-employees"]}},
|
|
"grantControls" => %{"builtInControls" => ["compliantDevice"]}
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:tls-keycloak-cert-example",
|
|
artifact_type: "tls_server_cert",
|
|
artifact_name: "keycloak.guildhouse.dev",
|
|
artifact_runtime: "x509",
|
|
tier: "b",
|
|
content: %{
|
|
"subject" => "CN=keycloak.guildhouse.dev",
|
|
"not_before" => "2026-04-17T00:00:00Z",
|
|
"not_after" => "2027-04-17T00:00:00Z",
|
|
"fingerprint_sha256" => "abc...",
|
|
"ct_log_refs" => []
|
|
}
|
|
},
|
|
%{
|
|
cid: "sha256:oci-image-example",
|
|
artifact_type: "oci_image",
|
|
artifact_name: "ghcr.io/guildhouse/substrate-operator",
|
|
artifact_runtime: "oci",
|
|
tier: "b",
|
|
content: %{
|
|
"image_reference" => "ghcr.io/guildhouse/substrate-operator",
|
|
"digest" => "sha256:a1b2c3...",
|
|
"architectures" => ["linux/amd64", "linux/arm64"],
|
|
"sbom_cid" => "sha256:..."
|
|
}
|
|
}
|
|
]
|
|
|
|
inserted =
|
|
Enum.map(artifacts, fn attrs ->
|
|
%GovernedArtifact{accord_binding_id: accord.id, human_authored: true}
|
|
|> GovernedArtifact.changeset(attrs)
|
|
|> Repo.insert!()
|
|
end)
|
|
|
|
# ────────────────────────────────────────────────────────
|
|
# 3. One custody transition per artifact (proposed → ceremony_open)
|
|
# ────────────────────────────────────────────────────────
|
|
Enum.each(inserted, fn artifact ->
|
|
Repo.insert!(%CustodyTransition{
|
|
governed_artifact_id: artifact.id,
|
|
sequence_number: 1,
|
|
from_state: "proposed",
|
|
to_state: "ceremony_open",
|
|
actor_did: "did:web:guildhouse.dev:user:tking",
|
|
ceremony_id: "ceremony-dev-#{artifact.id}",
|
|
witness_sigs: [],
|
|
transitioned_at: now
|
|
})
|
|
end)
|
|
|
|
# ────────────────────────────────────────────────────────
|
|
# 4. Mix of deployment_states (healthy / drifted)
|
|
# ────────────────────────────────────────────────────────
|
|
inserted
|
|
|> Enum.with_index()
|
|
|> Enum.each(fn {artifact, idx} ->
|
|
drift = if rem(idx, 3) == 0, do: "drift", else: "match"
|
|
|
|
Repo.insert!(%DeploymentState{
|
|
governed_artifact_id: artifact.id,
|
|
target_kind: "dev-cluster",
|
|
target_identifier: "hetzner-talos",
|
|
deployed_cid: artifact.cid,
|
|
desired_cid: artifact.cid,
|
|
last_deployed_at: now,
|
|
last_reconciled_at: now,
|
|
drift_status: drift
|
|
})
|
|
end)
|
|
|
|
# ────────────────────────────────────────────────────────
|
|
# 5. Recent verification results
|
|
# ────────────────────────────────────────────────────────
|
|
Enum.each(inserted, fn artifact ->
|
|
Repo.insert!(%VerificationResult{
|
|
governed_artifact_id: artifact.id,
|
|
verified_cid: artifact.cid,
|
|
target_kind: "dev-cluster",
|
|
target_identifier: "hetzner-talos",
|
|
layer: "layer1",
|
|
verdict: "match",
|
|
verified_at: now,
|
|
verifier_did: "did:web:guildhouse.dev:verifier:local",
|
|
verifier_infrastructure: "local",
|
|
evidence: %{"method" => "seed_data"}
|
|
})
|
|
end)
|
|
|
|
IO.puts("Seeded #{length(inserted)} governed artifacts under Accord #{accord.accord_name}.")
|