bascule-workspace/bascule-core/src/audit.rs
Tyler King b1865a0627 initial: bascule v0.1.0
Bascule shell runtime workspace — governed shell access layer
for Substrate/Guildhouse FFC deployments.

Crates:
- bascule-agent: node agent with SSH server + command filtering
- bascule-core: audit, grant engine, ceremony types, session
- bascule-filter-core: log line filtering (stdio protocol)
- bascule-gateway: OIDC auth, session management, SAT validation
- bascule-node-agent: k8s DaemonSet agent (pod watcher, BPF manager)
- bascule-proto: protobuf definitions
- bascule-shell: governed SSH shell (commands, elevation, REPL)
- bascule-tail: chronicle log tail + fanout
- ceremony-engine: ceremony lifecycle (6 types + request/resolution)

172 tests passing.
Implements SBS-SPEC-0001 shell model.
Reference impl for SPEC-SHELLOPS-0001 Layer 1 (root shell).
2026-03-18 16:40:48 -04:00

92 lines
2.4 KiB
Rust

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::command::{ChangeClassification, CommandRecord, ResourceRef};
use crate::session::OperatorIdentity;
/// A complete audit event for a command execution.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEvent {
pub event_id: Uuid,
pub session_id: Uuid,
pub operator_identity: OperatorIdentity,
pub timestamp: DateTime<Utc>,
pub command: CommandRecord,
pub classification: ChangeClassification,
pub policy_decision: PolicyDecision,
pub execution_result: ExecutionResult,
pub target_resources: Vec<ResourceRef>,
pub target_profile_hash: Option<String>,
}
/// The result of policy evaluation for a command.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyDecision {
pub allowed: bool,
pub policy_bundle_hash: String,
pub accord_version: String,
pub evaluation_duration_ms: u32,
pub denied_reason: Option<String>,
}
impl PolicyDecision {
/// Create an allow-all stub decision (used in Phase 1 when OPA is not deployed).
pub fn allow_all_stub() -> Self {
Self {
allowed: true,
policy_bundle_hash: "stub".into(),
accord_version: "none".into(),
evaluation_duration_ms: 0,
denied_reason: None,
}
}
}
/// The result of executing a command.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionResult {
pub status: ExecutionStatus,
pub summary: String,
pub resources_affected: u32,
pub mutations_applied: u32,
}
/// Execution outcome.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionStatus {
Success,
Denied,
Error,
Timeout,
}
impl ExecutionResult {
pub fn success(summary: String) -> Self {
Self {
status: ExecutionStatus::Success,
summary,
resources_affected: 0,
mutations_applied: 0,
}
}
pub fn denied(reason: String) -> Self {
Self {
status: ExecutionStatus::Denied,
summary: reason,
resources_affected: 0,
mutations_applied: 0,
}
}
pub fn error(msg: String) -> Self {
Self {
status: ExecutionStatus::Error,
summary: msg,
resources_affected: 0,
mutations_applied: 0,
}
}
}