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)
|
||||
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 ; \
|
||||
fi
|
||||
|
||||
# kong-template:
|
||||
# envsubst < kong/kong.template.yml > kong/kong.yml
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# Lifecycle targets
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: "3.9"
|
||||
# version: "3.9"
|
||||
|
||||
x-common-env: &common-env
|
||||
TZ: "UTC"
|
||||
|
|
@ -8,21 +8,84 @@ x-common-env: &common-env
|
|||
############################################################
|
||||
services:
|
||||
# ──────────────────────────────
|
||||
kong:
|
||||
image: docker.io/library/kong:3.7
|
||||
container_name: kong
|
||||
restart: unless-stopped
|
||||
# kong:
|
||||
# image: kong/kong:3.6
|
||||
# container_name: kong
|
||||
# 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:
|
||||
<<: *common-env
|
||||
KONG_DATABASE: "off"
|
||||
KONG_DECLARATIVE_CONFIG: /config/kong.yml
|
||||
KONG_LOG_LEVEL: info
|
||||
volumes:
|
||||
- ./kong/kong.yml:/config/kong.yml:ro
|
||||
ports:
|
||||
- "8000:8000" # proxy (handy for localhost curl)
|
||||
- "8001:8001" # admin
|
||||
networks: [internal, nginx-proxy]
|
||||
OAUTH2_PROXY_PROVIDER: oidc
|
||||
OAUTH2_PROXY_OIDC_ISSUER_URL: https://kc.kellsupport.com/realms/cmmc
|
||||
OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID}
|
||||
OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET}
|
||||
OAUTH2_PROXY_REDIRECT_URL: https://api.kellsupport.com/oauth2/callback
|
||||
OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET}
|
||||
|
||||
# Forward all traffic to FastAPI (which handles /api/* etc)
|
||||
OAUTH2_PROXY_UPSTREAMS: http://fastapi:8000
|
||||
|
||||
# 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:
|
||||
|
|
@ -33,7 +96,7 @@ services:
|
|||
<<: *common-env
|
||||
# Default to local container; overridden by external URL in Makefile/CI
|
||||
KEYCLOAK_URL: "${KEYCLOAK_URL:-http://keycloak:8080}"
|
||||
KEYCLOAK_REALM: "cmmc-platform-dev"
|
||||
KEYCLOAK_REALM: "cmmc"
|
||||
KEYCLOAK_CLIENT_ID: "frontend"
|
||||
# ports:
|
||||
# # 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"
|
||||
_transform: true
|
||||
|
||||
|
||||
|
||||
services:
|
||||
- name: fastapi-svc
|
||||
host: fastapi
|
||||
port: 8000
|
||||
protocol: http
|
||||
|
||||
routes:
|
||||
- name: fastapi-api
|
||||
paths: ["/api/"]
|
||||
strip_path: true
|
||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||
plugins:
|
||||
- name: cors
|
||||
config:
|
||||
origins: ["*"]
|
||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||
headers: ["Accept", "Content-Type", "Authorization"]
|
||||
credentials: false
|
||||
max_age: 3600
|
||||
|
||||
- name: fastapi-health
|
||||
paths: ["/gateway-health", "/healthz"]
|
||||
strip_path: true
|
||||
methods: ["GET"]
|
||||
|
||||
- name: kong-meta
|
||||
url: http://localhost:8001
|
||||
routes:
|
||||
- name: root-status
|
||||
paths: ["/"]
|
||||
strip_path: true
|
||||
methods: ["GET"]
|
||||
routes:
|
||||
- name: api-root
|
||||
paths: ["/api/"]
|
||||
strip_path: true
|
||||
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
|
||||
plugins:
|
||||
- name: request-termination
|
||||
- name: request-transformer
|
||||
config:
|
||||
status_code: 200
|
||||
content_type: application/json
|
||||
body: '{"status":"Kong Gateway OK"}'
|
||||
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
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
@ -8,6 +9,31 @@ async def healthz() -> dict[str, str]:
|
|||
return {"status": "pong"}
|
||||
|
||||
|
||||
@app.get("/get-health", tags=["meta"])
|
||||
async def get_health() -> dict[str, str]:
|
||||
return {"status": "pong"}
|
||||
|
||||
|
||||
@app.get("/", tags=["meta"])
|
||||
async def root() -> dict[str, str]:
|
||||
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