Skip to main content

systemprompt_cli/commands/admin/access_control/
mod.rs

1//! `admin access-control` subcommand: inspect and promote live RBAC rules.
2//!
3//! Exposes [`AccessControlCommands`] for exporting the current role rules as a
4//! committable YAML baseline and linting the live access-control tables for
5//! unknown entities or unreachable rules.
6
7mod export;
8mod lint;
9
10use anyhow::Result;
11use clap::{Args, Subcommand};
12
13use crate::CliConfig;
14use crate::shared::{CommandOutput, render_result};
15
16#[derive(Debug, Clone, Copy, Subcommand)]
17pub enum AccessControlCommands {
18    #[command(
19        about = "Print current role rules as a YAML snippet for promotion to the committed \
20                 baseline"
21    )]
22    ExportYaml(ExportYamlArgs),
23
24    #[command(
25        about = "Lint the live access-control tables for unknown entities and unreachable rules; \
26                 exits non-zero on findings"
27    )]
28    Lint(LintArgs),
29}
30
31#[derive(Debug, Clone, Copy, Args)]
32pub struct ExportYamlArgs;
33
34#[derive(Debug, Clone, Copy, Args)]
35pub struct LintArgs;
36
37pub async fn execute(cmd: AccessControlCommands, config: &CliConfig) -> Result<()> {
38    match cmd {
39        AccessControlCommands::ExportYaml(args) => {
40            let result = export::run(args, config).await?;
41            render_result(&result);
42            Ok(())
43        },
44        AccessControlCommands::Lint(args) => {
45            let (text, exit_nonzero) = lint::run(args, config).await?;
46            let result = CommandOutput::text_titled("Access-control lint", text);
47            render_result(&result);
48            if exit_nonzero {
49                anyhow::bail!("access-control lint failed; see report above");
50            }
51            Ok(())
52        },
53    }
54}