Skip to content

Commit 8f5c792

Browse files
andrasbacsaiclaude
andcommitted
refactor(builder): replace runtime JWT signing with pre-minted bearer
Builder now reads a pre-minted JWT from BUILDER_JWT_PATH (default /etc/coolify/builder-jwt) instead of loading an EC private key and signing its own token. Mirrors coold's model where central mints the bearer, avoiding per-builder private key distribution. Also corrects the default BUILDER_BROKER_URL port from 6443 (coold stream) to 6444 (builder stream). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cb3a3f4 commit 8f5c792

4 files changed

Lines changed: 12 additions & 43 deletions

File tree

builder/src/auth.rs

Lines changed: 0 additions & 30 deletions
This file was deleted.

builder/src/config.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ pub struct Config {
1212
#[arg(long, env = "BUILDER_ID")]
1313
pub builder_id: String,
1414

15-
/// Broker gRPC address to dial.
16-
#[arg(long, env = "BUILDER_BROKER_URL", default_value = "http://127.0.0.1:6443")]
15+
/// Broker gRPC address to dial (builder-stream listener, default :6444).
16+
#[arg(long, env = "BUILDER_BROKER_URL", default_value = "http://127.0.0.1:6444")]
1717
pub broker_url: String,
1818

19-
/// PEM-encoded EC/RSA private key for signing the builder JWT.
20-
#[arg(long, env = "BUILDER_JWT_PRIVATE_KEY_PATH", default_value = "/etc/coolify/builder.key")]
21-
pub jwt_private_key_path: std::path::PathBuf,
19+
/// Path to the pre-minted ES256 bearer JWT signed by central (aud="builder").
20+
#[arg(long, env = "BUILDER_JWT_PATH", default_value = "/etc/coolify/builder-jwt")]
21+
pub jwt_path: std::path::PathBuf,
2222

23-
/// Loaded private key — populated at startup.
23+
/// Loaded bearer token — populated at startup.
2424
#[clap(skip)]
25-
pub jwt_private_key: String,
25+
pub jwt: String,
2626

2727
/// Directory for temporary build work dirs.
2828
#[arg(long, env = "BUILDER_WORK_DIR", default_value = "/var/lib/coolify-builder/work")]
@@ -40,9 +40,10 @@ pub struct Config {
4040
impl Config {
4141
pub async fn load() -> anyhow::Result<Self> {
4242
let mut cfg = Self::parse();
43-
cfg.jwt_private_key = tokio::fs::read_to_string(&cfg.jwt_private_key_path)
43+
cfg.jwt = tokio::fs::read_to_string(&cfg.jwt_path)
4444
.await
45-
.map_err(|e| anyhow::anyhow!("read JWT privkey {}: {e}", cfg.jwt_private_key_path.display()))?;
45+
.map_err(|e| anyhow::anyhow!("read JWT from {}: {e}", cfg.jwt_path.display()))?;
46+
cfg.jwt = cfg.jwt.trim().to_owned();
4647
tokio::fs::create_dir_all(&cfg.work_dir).await?;
4748
Ok(cfg)
4849
}

builder/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
mod auth;
21
mod config;
32
mod executor;
43
mod progress;

builder/src/stream.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use coolify_proto::builder::v1::{
99
BuilderHello,
1010
};
1111

12-
use crate::{auth, config::Config};
12+
use crate::config::Config;
1313

1414
const RECONNECT_DELAY_SECS: u64 = 5;
1515

@@ -33,8 +33,7 @@ async fn connect_and_run(config: &Config) -> Result<()> {
3333
.connect()
3434
.await?;
3535

36-
let token = auth::sign_jwt(&config.builder_id, &config.jwt_private_key)?;
37-
let bearer: MetadataValue<_> = format!("Bearer {token}").parse()?;
36+
let bearer: MetadataValue<_> = format!("Bearer {}", config.jwt).parse()?;
3837

3938
let mut client = BuilderClient::with_interceptor(channel, move |mut req: tonic::Request<()>| {
4039
req.metadata_mut().insert("authorization", bearer.clone());

0 commit comments

Comments
 (0)