docs(examples): Kubernetes Ingress Authentication
@aRustyDev ci sta già lavorando.
Dal 5/1/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
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
- Lingua principale
- Rust
- Stelle
- 0
- Fork
- 1
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di aRustyDev/mdbook-htmx
-
feat(ci): Implement cross-repo-validate compliance for docs syncForse di nuovo libera @aRustyDev l’ha presa 279 giorni fa e non c’è nessuna pull request aperta. Apertaci enhancement
aRustyDev/mdbook-htmx#58 · 1 commento · 1 assegnatario ·
-
docs(htmx): Explain how HTMX worksForse di nuovo libera @aRustyDev l’ha presa 281 giorni fa e non c’è nessuna pull request aperta. Aperta
aRustyDev/mdbook-htmx#48 · 3 commenti · 1 assegnatario ·
-
docs(mdbook-htmx): Parent Issue for documentationForse di nuovo libera @aRustyDev l’ha presa 281 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#47 · 1 assegnatario ·
-
docs(examples): Secure Self-Hosted Meilisearch via CloudflareForse di nuovo libera @aRustyDev l’ha presa 281 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#46 · 1 assegnatario ·
-
docs(examples): Kubernetes with MeilisearchForse di nuovo libera @aRustyDev l’ha presa 281 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#45 · 1 assegnatario ·
Tutte le issue di aRustyDev/mdbook-htmx
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
I maintainer di solito rispondono entro 1 giorno
-
V1 manifest lists written by Java lose added/existing/deleted file countsForse già presa @kacper-li-airspace-intelligence l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
apache/iceberg-rust#3445 ·
I maintainer di solito rispondono entro 4 giorni
-
area::tern-sync kind::cleanup triage::ready
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
review-bot
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
midagedev/bloomery#160 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
oxidecomputer/humility#737 ·