security(hermes): canary current oauth proxy
This commit is contained in:
parent
a9b86d4cc4
commit
bd7c1640ee
@ -29,6 +29,12 @@ resources:
|
|||||||
- agent-ingress.yaml
|
- agent-ingress.yaml
|
||||||
|
|
||||||
configMapGenerator:
|
configMapGenerator:
|
||||||
|
- name: hermes-chat-oauth-templates
|
||||||
|
namespace: hermes
|
||||||
|
files:
|
||||||
|
- error.html=oauth2-proxy-templates/error.html
|
||||||
|
options:
|
||||||
|
disableNameSuffixHash: true
|
||||||
- name: hermes-operator-guide
|
- name: hermes-operator-guide
|
||||||
namespace: hermes
|
namespace: hermes
|
||||||
files:
|
files:
|
||||||
|
|||||||
29
services/hermes/oauth2-proxy-templates/error.html
Normal file
29
services/hermes/oauth2-proxy-templates/error.html
Normal 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}}
|
||||||
@ -9,43 +9,6 @@ data:
|
|||||||
brad@bstein.dev
|
brad@bstein.dev
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
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
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: oauth2-proxy-hermes-agent
|
name: oauth2-proxy-hermes-agent
|
||||||
@ -276,7 +239,7 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: oauth2-proxy-hermes-chat
|
app: oauth2-proxy-hermes-chat
|
||||||
annotations:
|
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-inject: "true"
|
||||||
vault.hashicorp.com/agent-pre-populate-only: "true"
|
vault.hashicorp.com/agent-pre-populate-only: "true"
|
||||||
vault.hashicorp.com/role: hermes-chat
|
vault.hashicorp.com/role: hermes-chat
|
||||||
@ -292,7 +255,7 @@ spec:
|
|||||||
automountServiceAccountToken: true
|
automountServiceAccountToken: true
|
||||||
containers:
|
containers:
|
||||||
- name: oauth2-proxy
|
- 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
|
imagePullPolicy: IfNotPresent
|
||||||
args:
|
args:
|
||||||
- --provider=oidc
|
- --provider=oidc
|
||||||
@ -311,6 +274,9 @@ spec:
|
|||||||
- --cookie-path=/
|
- --cookie-path=/
|
||||||
- --cookie-secure=true
|
- --cookie-secure=true
|
||||||
- --cookie-samesite=lax
|
- --cookie-samesite=lax
|
||||||
|
- --cookie-csrf-expire=10m
|
||||||
|
- --cookie-csrf-per-request=true
|
||||||
|
- --cookie-csrf-per-request-limit=8
|
||||||
- --cookie-refresh=1h
|
- --cookie-refresh=1h
|
||||||
- --cookie-expire=8h
|
- --cookie-expire=8h
|
||||||
- --custom-templates-dir=/etc/oauth2-proxy/templates
|
- --custom-templates-dir=/etc/oauth2-proxy/templates
|
||||||
@ -319,6 +285,7 @@ spec:
|
|||||||
- --http-address=0.0.0.0:4180
|
- --http-address=0.0.0.0:4180
|
||||||
- --skip-provider-button=true
|
- --skip-provider-button=true
|
||||||
- --reverse-proxy=true
|
- --reverse-proxy=true
|
||||||
|
- --trusted-proxy-ip=10.42.0.0/16
|
||||||
ports:
|
ports:
|
||||||
- {name: http, containerPort: 4180}
|
- {name: http, containerPort: 4180}
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
|||||||
@ -104,16 +104,16 @@ def test_chat_oauth_allows_stale_service_worker_retirement():
|
|||||||
assert "--skip-auth-route=GET=^/sw[.]js([?].*)?$" in args
|
assert "--skip-auth-route=GET=^/sw[.]js([?].*)?$" in args
|
||||||
assert "--custom-templates-dir=/etc/oauth2-proxy/templates" in args
|
assert "--custom-templates-dir=/etc/oauth2-proxy/templates" in args
|
||||||
|
|
||||||
template = next(
|
template = (HERMES / "oauth2-proxy-templates" / "error.html").read_text()
|
||||||
document
|
|
||||||
for document in documents
|
|
||||||
if document["kind"] == "ConfigMap"
|
|
||||||
and document["metadata"]["name"] == "hermes-chat-oauth-templates"
|
|
||||||
)["data"]["error.html"]
|
|
||||||
assert 'http-equiv="refresh"' in template
|
assert 'http-equiv="refresh"' in template
|
||||||
assert "Unable to find a valid CSRF token" in template
|
assert "Unable to find a valid CSRF token" in template
|
||||||
assert "expired or was already used" in template
|
assert "expired or was already used" in template
|
||||||
assert "/sign_in?rd=/" 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():
|
def test_chat_auth_file_mount_survives_atomic_provider_refresh():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user