feat: push Ed25519 public key to tenant server containers

DockerTenantProvisioner now injects CAMELEER_SERVER_LICENSE_PUBLICKEY
env var on provisioned server containers, enabling cryptographic
license validation. SigningKeyService passed through auto-config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-26 17:36:06 +02:00
parent 6c3f21d4db
commit 4dea1c6764
2 changed files with 8 additions and 3 deletions

View File

@@ -21,9 +21,12 @@ public class DockerTenantProvisioner implements TenantProvisioner {
private final DockerClient docker; private final DockerClient docker;
private final ProvisioningProperties props; private final ProvisioningProperties props;
private final net.siegeln.cameleer.saas.license.SigningKeyService signingKeyService;
public DockerTenantProvisioner(DockerClientConfig config, ProvisioningProperties props) { public DockerTenantProvisioner(DockerClientConfig config, ProvisioningProperties props,
net.siegeln.cameleer.saas.license.SigningKeyService signingKeyService) {
this.props = props; this.props = props;
this.signingKeyService = signingKeyService;
DockerHttpClient httpClient = new ZerodepDockerHttpClient.Builder() DockerHttpClient httpClient = new ZerodepDockerHttpClient.Builder()
.dockerHost(config.getDockerHost()) .dockerHost(config.getDockerHost())
.maxConnections(10) .maxConnections(10)
@@ -223,6 +226,7 @@ public class DockerTenantProvisioner implements TenantProvisioner {
"CAMELEER_SERVER_SECURITY_OIDC_AUDIENCE=https://api.cameleer.local", "CAMELEER_SERVER_SECURITY_OIDC_AUDIENCE=https://api.cameleer.local",
"CAMELEER_SERVER_SECURITY_CORSALLOWEDORIGINS=" + props.corsOrigins(), "CAMELEER_SERVER_SECURITY_CORSALLOWEDORIGINS=" + props.corsOrigins(),
"CAMELEER_SERVER_LICENSE_TOKEN=" + req.licenseToken(), "CAMELEER_SERVER_LICENSE_TOKEN=" + req.licenseToken(),
"CAMELEER_SERVER_LICENSE_PUBLICKEY=" + signingKeyService.getPublicKeyBase64(),
"CAMELEER_SERVER_RUNTIME_ENABLED=true", "CAMELEER_SERVER_RUNTIME_ENABLED=true",
"CAMELEER_SERVER_RUNTIME_SERVERURL=http://" + name + ":8081", "CAMELEER_SERVER_RUNTIME_SERVERURL=http://" + name + ":8081",
"CAMELEER_SERVER_RUNTIME_ROUTINGDOMAIN=" + props.publicHost(), "CAMELEER_SERVER_RUNTIME_ROUTINGDOMAIN=" + props.publicHost(),

View File

@@ -2,6 +2,7 @@ package net.siegeln.cameleer.saas.provisioning;
import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.DockerClientConfig;
import net.siegeln.cameleer.saas.license.SigningKeyService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -17,13 +18,13 @@ public class TenantProvisionerAutoConfig {
private static final Logger log = LoggerFactory.getLogger(TenantProvisionerAutoConfig.class); private static final Logger log = LoggerFactory.getLogger(TenantProvisionerAutoConfig.class);
@Bean @Bean
TenantProvisioner tenantProvisioner(ProvisioningProperties props) { TenantProvisioner tenantProvisioner(ProvisioningProperties props, SigningKeyService signingKeyService) {
if (Files.exists(Path.of("/var/run/docker.sock"))) { if (Files.exists(Path.of("/var/run/docker.sock"))) {
log.info("Docker socket detected — enabling Docker tenant provisioner"); log.info("Docker socket detected — enabling Docker tenant provisioner");
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("unix:///var/run/docker.sock") .withDockerHost("unix:///var/run/docker.sock")
.build(); .build();
return new DockerTenantProvisioner(config, props); return new DockerTenantProvisioner(config, props, signingKeyService);
} }
log.info("No Docker socket — tenant provisioning disabled"); log.info("No Docker socket — tenant provisioning disabled");
return new DisabledTenantProvisioner(); return new DisabledTenantProvisioner();