TLS everywhere
Produktions-sicher heißt TLS auf jeder Netzwerkoberfläche. Jede Komponente des Frameworks hat ihre eigene TLS-Konfiguration; diese Seite ist der Katalog, wo TLS zu aktivieren ist und welches Cert-Material jede Komponente braucht.
Cluster-Transport
Abschnitt betitelt „Cluster-Transport“import { TcpTransport, Cluster, ClusterOptions } from 'actor-ts';
const transport = new TcpTransport(self, log, { cert: fs.readFileSync('./tls/cluster.crt'), key: fs.readFileSync('./tls/cluster.key'), ca: fs.readFileSync('./tls/ca.crt'), rejectUnauthorized: true,});
const clusterOptions = ClusterOptions.create() .withHost(host) .withPort(port) .withSeeds(seeds) .withTransport(transport);await Cluster.join(system, clusterOptions);Mutually authenticated TLS zwischen Cluster-Nodes. Siehe Cluster-Sicherheit für die vollständige Diskussion.
Jedes Feld hier nimmt das Zertifikatsmaterial selbst entgegen, niemals einen Pfad darauf — deshalb liest das Beispiel die Dateien selbst ein. Nichts im Transport greift auf das Dateisystem zu, und weder Bun noch Node noch Deno akzeptiert in diesen Feldern einen Dateinamen.
cert und key sind auf einem Listener nur gemeinsam gültig.
Ein tls-Objekt mit nur einem von beiden brachte den Listener
bisher zu dem Schluss „kein TLS”, und er lauschte im Klartext —
während dieselbe Konfiguration weiterhin über TLS hinauswählte. Der
Cluster bildete sich also, und nichts sah falsch aus. Diese
Kombination wird jetzt beim Bind abgelehnt; ein so
fehlkonfigurierter Knoten degradiert damit nicht mehr still,
sondern scheitert laut.
Nicht überspringen — auch in internen Netzwerken gilt Defense in Depth.
HTTP-Server
Abschnitt betitelt „HTTP-Server“import { HttpExtensionId } from 'actor-ts';
const http = system.extension(HttpExtensionId);
await http.newServerAt('0.0.0.0', 8443) .useBackend(new FastifyBackend({ https: { cert: fs.readFileSync('./tls/http.crt'), key: fs.readFileSync('./tls/http.key'), }, })) .bind(routes);Für HTTPS auf der Anwendungsebene. Oft am Load Balancer terminiert stattdessen — in K8s übernimmt Service/Ingress TLS, die App spricht intern Plain-HTTP. Wählen je nach Form deiner Infrastruktur.
Management-Endpunkt
Abschnitt betitelt „Management-Endpunkt“import { managementRoutes, FastifyBackend } from 'actor-ts';
const { routes } = managementRoutes(system, cluster);
// TLS is a property of the HTTP backend — Fastify's `https` option.const tlsBackend = new FastifyBackend({ https: { cert: fs.readFileSync('./tls/mgmt.crt'), key: fs.readFileSync('./tls/mgmt.key'), },});await system.http(8558, { backend: tlsBackend }).bind(routes);Der Management-Server ist standardmäßig nur intern — aber TLS hilft trotzdem:
- Schützt vor lateraler Bewegung in einem kompromittierten Netzwerk.
- Wird von manchen Compliance-Regimen unabhängig von der Netzwerk-Topologie verlangt.
Broker-Actors
Abschnitt betitelt „Broker-Actors“Jeder Broker-Actor hat seine eigenen TLS-Knöpfe:
const kafkaOptions = KafkaOptions.create() .withBrokers(['kafka-1:9093']) .withSsl(true) .withSasl({ mechanism: 'scram-sha-512', username: process.env.KAFKA_USER!, password: process.env.KAFKA_PASS!, });new KafkaActor(kafkaOptions);const mqttOptions = MqttOptions.create() .withBrokerUrl('mqtts://mqtt.example.com:8883') .withCredentials(process.env.MQTT_USER, process.env.MQTT_PASS);new MqttActor(mqttOptions);mqtts://-URL-Schema. Cert-Verifizierung folgt den Defaults des
zugrundeliegenden mqtt-Pakets.
const amqpOptions = AmqpOptions.create().withUrl('amqps://rabbitmq.example.com:5671');new AmqpActor(amqpOptions); // amqplib nutzt URL-Parameter für die TLS-Konfigurationamqps://-URL-Schema.
const natsOptions = NatsOptions.create().withServers(['nats://nats.example.com:4222']);new NatsActor(natsOptions); // mTLS-Cert-Material (ca / cert / key) wird an die zugrundeliegende // nats-Verbindung übergeben — z. B. via Connect-Optionen / URL des Treibers.mTLS via das tls-Objekt — üblich für Produktions-NATS.
Redis Streams
Abschnitt betitelt „Redis Streams“const redisStreamsOptions = RedisStreamsOptions.create().withUrl('rediss://redis.example.com:6380');new RedisStreamsActor(redisStreamsOptions); // das `rediss://`-Schema aktiviert TLS auf der Verbindungrediss://-URL-Schema (beachte das doppelte s).
const grpcClientOptions = GrpcClientOptions.create() .withEndpoint('orders.example.com:50051') .withCredentials({ kind: 'tls', rootCerts: fs.readFileSync('./tls/ca.crt'), });new GrpcClientActor(grpcClientOptions);Für Mutual TLS cert + key ergänzen.
WebSocket
Abschnitt betitelt „WebSocket“const webSocketClientOptions = WebsocketClientOptions.create().withUrl('wss://realtime.example.com/feed');new WebsocketClientActor(webSocketClientOptions);wss://-URL-Schema. Cert-Verifizierung folgt den TLS-Defaults der
Runtime.
Persistence-Backends
Abschnitt betitelt „Persistence-Backends“Nicht zutreffend — lokaler Datei-Zugriff. TLS nicht anwendbar.Cassandra
Abschnitt betitelt „Cassandra“const cassandraJournalOptions = CassandraJournalOptions.create() .withContactPoints(['cass-1.example.com:9042']) .withClient(clientWithMtls);new CassandraJournal(cassandraJournalOptions); // mTLS-Cert-Material (cert / key / ca) wird auf dem via withClient() // übergebenen cassandra-driver-Client konfiguriertCassandra-Cluster laufen in Produktion typischerweise mit mTLS.
Object Storage
Abschnitt betitelt „Object Storage“const s3ObjectStorageOptions = S3ObjectStorageOptions.create().withRegion('eu-west-1');const objectStorageDurableStateStoreOptions = ObjectStorageDurableStateStoreOptions.create().withBackend(new S3ObjectStorageBackend(s3ObjectStorageOptions));new ObjectStorageDurableStateStore(objectStorageDurableStateStoreOptions); // S3 nutzt per Default HTTPSCloud-Object-Storage (S3, GCS, Azure Blob) nutzt immer TLS. Keine Konfiguration nötig außer dem Endpoint.
Cert-Provisionierung
Abschnitt betitelt „Cert-Provisionierung“Drei Muster in K8s-Produktion:
cert-manager
Abschnitt betitelt „cert-manager“apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: actor-ts-clusterspec: secretName: actor-ts-cluster-tls issuerRef: name: actor-ts-ca kind: ClusterIssuer commonName: actor-ts dnsNames: [actor-ts-cluster.svc] duration: 8760h renewBefore: 720hcert-manager erneuert Certs automatisch vor Ablauf. Die meisten Produktions-K8s-Setups nutzen ihn.
Vault Agent
Abschnitt betitelt „Vault Agent“Vault Agent läuft als Sidecar; zieht Certs in das Pod-Filesystem; erneuert automatisch. Nützlich, wenn du schon HashiCorp Vault hast.
Manuell + geplante Rotation
Abschnitt betitelt „Manuell + geplante Rotation“Für Nicht-K8s-Umgebungen geplante Cron-Jobs, die frische Certs aus einer internen CA ziehen + die betroffenen Services neu starten. Funktioniert, erfordert aber sorgfältige operative Disziplin.
Was ist mit der CA-Kette?
Abschnitt betitelt „Was ist mit der CA-Kette?“ca: fs.readFileSync('./tls/ca.crt'),Die meisten internen Setups: eine CA, signiert alle Client- + Server-Certs. Die Cert-Verifizierung braucht das CA-Cert auf beiden Enden.
Cloud-managed Certificates (Let’s Encrypt, AWS ACM): nutze
öffentliche CA-Bundles — in den meisten Runtimes bereits
vorhanden. Kein expliziter ca nötig.
Wohin als nächstes
Abschnitt betitelt „Wohin als nächstes“- Cluster-Sicherheit — das Detail zum Cluster-Transport.
- Master-Key-Rotation — für Daten at-rest.
- Kubernetes-Deployment — das K8s-Rezept + cert-manager-Integration.
- Operations-Überblick — die Produktions-Sicherheits-Checkliste.
