Private
Public Access
1
0

feat: add self-enrollment workflow for automated PKI provisioning

- Phase 1: CLI args (--enroll flag), enroll module skeleton, config support
- Phase 2: Registration request, polling loop (24h timeout), main.rs integration
- Phase 3: PKI extraction, atomic cert writing, whitelist auto-append, mTLS transition
- Phase 4: E2E test suite, README/DEPLOYMENT docs, CI pipeline
- Phase 5: SPEC.md, API_DOCUMENTATION.md, CHANGELOG.md, ROADMAP.md sync

Security review: APPROVED (0 critical, 0 high findings)
Cross-distro compatible: Debian/Ubuntu, RHEL/CentOS/Fedora, Alpine, Arch Linux
This commit is contained in:
2026-05-17 05:30:42 +00:00
parent 949cbb2632
commit 75ec2b8e3c
24 changed files with 4610 additions and 70 deletions

View File

@ -24,6 +24,7 @@ use tracing::{error, info, warn};
use linux_patch_api::api::{configure_api_routes, configure_health_route};
use linux_patch_api::auth::{mtls, MtlsMiddleware, WhitelistManager};
use linux_patch_api::packages::create_backend;
use linux_patch_api::enroll;
use linux_patch_api::{init_logging, AppConfig, JobManager};
/// Linux Patch API CLI arguments
@ -39,6 +40,10 @@ struct Args {
/// Enable verbose logging
#[arg(short, long)]
verbose: bool,
/// Enroll with manager at URL (skips mTLS startup, runs enrollment flow only)
#[arg(long, help = "Enroll with manager at URL (skips mTLS startup, runs enrollment flow only)")]
enroll: Option<String>,
}
#[actix_web::main]
@ -71,6 +76,20 @@ async fn main() -> Result<()> {
}
};
// Handle enrollment mode - runs before server startup
if let Some(ref manager_url) = args.enroll {
info!(manager_url = manager_url, "Enrollment mode activated - running enrollment flow before server startup");
match enroll::run_enrollment(manager_url, &config).await {
Ok(()) => {
info!("Enrollment complete - proceeding to server startup");
}
Err(e) => {
error!(error = %e, "Enrollment failed - shutting down");
return Err(anyhow::anyhow!("Enrollment failed: {}", e));
}
}
}
// Initialize job manager
let job_manager = JobManager::new(config.jobs.max_concurrent, config.jobs.timeout_minutes)?;
info!(