systemprompt_cli/commands/admin/
mod.rs1pub mod access_control;
12pub mod agents;
13pub mod bootstrap;
14pub mod bridge;
15pub mod config;
16pub mod identity;
17pub mod keys;
18pub mod session;
19pub mod setup;
20pub mod users;
21
22use anyhow::Result;
23use clap::Subcommand;
24
25use crate::context::CommandContext;
26use crate::shared::render_result;
27
28#[derive(Debug, Subcommand)]
29pub enum AdminCommands {
30 #[command(subcommand, about = "User management and IP banning")]
31 Users(users::UsersCommands),
32
33 #[command(subcommand, about = "Agent management")]
34 Agents(agents::AgentsCommands),
35
36 #[command(subcommand, about = "Configuration management and rate limits")]
37 Config(config::ConfigCommands),
38
39 #[command(about = "Interactive setup wizard for local development environment")]
40 Setup(setup::SetupArgs),
41
42 #[command(
43 about = "Idempotently ensure the system admin user exists with the admin role. Required \
44 by every install recipe before services start. Note: the admin ROLE only — \
45 deployments that derive platform admin from organization membership grant that \
46 half themselves (at boot, or via their own tooling)."
47 )]
48 Bootstrap(bootstrap::BootstrapArgs),
49
50 #[command(subcommand, about = "Manage CLI session and profile switching")]
51 Session(session::SessionCommands),
52
53 #[command(
54 subcommand,
55 about = "Bridge helper enrollment (device certs, exchange codes)"
56 )]
57 Bridge(bridge::BridgeCommands),
58
59 #[command(
60 subcommand,
61 name = "access-control",
62 about = "Access-control baseline operations (DB → YAML export)"
63 )]
64 AccessControl(access_control::AccessControlCommands),
65
66 #[command(
67 subcommand,
68 about = "RSA signing-key generation for the federated JWT plane"
69 )]
70 Keys(keys::KeysCommands),
71
72 #[command(
73 subcommand,
74 about = "Replica identity secrets shared by every node of a deployment"
75 )]
76 Identity(identity::IdentityCommands),
77}
78
79pub async fn execute(cmd: AdminCommands, ctx: &CommandContext) -> Result<()> {
80 if ctx.is_database_scoped()
81 && !matches!(cmd, AdminCommands::Users(_) | AdminCommands::Session(_))
82 {
83 return Err(crate::shared::database_scoped_command_error());
84 }
85
86 match cmd {
87 AdminCommands::Users(cmd) => users::execute(cmd, ctx).await,
88 AdminCommands::Agents(cmd) => Box::pin(agents::execute(cmd, ctx)).await,
89 AdminCommands::Config(cmd) => config::execute(cmd, ctx).await,
90 AdminCommands::Setup(args) => {
91 let result = Box::pin(setup::execute(args, ctx)).await?;
92 render_result(&result, &ctx.cli);
93 Ok(())
94 },
95 AdminCommands::Bootstrap(args) => {
96 let result = bootstrap::execute(args, &ctx.cli).await?;
97 render_result(&result, &ctx.cli);
98 Ok(())
99 },
100 AdminCommands::Session(cmd) => session::execute(cmd, ctx).await,
101 AdminCommands::Bridge(cmd) => bridge::execute(cmd, ctx).await,
102 AdminCommands::AccessControl(cmd) => access_control::execute(cmd, ctx).await,
103 AdminCommands::Keys(cmd) => keys::execute(cmd, ctx).await,
104 AdminCommands::Identity(cmd) => identity::execute(cmd, ctx),
105 }
106}