updates for routing and services
This commit is contained in:
parent
46426c1567
commit
f38c4c30f6
15
.env
15
.env
|
|
@ -7,3 +7,18 @@ KEYCLOAK_URL=https://kc.kellsupport.com
|
||||||
|
|
||||||
# Custom project name (avoids long folder names in ~/.local/share/containers)
|
# Custom project name (avoids long folder names in ~/.local/share/containers)
|
||||||
COMPOSE_PROJECT_NAME=cmmc-platform
|
COMPOSE_PROJECT_NAME=cmmc-platform
|
||||||
|
|
||||||
|
# Keycloak OIDC config for Kong
|
||||||
|
KEYCLOAK_URL=https://kc.kellsupport.com
|
||||||
|
KEYCLOAK_REALM=cmmc
|
||||||
|
# KEYCLOAK_CLIENT_ID=kong-gateway
|
||||||
|
# KEYCLOAK_CLIENT_SECRET=3FefJAfN7Rox2x7EW7JzZ38vLI04cXMB
|
||||||
|
KEYCLOAK_CLIENT_ID=cmmc-oauth2-proxy
|
||||||
|
KEYCLOAK_CLIENT_SECRET=OOPXQpXhFeG57lC7G1AktnpPyodtDkib
|
||||||
|
OIDC_SESSION_SECRET=3b4b1b8c8366b1d7c50c49742f879bdd20b85d5b95adaaf4af38d89a36c372ab
|
||||||
|
|
||||||
|
OAUTH2_PROXY_CLIENT_ID=${KEYCLOAK_CLIENT_ID}
|
||||||
|
OAUTH2_PROXY_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET}
|
||||||
|
OAUTH2_PROXY_COOKIE_SECRET=P1eo4uZRzZM1QNrXIlzlep5dsmbnJr1K19CETok0BhU=
|
||||||
|
OAUTH2_PROXY_PROVIDER_URL=https://kc.kellsupport.com/realms/cmmc
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
FROM kong:0.14-centos
|
||||||
|
|
||||||
|
USER root
|
||||||
|
|
||||||
|
RUN yum install -y git unzip openssl-devel gcc && yum clean all
|
||||||
|
|
||||||
|
# Install kong-oidc version 1.0.1
|
||||||
|
RUN luarocks install kong-oidc 1.0.1
|
||||||
|
|
||||||
|
# Enable the plugin
|
||||||
|
ENV KONG_PLUGINS=bundled,oidc
|
||||||
|
|
||||||
|
USER kong
|
||||||
2
Makefile
2
Makefile
|
|
@ -27,6 +27,8 @@ check-idp:
|
||||||
echo "🛠 No external Keycloak found."; echo 0 >.idp_flag ; \
|
echo "🛠 No external Keycloak found."; echo 0 >.idp_flag ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# kong-template:
|
||||||
|
# envsubst < kong/kong.template.yml > kong/kong.yml
|
||||||
|
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
# Lifecycle targets
|
# Lifecycle targets
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
version: "3.9"
|
# version: "3.9"
|
||||||
|
|
||||||
x-common-env: &common-env
|
x-common-env: &common-env
|
||||||
TZ: "UTC"
|
TZ: "UTC"
|
||||||
|
|
@ -8,21 +8,84 @@ x-common-env: &common-env
|
||||||
############################################################
|
############################################################
|
||||||
services:
|
services:
|
||||||
# ──────────────────────────────
|
# ──────────────────────────────
|
||||||
kong:
|
# kong:
|
||||||
image: docker.io/library/kong:3.7
|
# image: kong/kong:3.6
|
||||||
container_name: kong
|
# container_name: kong
|
||||||
restart: unless-stopped
|
# restart: unless-stopped
|
||||||
|
# environment:
|
||||||
|
# KONG_DATABASE: "off"
|
||||||
|
# KONG_DECLARATIVE_CONFIG: /config/kong.yml
|
||||||
|
# KONG_LOG_LEVEL: info
|
||||||
|
# KONG_PLUGINS: bundled
|
||||||
|
# KONG_PROXY_ACCESS_LOG: /dev/stdout
|
||||||
|
# KONG_ADMIN_ACCESS_LOG: /dev/stdout
|
||||||
|
# KONG_PROXY_ERROR_LOG: /dev/stderr
|
||||||
|
# KONG_ADMIN_ERROR_LOG: /dev/stderr
|
||||||
|
# volumes:
|
||||||
|
# - ./kong:/config
|
||||||
|
# networks:
|
||||||
|
# - internal
|
||||||
|
# - nginx-proxy
|
||||||
|
# depends_on:
|
||||||
|
# - fastapi
|
||||||
|
|
||||||
|
|
||||||
|
oauth2-proxy:
|
||||||
|
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
|
||||||
|
container_name: oauth2-proxy
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- nginx-proxy
|
||||||
environment:
|
environment:
|
||||||
<<: *common-env
|
OAUTH2_PROXY_PROVIDER: oidc
|
||||||
KONG_DATABASE: "off"
|
OAUTH2_PROXY_OIDC_ISSUER_URL: https://kc.kellsupport.com/realms/cmmc
|
||||||
KONG_DECLARATIVE_CONFIG: /config/kong.yml
|
OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID}
|
||||||
KONG_LOG_LEVEL: info
|
OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET}
|
||||||
volumes:
|
OAUTH2_PROXY_REDIRECT_URL: https://api.kellsupport.com/oauth2/callback
|
||||||
- ./kong/kong.yml:/config/kong.yml:ro
|
OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET}
|
||||||
ports:
|
|
||||||
- "8000:8000" # proxy (handy for localhost curl)
|
# Forward all traffic to FastAPI (which handles /api/* etc)
|
||||||
- "8001:8001" # admin
|
OAUTH2_PROXY_UPSTREAMS: http://fastapi:8000
|
||||||
networks: [internal, nginx-proxy]
|
|
||||||
|
# Secure cookies and session behavior
|
||||||
|
OAUTH2_PROXY_COOKIE_DOMAIN: api.kellsupport.com
|
||||||
|
OAUTH2_PROXY_COOKIE_NAME: _oauth2_proxy
|
||||||
|
OAUTH2_PROXY_COOKIE_SECURE: "true"
|
||||||
|
OAUTH2_PROXY_COOKIE_HTTPONLY: "false"
|
||||||
|
OAUTH2_PROXY_COOKIE_SAMESITE: Lax
|
||||||
|
OAUTH2_PROXY_COOKIE_EXPIRE: 168h
|
||||||
|
OAUTH2_PROXY_COOKIE_REFRESH: 60m
|
||||||
|
|
||||||
|
|
||||||
|
# Auth config
|
||||||
|
OAUTH2_PROXY_EMAIL_DOMAINS: "*"
|
||||||
|
OAUTH2_PROXY_SET_XAUTHREQUEST: "true"
|
||||||
|
OAUTH2_PROXY_SET_AUTHORIZATION_HEADER: "true"
|
||||||
|
OAUTH2_PROXY_PASS_ACCESS_TOKEN: "true"
|
||||||
|
OAUTH2_PROXY_PASS_USER_HEADERS: "true"
|
||||||
|
OAUTH2_PROXY_PREFER_EMAIL_TO_USER: "true"
|
||||||
|
OAUTH2_PROXY_COOKIE_CSRF_PER_REQUEST: "true"
|
||||||
|
OAUTH2_PROXY_CSRF_COOKIE_NAME: _oauth2_proxy_csrf
|
||||||
|
OAUTH2_PROXY_SHOW_DEBUG_ON_ERROR: "true"
|
||||||
|
|
||||||
|
|
||||||
|
# Optional: PKCE
|
||||||
|
OAUTH2_PROXY_CODE_CHALLENGE_METHOD: S256
|
||||||
|
|
||||||
|
# Health routes allowed anonymously
|
||||||
|
OAUTH2_PROXY_SKIP_AUTH_ROUTES: GET=^/gateway-health$,GET=^/healthz$,GET=^/favicon\.ico$
|
||||||
|
OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: "true"
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180
|
||||||
|
OAUTH2_PROXY_REVERSE_PROXY: "true"
|
||||||
|
|
||||||
|
expose:
|
||||||
|
- "4180"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ──────────────────────────────
|
# ──────────────────────────────
|
||||||
fastapi:
|
fastapi:
|
||||||
|
|
@ -33,7 +96,7 @@ services:
|
||||||
<<: *common-env
|
<<: *common-env
|
||||||
# Default to local container; overridden by external URL in Makefile/CI
|
# Default to local container; overridden by external URL in Makefile/CI
|
||||||
KEYCLOAK_URL: "${KEYCLOAK_URL:-http://keycloak:8080}"
|
KEYCLOAK_URL: "${KEYCLOAK_URL:-http://keycloak:8080}"
|
||||||
KEYCLOAK_REALM: "cmmc-platform-dev"
|
KEYCLOAK_REALM: "cmmc"
|
||||||
KEYCLOAK_CLIENT_ID: "frontend"
|
KEYCLOAK_CLIENT_ID: "frontend"
|
||||||
# ports:
|
# ports:
|
||||||
# # keep reachable only from localhost, not LAN
|
# # keep reachable only from localhost, not LAN
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
_format_version: "3.0"
|
||||||
|
_transform: true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: fastapi-svc
|
||||||
|
host: fastapi
|
||||||
|
port: 8000
|
||||||
|
protocol: http
|
||||||
|
|
||||||
|
routes:
|
||||||
|
- name: api-root
|
||||||
|
paths: ["/api/"]
|
||||||
|
strip_path: true
|
||||||
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||||
|
plugins:
|
||||||
|
- name: request-transformer
|
||||||
|
config:
|
||||||
|
add:
|
||||||
|
headers:
|
||||||
|
- "X-Forwarded-User: $http_x_auth_request_user"
|
||||||
|
- "X-Forwarded-Email: $http_x_auth_request_email"
|
||||||
|
remove:
|
||||||
|
headers:
|
||||||
|
- "Authorization"
|
||||||
|
|
||||||
|
- name: debug-api
|
||||||
|
url: http://fastapi:8000
|
||||||
|
|
||||||
|
|
||||||
|
# - name: openid
|
||||||
|
# config:
|
||||||
|
# issuer: "${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}"
|
||||||
|
# client_id: "${KEYCLOAK_CLIENT_ID}"
|
||||||
|
# client_secret: "${KEYCLOAK_CLIENT_SECRET}"
|
||||||
|
# redirect_uri: "https://api.kellsupport.com/api/"
|
||||||
|
# scopes: ["openid", "profile", "email"]
|
||||||
|
# bearer_only: false
|
||||||
|
# response_type: "code"
|
||||||
|
# session_secret: "${OIDC_SESSION_SECRET}"
|
||||||
|
# ssl_verify: false
|
||||||
|
# timeout: 10000
|
||||||
|
|
||||||
|
- name: cors
|
||||||
|
config:
|
||||||
|
origins: ["*"]
|
||||||
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||||
|
headers: ["Accept", "Content-Type", "Authorization"]
|
||||||
|
credentials: true
|
||||||
|
max_age: 3600
|
||||||
|
|
||||||
|
- name: api-debug-auth
|
||||||
|
paths: ["/api/debug-auth"]
|
||||||
|
strip_path: true
|
||||||
|
methods: ["GET"]
|
||||||
|
|
||||||
|
- name: gateway-health
|
||||||
|
paths: ["/gateway-health"]
|
||||||
|
strip_path: true
|
||||||
|
methods: ["GET"]
|
||||||
|
|
||||||
|
- name: healthz
|
||||||
|
paths: ["/healthz"]
|
||||||
|
strip_path: true
|
||||||
|
methods: ["GET"]
|
||||||
|
|
||||||
|
- name: debug-auth
|
||||||
|
paths: ["/api/debug-auth"]
|
||||||
|
strip_path: true
|
||||||
|
service: ["debug-api"]
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- name: rate-limiting
|
||||||
|
config:
|
||||||
|
second: 25
|
||||||
|
policy: local
|
||||||
|
|
@ -1,46 +1,74 @@
|
||||||
_format_version: "3.0"
|
_format_version: "3.0"
|
||||||
_transform: true
|
_transform: true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- name: fastapi-svc
|
- name: fastapi-svc
|
||||||
host: fastapi
|
host: fastapi
|
||||||
port: 8000
|
port: 8000
|
||||||
protocol: http
|
protocol: http
|
||||||
|
|
||||||
routes:
|
routes:
|
||||||
- name: fastapi-api
|
- name: api-root
|
||||||
paths: ["/api/"]
|
paths: ["/api/"]
|
||||||
strip_path: true
|
strip_path: true
|
||||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||||
plugins:
|
plugins:
|
||||||
|
- name: request-transformer
|
||||||
|
config:
|
||||||
|
add:
|
||||||
|
headers:
|
||||||
|
- "X-Forwarded-User: "
|
||||||
|
- "X-Forwarded-Email: "
|
||||||
|
remove:
|
||||||
|
headers:
|
||||||
|
- "Authorization"
|
||||||
|
|
||||||
|
- name: debug-api
|
||||||
|
url: http://fastapi:8000
|
||||||
|
|
||||||
|
|
||||||
|
# - name: openid
|
||||||
|
# config:
|
||||||
|
# issuer: "https://kc.kellsupport.com/realms/cmmc"
|
||||||
|
# client_id: "kong-gateway"
|
||||||
|
# client_secret: "3FefJAfN7Rox2x7EW7JzZ38vLI04cXMB"
|
||||||
|
# redirect_uri: "https://api.kellsupport.com/api/"
|
||||||
|
# scopes: ["openid", "profile", "email"]
|
||||||
|
# bearer_only: false
|
||||||
|
# response_type: "code"
|
||||||
|
# session_secret: "3b4b1b8c8366b1d7c50c49742f879bdd20b85d5b95adaaf4af38d89a36c372ab"
|
||||||
|
# ssl_verify: false
|
||||||
|
# timeout: 10000
|
||||||
|
|
||||||
- name: cors
|
- name: cors
|
||||||
config:
|
config:
|
||||||
origins: ["*"]
|
origins: ["*"]
|
||||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||||
headers: ["Accept", "Content-Type", "Authorization"]
|
headers: ["Accept", "Content-Type", "Authorization"]
|
||||||
credentials: false
|
credentials: true
|
||||||
max_age: 3600
|
max_age: 3600
|
||||||
|
|
||||||
- name: fastapi-health
|
- name: api-debug-auth
|
||||||
paths: ["/gateway-health", "/healthz"]
|
paths: ["/api/debug-auth"]
|
||||||
strip_path: true
|
strip_path: true
|
||||||
methods: ["GET"]
|
methods: ["GET"]
|
||||||
|
|
||||||
- name: kong-meta
|
- name: gateway-health
|
||||||
url: http://localhost:8001
|
paths: ["/gateway-health"]
|
||||||
routes:
|
|
||||||
- name: root-status
|
|
||||||
paths: ["/"]
|
|
||||||
strip_path: true
|
strip_path: true
|
||||||
methods: ["GET"]
|
methods: ["GET"]
|
||||||
plugins:
|
|
||||||
- name: request-termination
|
|
||||||
config:
|
|
||||||
status_code: 200
|
|
||||||
content_type: application/json
|
|
||||||
body: '{"status":"Kong Gateway OK"}'
|
|
||||||
|
|
||||||
|
- name: healthz
|
||||||
|
paths: ["/healthz"]
|
||||||
|
strip_path: true
|
||||||
|
methods: ["GET"]
|
||||||
|
|
||||||
|
- name: debug-auth
|
||||||
|
paths: ["/api/debug-auth"]
|
||||||
|
strip_path: true
|
||||||
|
service: ["debug-api"]
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- name: rate-limiting
|
- name: rate-limiting
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI, Request, Depends, HTTPException
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
app = FastAPI(title="CMMC Platform API MVP", version="0.1.0")
|
app = FastAPI(title="CMMC Platform API MVP", version="0.1.0")
|
||||||
|
|
||||||
|
|
@ -8,6 +9,31 @@ async def healthz() -> dict[str, str]:
|
||||||
return {"status": "pong"}
|
return {"status": "pong"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/get-health", tags=["meta"])
|
||||||
|
async def get_health() -> dict[str, str]:
|
||||||
|
return {"status": "pong"}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/", tags=["meta"])
|
@app.get("/", tags=["meta"])
|
||||||
async def root() -> dict[str, str]:
|
async def root() -> dict[str, str]:
|
||||||
return {"message": "CMMC Platform – it works!"}
|
return {"message": "CMMC Platform – it works!"}
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user(request: Request) -> dict:
|
||||||
|
user = request.headers.get("X-Auth-Request-User")
|
||||||
|
email = request.headers.get("X-Auth-Request-Email")
|
||||||
|
preferred_username = request.headers.get("X-Auth-Request-Preferred-Username")
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"user": user,
|
||||||
|
"email": email,
|
||||||
|
"id": preferred_username
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/debug-auth", tags=["auth"])
|
||||||
|
def debug_auth(user=Depends(get_current_user)):
|
||||||
|
return JSONResponse(user)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue