docs(examples): Kubernetes Ingress Authentication
@aRustyDev 已经在做这个了。
开始于 2026年1月5日。
评估
这个 Issue 还没有评估数据。
描述
Kubernetes Ingress Authentication
Add authentication to mdbook-htmx using Kubernetes Ingress annotations and OAuth2 Proxy.
Overview
Options for Ingress authentication:
- Basic Auth: Simple username/password
- OAuth2 Proxy: SSO with GitHub, Google, etc.
- External Auth Service: Custom authentication service
Option 1: Basic Authentication
Create Secret
# Create htpasswd file
htpasswd -c auth admin
# Create Kubernetes secret
kubectl create secret generic basic-auth \
--from-file=auth \
-n docs
Ingress with Basic Auth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docs
namespace: docs
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
# Basic auth annotations
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Documentation - Login Required"
spec:
tls:
- hosts:
- docs.example.com
secretName: docs-tls
rules:
- host: docs.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docs
port:
number: 80
Selective Protection
Protect only specific paths:
# Public docs
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docs-public
namespace: docs
spec:
rules:
- host: docs.example.com
http:
paths:
- path: /public
pathType: Prefix
backend:
service:
name: docs
port:
number: 80
---
# Protected internal docs
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docs-internal
namespace: docs
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
spec:
rules:
- host: docs.example.com
http:
paths:
- path: /internal
pathType: Prefix
backend:
service:
name: docs
port:
number: 80
Option 2: OAuth2 Proxy
Deploy OAuth2 Proxy
# oauth2-proxy-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: docs
spec:
replicas: 2
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.5.1
args:
- --provider=github
- --email-domain=*
- --upstream=file:///dev/null
- --http-address=0.0.0.0:4180
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-refresh=1h
- --cookie-expire=4h
- --set-xauthrequest=true
- --pass-access-token=true
- --pass-user-headers=true
env:
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: client-id
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: cookie-secret
ports:
- containerPort: 4180
name: http
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
livenessProbe:
httpGet:
path: /ping
port: 4180
initialDelaySeconds: 3
readinessProbe:
httpGet:
path: /ping
port: 4180
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: docs
spec:
ports:
- port: 4180
targetPort: 4180
selector:
app: oauth2-proxy
OAuth2 Proxy Secrets
# Generate cookie secret
cookie_secret=$(openssl rand -base64 32 | head -c 32)
# Create secret
kubectl create secret generic oauth2-proxy-secrets \
--from-literal=client-id=YOUR_GITHUB_CLIENT_ID \
--from-literal=client-secret=YOUR_GITHUB_CLIENT_SECRET \
--from-literal=cookie-secret=$cookie_secret \
-n docs
Ingress with OAuth2 Proxy
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docs
namespace: docs
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
# OAuth2 Proxy annotations
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email,X-Auth-Request-Groups"
spec:
tls:
- hosts:
- docs.example.com
secretName: docs-tls
rules:
- host: docs.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docs
port:
number: 80
---
# OAuth2 Proxy endpoints
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: oauth2-proxy
namespace: docs
spec:
tls:
- hosts:
- docs.example.com
secretName: docs-tls
rules:
- host: docs.example.com
http:
paths:
- path: /oauth2
pathType: Prefix
backend:
service:
name: oauth2-proxy
port:
number: 4180
GitHub OAuth App Setup
- Go to GitHub → Settings → Developer settings → OAuth Apps
- Create new OAuth App:
- Application name:
Docs Auth - Homepage URL:
https://docs.example.com - Authorization callback URL:
https://docs.example.com/oauth2/callback
- Application name:
- Copy Client ID and Client Secret
Restrict to Organization
args:
- --provider=github
- --github-org=your-org # Only allow org members
- --github-team=your-team # Optional: restrict to team
User Info in Templates
Pass authenticated user info to mdbook-htmx:
# NGINX config snippet
nginx.ingress.kubernetes.io/configuration-snippet: |
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
Option 3: External Auth Service
Custom Auth Service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docs
namespace: docs
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://auth-service.auth.svc.cluster.local:8080/verify"
nginx.ingress.kubernetes.io/auth-method: GET
nginx.ingress.kubernetes.io/auth-response-headers: "X-User-Id,X-User-Roles"
nginx.ingress.kubernetes.io/auth-cache-key: "$cookie_session"
nginx.ingress.kubernetes.io/auth-cache-duration: "200 202 5m, 401 1m"
spec:
# ... rest of ingress
Auth Service Implementation
# auth_service.py
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/verify')
def verify():
# Get session cookie
session_token = request.cookies.get('session')
if not session_token:
return Response('Unauthorized', status=401)
# Validate session (lookup in database, verify JWT, etc.)
user = validate_session(session_token)
if not user:
return Response('Unauthorized', status=401)
# Return user info in headers
return Response('OK', headers={
'X-User-Id': user['id'],
'X-User-Roles': ','.join(user['roles']),
'X-User-Email': user['email'],
})
Role-Based Access Control
Pass roles to documentation
nginx.ingress.kubernetes.io/configuration-snippet: |
auth_request_set $roles $upstream_http_x_user_roles;
proxy_set_header X-User-Roles $roles;
Filter content by role (in mdbook-htmx)
# book.toml
[output.htmx.authz]
header = "X-User-Roles"
[[output.htmx.authz.rules]]
paths = ["/internal/*"]
required_roles = ["internal", "admin"]
[[output.htmx.authz.rules]]
paths = ["/admin/*"]
required_roles = ["admin"]
IP Allowlisting
For internal docs, combine with IP restrictions:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
Rate Limiting
Protect against brute force:
annotations:
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "5"
Monitoring Auth
Log authentication events
nginx.ingress.kubernetes.io/configuration-snippet: |
access_log /var/log/nginx/auth.log auth_log if=$auth_log_enabled;
Metrics
# ServiceMonitor for OAuth2 Proxy
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: oauth2-proxy
spec:
selector:
matchLabels:
app: oauth2-proxy
endpoints:
- port: http
path: /metrics
Troubleshooting
Debug auth headers
# Check what headers reach the pod
kubectl exec -it deploy/docs -- curl -v http://localhost/debug-headers
OAuth2 Proxy logs
kubectl logs -f deploy/oauth2-proxy -n docs
Common issues
- Cookie not set: Check
cookie-securematches your TLS setup - Redirect loop: Verify callback URL matches ingress host
- 401 on static assets: Exclude static paths from auth
Next Steps
- Deploy with Helm chart
- Set up GitHub Pages for public docs
- Use Docker Compose for local testing
- 主要语言
- Rust
- 星标
- 0
- 派生
- 1
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
aRustyDev/mdbook-htmx 的其他 Issue
-
feat(ci): Implement cross-repo-validate compliance for docs sync可能重新可做 @aRustyDev 于 279 天前认领,目前没有进行中的 PR。 未关闭ci enhancement
aRustyDev/mdbook-htmx#58 · 1 条评论 · 已指派 1 人 ·
-
docs(htmx): Explain how HTMX works可能重新可做 @aRustyDev 于 281 天前认领,目前没有进行中的 PR。 未关闭
aRustyDev/mdbook-htmx#48 · 3 条评论 · 已指派 1 人 ·
-
docs(mdbook-htmx): Parent Issue for documentation可能重新可做 @aRustyDev 于 281 天前认领,目前没有进行中的 PR。 未关闭documentation
aRustyDev/mdbook-htmx#47 · 已指派 1 人 ·
-
docs(examples): Secure Self-Hosted Meilisearch via Cloudflare可能重新可做 @aRustyDev 于 281 天前认领,目前没有进行中的 PR。 未关闭documentation
aRustyDev/mdbook-htmx#46 · 已指派 1 人 ·
-
docs(examples): Kubernetes with Meilisearch可能重新可做 @aRustyDev 于 281 天前认领,目前没有进行中的 PR。 未关闭documentation
aRustyDev/mdbook-htmx#45 · 已指派 1 人 ·
查看 aRustyDev/mdbook-htmx 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
bytecodealliance/rustix#1703 ·
维护者通常 3 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 88/100
Pomax/vst-plugins#24 ·
维护者通常 1 天内回复
-
V1 manifest lists written by Java lose added/existing/deleted file counts可能已有人在做 @kacper-li-airspace-intelligence 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
apache/iceberg-rust#3445 ·
维护者通常 4 天内回复
-
Slack integration: links on self-hosted domains never unfurl (parseCapShareUrl only accepts cap.so / cap.link)可能已有人在做 @mangeshraut712 今天认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
CapSoftware/Cap#2546 · 1 条评论 ·
维护者通常 1 天内回复