use authzd::EntitiesRepository; use authzd::gitlab::Api; use clap::{Parser, Subcommand}; #[derive(Parser, Debug)] #[command( author, version, about = "Authorization CLI for managing Cedar entities and policies" )] struct Args { #[command(subcommand)] command: Commands, } #[derive(Subcommand, Debug)] enum Commands { /// Generate entities from GitLab API Generate { /// Project ID or path (e.g., gitlab-org/gitlab) #[arg(short, long)] project: String, /// Output file path #[arg(short, long, default_value = "entities.json")] output: String, /// GitLab API token #[arg(short, long, env = "GITLAB_TOKEN")] token: String, /// GitLab instance URL #[arg( short = 'H', long, env = "GITLAB_HOST", default_value = "https://gitlab.com" )] host: String, }, Server { /// Address to bind to #[arg(short, long, env = "BIND_ADDR", default_value = "127.0.0.1:50051")] addr: String, }, } #[tokio::main] async fn main() -> Result<(), Box> { let args = Args::parse(); match args.command { Commands::Generate { project, output, token, host, } => { let repository = EntitiesRepository::new(Api::new(token, host)); let entities = repository.all(project).await?; EntitiesRepository::is_valid(&entities)?; let json = serde_json::to_string_pretty(&entities)?; std::fs::write(&output, json)?; println!( "Successfully generated {} entities to {}", entities.len(), output ); } Commands::Server { addr } => { tracing_subscriber::fmt() .json() .with_ansi(false) .with_current_span(true) .with_file(true) .with_level(false) .with_line_number(true) .with_max_level(tracing::Level::INFO) .with_span_list(true) .with_target(false) .with_thread_ids(false) .with_thread_names(false) .init(); tracing::info!(address = %addr, "Starting"); authzd::authorization::Server::new(authzd::authorization::CedarAuthorizer::default())? .serve(addr.parse().unwrap()) .await?; } } Ok(()) }