fix: restrict key.pem file permissions to 0600 (owner-only)
All checks were successful
CI / build (push) Successful in 1m6s
CI / docker (push) Successful in 34s

All private key writes now use writeAtomicRestricted which sets POSIX
owner-read/write permissions after writing. Gracefully skips on
non-POSIX filesystems (Windows dev).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-10 19:49:07 +02:00
parent 3ae8fa18cd
commit 0fe084bcb2

View File

@@ -113,7 +113,7 @@ public class DockerCertificateManager implements CertificateManager {
Files.createDirectories(stagedDir);
writeAtomic(stagedDir.resolve("cert.pem"), certPem);
writeAtomic(stagedDir.resolve("key.pem"), decryptedKeyPem);
writeAtomicRestricted(stagedDir.resolve("key.pem"), decryptedKeyPem);
if (caBundlePem != null && caBundlePem.length > 0) {
writeAtomic(stagedDir.resolve("ca.pem"), caBundlePem);
} else {
@@ -153,7 +153,7 @@ public class DockerCertificateManager implements CertificateManager {
// Move staged -> active (atomic swap via .wip)
writeAtomic(certsDir.resolve("cert.pem"), Files.readAllBytes(stagedDir.resolve("cert.pem")));
writeAtomic(certsDir.resolve("key.pem"), Files.readAllBytes(stagedDir.resolve("key.pem")));
writeAtomicRestricted(certsDir.resolve("key.pem"), Files.readAllBytes(stagedDir.resolve("key.pem")));
if (Files.exists(stagedDir.resolve("ca.pem"))) {
writeAtomic(certsDir.resolve("ca.pem"), Files.readAllBytes(stagedDir.resolve("ca.pem")));
}
@@ -187,7 +187,7 @@ public class DockerCertificateManager implements CertificateManager {
// Prev -> active
writeAtomic(certsDir.resolve("cert.pem"), Files.readAllBytes(prevDir.resolve("cert.pem")));
writeAtomic(certsDir.resolve("key.pem"), Files.readAllBytes(prevDir.resolve("key.pem")));
writeAtomicRestricted(certsDir.resolve("key.pem"), Files.readAllBytes(prevDir.resolve("key.pem")));
if (Files.exists(prevDir.resolve("ca.pem"))) {
writeAtomic(certsDir.resolve("ca.pem"), Files.readAllBytes(prevDir.resolve("ca.pem")));
} else {
@@ -355,6 +355,23 @@ public class DockerCertificateManager implements CertificateManager {
Files.move(wip, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
}
/** Write with owner-only permissions (0600) for private key files. */
private void writeAtomicRestricted(Path target, byte[] data) throws IOException {
writeAtomic(target, data);
try {
var posix = Files.getFileAttributeView(target, java.nio.file.attribute.PosixFileAttributeView.class);
if (posix != null) {
posix.setPermissions(java.util.Set.of(
java.nio.file.attribute.PosixFilePermission.OWNER_READ,
java.nio.file.attribute.PosixFilePermission.OWNER_WRITE
));
}
} catch (UnsupportedOperationException e) {
// Non-POSIX filesystem (e.g., Windows) — skip
log.debug("Cannot set POSIX permissions on {}: {}", target, e.getMessage());
}
}
private void moveFile(Path source, Path target) throws IOException {
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
}