security(hermes): canary current oauth proxy

This commit is contained in:
jenkins 2026-08-09 13:40:58 -03:00
parent a9b86d4cc4
commit bd7c1640ee
4 changed files with 47 additions and 45 deletions

View File

@ -29,6 +29,12 @@ resources:
- agent-ingress.yaml
configMapGenerator:
- name: hermes-chat-oauth-templates
namespace: hermes
files:
- error.html=oauth2-proxy-templates/error.html
options:
disableNameSuffixHash: true
- name: hermes-operator-guide
namespace: hermes
files:

View File

@ -0,0 +1,29 @@
{{define "error.html"}}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{.StatusCode}} {{.Title}}</title>
{{if or (eq .StatusCode 500) (eq .Message "Login Failed: Unable to find a valid CSRF token. Please try again.")}}<meta http-equiv="refresh" content="0;url={{.ProxyPrefix}}/sign_in?rd=/">{{end}}
<style>
body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f5f5f5;color:#333;font:16px/1.5 system-ui,sans-serif}
main{width:min(560px,calc(100% - 40px));box-sizing:border-box;padding:36px;border:1px solid #ddd;border-radius:14px;background:#fff;text-align:center;box-shadow:0 12px 45px #0002}
h1{font-size:3rem;margin:.2rem}.detail{color:#666}a{display:inline-block;margin-top:18px;padding:10px 16px;border-radius:8px;background:#00bfa5;color:#fff;text-decoration:none}
</style>
</head>
<body>
<main>
{{if or (eq .StatusCode 500) (eq .Message "Login Failed: Unable to find a valid CSRF token. Please try again.")}}
<h1>Signing you back in…</h1>
<p class="detail">The previous one-time login callback expired or was already used. Hermes is starting a fresh sign-in automatically.</p>
<a href="{{.ProxyPrefix}}/sign_in?rd=/">Continue now</a>
{{else}}
<h1>{{.StatusCode}} {{.Title}}</h1>
{{if .Message}}<p class="detail">{{.Message}}</p>{{end}}
<a href="{{.ProxyPrefix}}/sign_in?rd=/">Sign in again</a>
{{end}}
</main>
</body>
</html>
{{end}}

View File

@ -9,43 +9,6 @@ data:
brad@bstein.dev
---
apiVersion: v1
kind: ConfigMap
metadata:
name: hermes-chat-oauth-templates
namespace: hermes
data:
error.html: |
{{define "error.html"}}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{.StatusCode}} {{.Title}}</title>
{{if or (eq .StatusCode 500) (eq .Message "Login Failed: Unable to find a valid CSRF token. Please try again.")}}<meta http-equiv="refresh" content="0;url={{.ProxyPrefix}}/sign_in?rd=/">{{end}}
<style>
body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f5f5f5;color:#333;font:16px/1.5 system-ui,sans-serif}
main{width:min(560px,calc(100% - 40px));box-sizing:border-box;padding:36px;border:1px solid #ddd;border-radius:14px;background:#fff;text-align:center;box-shadow:0 12px 45px #0002}
h1{font-size:3rem;margin:.2rem}.detail{color:#666}a{display:inline-block;margin-top:18px;padding:10px 16px;border-radius:8px;background:#00bfa5;color:#fff;text-decoration:none}
</style>
</head>
<body>
<main>
{{if or (eq .StatusCode 500) (eq .Message "Login Failed: Unable to find a valid CSRF token. Please try again.")}}
<h1>Signing you back in…</h1>
<p class="detail">The previous one-time login callback expired or was already used. Hermes is starting a fresh sign-in automatically.</p>
<a href="{{.ProxyPrefix}}/sign_in?rd=/">Continue now</a>
{{else}}
<h1>{{.StatusCode}} {{.Title}}</h1>
{{if .Message}}<p class="detail">{{.Message}}</p>{{end}}
<a href="{{.ProxyPrefix}}/sign_in?rd=/">Sign in again</a>
{{end}}
</main>
</body>
</html>
{{end}}
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy-hermes-agent
@ -276,7 +239,7 @@ spec:
labels:
app: oauth2-proxy-hermes-chat
annotations:
ai.bstein.dev/config-rev: "20260809-expired-callback-recovery"
ai.bstein.dev/config-rev: "20260809-oauth2-proxy-7-15-canary"
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-pre-populate-only: "true"
vault.hashicorp.com/role: hermes-chat
@ -292,7 +255,7 @@ spec:
automountServiceAccountToken: true
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0@sha256:dcb6ff8dd21bf3058f6a22c6fa385fa5b897a9cd3914c88a2cc2bb0a85f8065d
image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.3@sha256:10a1165743a192e1940b4708fb9647027185ce11a681a1c5519b442ff7f1f561
imagePullPolicy: IfNotPresent
args:
- --provider=oidc
@ -311,6 +274,9 @@ spec:
- --cookie-path=/
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-csrf-expire=10m
- --cookie-csrf-per-request=true
- --cookie-csrf-per-request-limit=8
- --cookie-refresh=1h
- --cookie-expire=8h
- --custom-templates-dir=/etc/oauth2-proxy/templates
@ -319,6 +285,7 @@ spec:
- --http-address=0.0.0.0:4180
- --skip-provider-button=true
- --reverse-proxy=true
- --trusted-proxy-ip=10.42.0.0/16
ports:
- {name: http, containerPort: 4180}
readinessProbe:

View File

@ -104,16 +104,16 @@ def test_chat_oauth_allows_stale_service_worker_retirement():
assert "--skip-auth-route=GET=^/sw[.]js([?].*)?$" in args
assert "--custom-templates-dir=/etc/oauth2-proxy/templates" in args
template = next(
document
for document in documents
if document["kind"] == "ConfigMap"
and document["metadata"]["name"] == "hermes-chat-oauth-templates"
)["data"]["error.html"]
template = (HERMES / "oauth2-proxy-templates" / "error.html").read_text()
assert 'http-equiv="refresh"' in template
assert "Unable to find a valid CSRF token" in template
assert "expired or was already used" in template
assert "/sign_in?rd=/" in template
container = deployment["spec"]["template"]["spec"]["containers"][0]
assert "v7.15.3@sha256:10a1165743a192e" in container["image"]
assert "--cookie-csrf-per-request=true" in args
assert "--cookie-csrf-per-request-limit=8" in args
assert "--trusted-proxy-ip=10.42.0.0/16" in args
def test_chat_auth_file_mount_survives_atomic_provider_refresh():