Skip to content

Commit decf2ae

Browse files
entleinEntleinclaude
authored
feat(ae-control): TLS on the control surface (CONTROL_TLS) (#71)
Auth without TLS is half a control: tcpdump on dx→AE :9100 captured 720 cleartext `Authorization: Bearer` JWTs in 70s — the #68 token crosses the CNI in plaintext. CONTROL_TLS=true now serves TLS with server.crt/key from the service-tls-certs secret (broker/PEM already use it; dx skip-verifies). Default-OFF for incremental rollout, symmetric to CONTROL_REQUIRE_AUTH. Stacks on #68 (ae-followup-auth). dx client half: entlein/dx#88. Co-authored-by: Entlein <eineintlein@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent dfdc465 commit decf2ae

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

k8s/vizier/bootstrap/adaptive_export_deployment.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,24 @@ spec:
8888
# value: "changeme-ingest"
8989
# - name: CLICKHOUSE_DATABASE
9090
# value: "forensic_db"
91+
# TLS for the control surface (CONTROL_TLS=true). server.crt/key from the
92+
# same service-tls-certs secret the broker/PEM use; without this the dx
93+
# bearer JWT crosses the CNI in cleartext. Harmless when control is off.
94+
volumeMounts:
95+
- name: certs
96+
mountPath: /certs
97+
readOnly: true
9198
securityContext:
9299
allowPrivilegeEscalation: false
93100
capabilities:
94101
drop:
95102
- ALL
96103
seccompProfile:
97104
type: RuntimeDefault
105+
volumes:
106+
- name: certs
107+
secret:
108+
secretName: service-tls-certs
98109
securityContext:
99110
runAsUser: 10100
100111
runAsGroup: 10100

src/vizier/services/adaptive_export/cmd/main.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,27 @@ func main() {
600600
}
601601
go func() {
602602
log.WithField("addr", addr).Info("control surface listening")
603-
if err := httpSrv.ListenAndServe(); err != nil &&
604-
err != http.ErrServerClosed {
603+
// CONTROL_TLS=true → serve TLS so the bearer JWT + control payloads
604+
// don't cross the CNI in cleartext (auth without TLS leaks the token).
605+
// Cert/key from the service-tls-certs secret the broker/PEM already use
606+
// (mounted /certs); dx skip-verifies. Default-OFF for incremental rollout.
607+
var err error
608+
if os.Getenv("CONTROL_TLS") == "true" {
609+
cert := os.Getenv("CONTROL_TLS_CERT")
610+
if cert == "" {
611+
cert = "/certs/server.crt"
612+
}
613+
key := os.Getenv("CONTROL_TLS_KEY")
614+
if key == "" {
615+
key = "/certs/server.key"
616+
}
617+
log.WithField("cert", cert).Info("control surface: TLS ENABLED")
618+
err = httpSrv.ListenAndServeTLS(cert, key)
619+
} else {
620+
log.Warn("control surface: TLS DISABLED — bearer JWT crosses the CNI in cleartext (set CONTROL_TLS=true)")
621+
err = httpSrv.ListenAndServe()
622+
}
623+
if err != nil && err != http.ErrServerClosed {
605624
log.WithError(err).Error("control surface stopped")
606625
}
607626
}()

0 commit comments

Comments
 (0)