orchestrator_security/
lib.rs1#![cfg_attr(
8 not(test),
9 deny(clippy::panic, clippy::unwrap_used, clippy::expect_used)
10)]
11#![deny(missing_docs)]
12
13pub mod secret_key_audit;
15pub mod secret_key_lifecycle;
17pub mod secret_store_crypto;
19pub mod secure_files;
21
22#[cfg(test)]
28pub(crate) fn init_test_schema(db_path: &std::path::Path) -> anyhow::Result<()> {
29 let conn = open_conn(db_path)?;
30 conn.execute_batch(
31 r#"
32 CREATE TABLE IF NOT EXISTS schema_version (
33 version INTEGER NOT NULL
34 );
35 INSERT INTO schema_version (version) VALUES (99);
36
37 CREATE TABLE IF NOT EXISTS secret_keys (
38 key_id TEXT PRIMARY KEY,
39 state TEXT NOT NULL,
40 fingerprint TEXT NOT NULL,
41 file_path TEXT NOT NULL,
42 created_at TEXT NOT NULL,
43 activated_at TEXT,
44 rotated_out_at TEXT,
45 retired_at TEXT,
46 revoked_at TEXT
47 );
48 CREATE INDEX IF NOT EXISTS idx_secret_keys_state ON secret_keys(state);
49
50 CREATE TABLE IF NOT EXISTS secret_key_audit (
51 id INTEGER PRIMARY KEY AUTOINCREMENT,
52 event_kind TEXT NOT NULL,
53 key_id TEXT NOT NULL,
54 key_fingerprint TEXT NOT NULL,
55 actor TEXT NOT NULL,
56 detail_json TEXT NOT NULL DEFAULT '{}',
57 created_at TEXT NOT NULL
58 );
59 CREATE INDEX IF NOT EXISTS idx_secret_key_audit_created ON secret_key_audit(created_at);
60 CREATE INDEX IF NOT EXISTS idx_secret_key_audit_key_id ON secret_key_audit(key_id, created_at);
61
62 CREATE TABLE IF NOT EXISTS resources (
63 kind TEXT NOT NULL,
64 project TEXT NOT NULL,
65 name TEXT NOT NULL,
66 api_version TEXT NOT NULL,
67 spec_json TEXT NOT NULL,
68 metadata_json TEXT NOT NULL,
69 generation INTEGER NOT NULL DEFAULT 1,
70 created_at TEXT NOT NULL,
71 updated_at TEXT NOT NULL,
72 PRIMARY KEY (kind, project, name)
73 );
74
75 CREATE TABLE IF NOT EXISTS resource_versions (
76 id INTEGER PRIMARY KEY AUTOINCREMENT,
77 kind TEXT NOT NULL,
78 project TEXT NOT NULL,
79 name TEXT NOT NULL,
80 spec_json TEXT NOT NULL,
81 metadata_json TEXT NOT NULL DEFAULT '{}',
82 version INTEGER NOT NULL,
83 author TEXT NOT NULL DEFAULT '',
84 created_at TEXT NOT NULL
85 );
86 CREATE INDEX IF NOT EXISTS idx_resource_versions_lookup
87 ON resource_versions(kind, project, name, version DESC);
88 "#,
89 )?;
90 Ok(())
91}
92
93pub(crate) fn now_ts() -> String {
95 chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true)
96}
97
98pub(crate) fn open_conn(db_path: &std::path::Path) -> anyhow::Result<rusqlite::Connection> {
100 use anyhow::Context;
101 let conn = rusqlite::Connection::open(db_path).context("failed to open sqlite db")?;
102 conn.busy_timeout(std::time::Duration::from_millis(5000))
103 .context("failed to set sqlite busy timeout")?;
104 conn.execute_batch("PRAGMA foreign_keys = ON;")
105 .context("failed to configure sqlite pragmas")?;
106 Ok(conn)
107}