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//!
7//! Copyright (c) systemprompt.io — Business Source License 1.1.
8//! See <https://systemprompt.io> for licensing details.
9
10pub mod export;
11mod lint;
12
13use anyhow::Result;
14use clap::{Args, Subcommand};
15
16use crate::context::CommandContext;
17use crate::shared::{CommandOutput, render_result};
18
19#[derive(Debug, Clone, Copy, Subcommand)]
20pub enum AccessControlCommands {
21    #[command(
22        about = "Print current role rules as a YAML snippet for promotion to the committed \
23                 baseline"
24    )]
25    ExportYaml(ExportYamlArgs),
26
27    #[command(
28        about = "Lint the live access-control tables for unknown entities and unreachable rules; \
29                 exits non-zero on findings"
30    )]
31    Lint(LintArgs),
32}
33
34#[derive(Debug, Clone, Copy, Args)]
35pub struct ExportYamlArgs;
36
37#[derive(Debug, Clone, Copy, Args)]
38pub struct LintArgs;
39
40pub async fn execute(cmd: AccessControlCommands, ctx: &CommandContext) -> Result<()> {
41    match cmd {
42        AccessControlCommands::ExportYaml(args) => {
43            let result = export::run(args, &ctx.cli).await?;
44            render_result(&result, &ctx.cli);
45            Ok(())
46        },
47        AccessControlCommands::Lint(args) => {
48            let (text, exit_nonzero) = lint::run(args, &ctx.cli).await?;
49            let result = CommandOutput::text_titled("Access-control lint", text);
50            render_result(&result, &ctx.cli);
51            if exit_nonzero {
52                anyhow::bail!("access-control lint failed; see report above");
53            }
54            Ok(())
55        },
56    }
57}