Compare commits

..

14 Commits

Author SHA1 Message Date
Jonathan Perret 877f2f896b 🔧(config) add healthcheck to docker-compose
This makes docker-compose up --wait work.
2025-11-21 11:48:41 +01:00
Jonathan Perret 5884e28292 🔧(cnb) temporarily hardcode email
Our test account currently does not have an email
address in the IdP.
2025-11-21 11:46:50 +01:00
Jonathan Perret b62fae53ec 🔧(cnb) request signed assertions or response
At least in the "recette" environment responses are not signed, but
assertions are.
2025-11-21 11:46:49 +01:00
Jonathan Perret 4a4a180ef1 🔧(cnb) change supported name_id_format
To comply with the CNB IdP we need to support
urn:oasis:names:tc:SAML:2.0:nameid-format:transient.
2025-11-21 11:46:48 +01:00
Jonathan Perret 138bc431fd 📌(pysaml2) pin pysaml2 to avoid double-signing of AuthNRequests
The current version of pysaml2 (7.5.2) has an issue where AuthNRequests
are both signed in the XML and with an extra `Signature` queryparam.
This was reported initially in 2021:
    https://github.com/IdentityPython/pysaml2/issues/819
And it was fixed by a changed in SATOSA:
    https://github.com/IdentityPython/SATOSA/pull/380
But it reappeared apparently and the original reporter has a PR open
against pysaml2 that is supposed to fix it:
    https://github.com/IdentityPython/pysaml2/pull/973
They report that the regression was introduced in pysaml2 by
   https://github.com/IdentityPython/pysaml2/pull/834
We try here to pin pysaml2 to the last version before this PR was
merged. Unfortunately this is quite an old version, but from basic
testing it seems to still be compatible with the current SATOSA
version.
This in turn forces us to also pin xmlschema to avoid
    https://github.com/IdentityPython/pysaml2/issues/947

Hopefully this can be temporary.
2025-11-21 11:46:47 +01:00
Jonathan Perret fbb190b455 🧑‍💻(oidc-test-client) configure OIDC client on each request
Downloading the discovery document from the OIDC provider on
each request rather than on startup lets the oidc-test-client be
independent of the availability of the OIDC provider, which is useful
in development scenarios.
2025-11-21 11:46:46 +01:00
Jonathan Perret 2cb64a42a8 🚀(cnb) create cnb-dev environment
For local validation of Helm chart using Tilt.
2025-11-21 11:46:44 +01:00
Jonathan Perret 917313bb5a 🚀(cnb) create cnb-staging environment
Test deployment for CNB.
2025-11-21 11:45:33 +01:00
Jonathan Perret 769342494f 🔧(config) create config for CNB
First attempt at a configuration that may work for interoperation
with the CNB IdP.
2025-11-21 11:43:42 +01:00
Jonathan Perret 8ee0bacee0 🔧(config) create instance-specific configuration directories
The Docker image will now expect the working directory to be set,
for example to /app/config/fer for the current (RENATER) configuration.
2025-11-21 11:42:25 +01:00
Jonathan Perret dda5bb918d 🔧(config) create instance-specific configuration directories
The Docker image will now expect the working directory to be set,
for example to /app/config/fer for the current (RENATER) configuration.
2025-11-21 11:42:23 +01:00
Jonathan Perret 46c7a7eea7 🔨(dockerfile) fix development image to work with a different working dir
Because the `pip install --editable` command was run from an empty
directory, the `oidc2fer` directory that was later copied from the sources
did not show up as an importable module. This worked before changing
the working directory because the import falled back on looking in the
current directory.
2025-11-21 11:40:21 +01:00
Jonathan Perret 5a2d3bb35b 🔧(secrets) update secrets to current main
No change for oidc2fer secrets.
2025-11-21 11:40:20 +01:00
Jonathan Perret 6dc94af598 📌(helm) move to bitnamilegacy image for local Redis
Bitnami moved their images…
2025-11-21 11:40:19 +01:00
60 changed files with 727 additions and 688 deletions
+6 -6
View File
@@ -17,14 +17,14 @@ jobs:
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
@@ -36,14 +36,14 @@ jobs:
type=raw,value=latest,enable={{is_default_branch}}
- name: Login to Github Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ github.token }}
- name: Build and push
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
uses: docker/build-push-action@v6
with:
context: .
target: production
@@ -59,7 +59,7 @@ jobs:
needs:
- build-and-push
steps:
- uses: numerique-gouv/action-argocd-webhook-notification@cac2ee67896eb13e84e804f60c4271370424eaa8 # main
- uses: numerique-gouv/action-argocd-webhook-notification@main
id: notify
with:
deployment_repo_path: "${{ github.repository }}"
+11 -19
View File
@@ -16,7 +16,7 @@ jobs:
if: github.event_name == 'pull_request' # Makes sense only for pull requests
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: show
@@ -39,7 +39,7 @@ jobs:
github.event_name == 'pull_request'
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check that the CHANGELOG has been modified in the current branch
@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
- name: Check CHANGELOG max line length
run: |
max_line_length=$(cat CHANGELOG.md | grep -Ev "^\[.*\]: https://github.com" | wc -L)
@@ -65,11 +65,11 @@ jobs:
working-directory: src/satosa
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
uses: actions/setup-python@v3
with:
python-version: '3.14'
python-version: '3.11'
- name: Install development dependencies
run: |
# Python's xmlsec requirement
@@ -89,11 +89,11 @@ jobs:
working-directory: src/satosa
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
uses: actions/setup-python@v3
with:
python-version: '3.14'
python-version: '3.11'
- name: Install development dependencies
run: |
# Python's xmlsec requirement
@@ -110,7 +110,7 @@ jobs:
image: ghcr.io/helmfile/helmfile:v1.2.0
steps:
-
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
@@ -119,18 +119,10 @@ jobs:
repositories: secrets
-
name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ steps.app-token.outputs.token }}
-
name: Install mkcert
run: |
apt-get update -y -q && apt-get install -y -q libnss3-tools
curl -Ss -L -o mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
mv mkcert /usr/local/bin/
TRUST_STORES=none mkcert -install
-
name: Helmfile lint
env:
+2 -8
View File
@@ -6,14 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.13] - 2026-03-26
- switch to stateless OIDC and remove Redis
## [1.0.12] - 2026-03-02
- upgrade dependencies: Python 3.14.3, gunicorn 25.1.0…
## [1.0.11] - 2025-11-24
- remove setuptools, wheel and pip from production Docker image
## Unreleased
- add alternate configuration for connection to CNB (#33)
## [1.0.10] - 2025-11-21
- rename helmfile.yaml for compatibility with helmfile 1.x
+12 -13
View File
@@ -1,17 +1,13 @@
# ---- base image to inherit from ----
FROM python:3.14.3-slim-trixie AS common
FROM python:3.11.12-slim-bookworm AS common
# Install xmlsec1 dependencies required for xmlsec (for SAML)
# Needs to be kept before the `pip install`
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
RUN apt-get update && \
apt-get -y upgrade && \
apt-get install -qy --no-install-recommends xmlsec1 && \
rm -rf /var/lib/apt/lists/*
# Silence pip warnings about running as root in a container
ENV PIP_ROOT_USER_ACTION=ignore
# We want the most up-to-date stable pip release
RUN pip install --upgrade pip
@@ -42,8 +38,7 @@ CMD ["gunicorn", "-c", "/usr/local/etc/gunicorn/satosa.py"]
FROM common AS development
# Install curl (for healthchecks)
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && apt-get install -qy curl
RUN apt-get update && apt-get install -qy curl
# Playwright browsers
ENV PLAYWRIGHT_BROWSERS_PATH=/pw-browsers
@@ -59,10 +54,15 @@ WORKDIR /app
# Copy project file to list dependencies
COPY ./src/satosa/pyproject.toml /app/
# Install oidc2fer in editable mode along with development dependencies
RUN pip install -e .[dev]
# Create empty module directory to please pip install --editable
# (without this, the oidc2fer module will not be importable because
# pip --editable scans the directory to create its "links")
RUN mkdir -p /app/oidc2fer
# Copy oidc2fer application (see .dockerignore)
# Install oidc2fer in editable mode along with development dependencies
RUN pip install --editable .[dev]
# Copy oidc2fer sources (see .dockerignore)
COPY ./src/satosa /app/
# Switch to unprivileged user
@@ -76,8 +76,7 @@ COPY ./src/satosa /app/
WORKDIR /app
# Uninstall pip, setuptools and wheel after installation to reduce attack surface
RUN pip install . && pip uninstall -y setuptools wheel pip
RUN pip install .
# Switch to unprivileged user
USER ${DOCKER_USER}
+1 -6
View File
@@ -13,11 +13,6 @@ docker_build(
]
)
docker_build(
'localhost:5001/oidc-test-client:latest',
context='docker/oidc-test-client'
)
watch_file('src/helm')
k8s_yaml(local('cd src/helm && helmfile -n oidc2fer -e dev template .'))
k8s_yaml(local('cd src/helm && helmfile -n oidc2fer -e %s template .' % os.getenv('TILT_ENV', 'dev')))
+8 -7
View File
@@ -14,7 +14,7 @@ services:
GUNICORN_CMD_ARGS: --workers=2
TEST_E2E: 1
#TEST_E2E_PC: 1
OIDC_DB_URI: stateless://:STATE-ENCRYPTION-KEY@localhost
OIDC_DB_URI: redis://redis/0
CLIENT_DB_JSON: |
{
"oidc-test-client": {
@@ -30,7 +30,7 @@ services:
}
}
SAML2_DISCOVERY_URL: https://discovery.renater.fr/test/
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/test/idps.xml
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/test/preview/preview-idps-test-metadata.xml
SAML2_ENTITY_ID: https://satosa.traefik.me/Saml2/proxy_saml2_backend.xml
env_file:
- env.d/development/common
@@ -38,6 +38,9 @@ services:
volumes:
- ./src/satosa:/app
- ./docker/files/usr/local/etc/gunicorn/satosa.py:/usr/local/etc/gunicorn/satosa.py
working_dir: /app/config/fer
depends_on:
- redis
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:8000/ping"]
interval: 60s
@@ -48,19 +51,14 @@ services:
oidc-test-client:
build: docker/oidc-test-client
depends_on:
- nginx # nginx must be up to override satosa.traefik.me resolution
- app-dev
stop_signal: SIGKILL
volumes:
- ./docker/oidc-test-client:/app
- ./env.d/development/certs/mkcert-root-ca.pem:/usr/local/share/ca-certificates/mkcert-root-ca.crt
# - run update-ca-certificates to make mkcert certificates valid
# - add startup delay because IDP must be available on boot
entrypoint: |
/bin/bash -c '
cat /usr/local/share/ca-certificates/mkcert-root-ca.crt >> $(python -m certifi)
sleep 1
cd /app
exec python app.py
'
@@ -75,6 +73,9 @@ services:
extra_hosts:
- "oidc2fer.127.0.0.1.nip.io:host-gateway"
redis:
image: redis:7.2.4
nginx:
image: nginx:1.25
ports:
+7
View File
@@ -38,6 +38,13 @@ printenv SAML2_BACKEND_CERT > /tmp/backend.crt
printenv SAML2_BACKEND_KEY > /tmp/backend.key
printenv OIDC_FRONTEND_KEY > /tmp/frontend.key
printenv CLIENT_DB_JSON > /tmp/client_db.json
printenv SAML2_IDP_METADATA > /tmp/idp_metadata.xml
# Redis database number must be specified
if [[ ! $OIDC_DB_URI =~ /[0-9]+$ ]]; then
echo "🐳(entrypoint) adding db id to OIDC_DB_URI"
export OIDC_DB_URI=$OIDC_DB_URI/0
fi
echo "🐳(entrypoint) running your command: ${*}"
exec "$@"
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.14.3-slim-trixie
FROM python:3.11
COPY . /app
+34 -13
View File
@@ -5,6 +5,7 @@ from oic import rndstr
from oic.oic.message import Claims, ClaimsRequest, RegistrationResponse
from oic.utils.http_util import Redirect
from oic.oic.message import AuthorizationResponse
from werkzeug.exceptions import InternalServerError
import secrets
import logging
import os
@@ -23,21 +24,27 @@ app.config.update(
}
)
client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
provider_info = client.provider_config(os.environ["OIDC_PROVIDER"])
def create_client() -> Client:
client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
info = {
"client_id": os.environ["OIDC_CLIENT_ID"],
"client_secret": os.environ["OIDC_CLIENT_SECRET"],
"redirect_uris": [f"{os.environ['OIDC_ROOT_URL']}/redirect_uri"],
}
client_reg = RegistrationResponse(**info)
client.store_registration_info(client_reg)
client.provider_config(os.environ["OIDC_PROVIDER"])
info = {
"client_id": os.environ["OIDC_CLIENT_ID"],
"client_secret": os.environ["OIDC_CLIENT_SECRET"],
}
client.store_registration_info(RegistrationResponse(**info))
client.redirect_uris = [f"{os.environ['OIDC_ROOT_URL']}/redirect_uri"]
return client
@app.route("/")
def index():
client = create_client()
session["state"] = rndstr()
session["nonce"] = rndstr()
@@ -47,7 +54,7 @@ def index():
"response_type": "code",
"scope": os.environ["OIDC_SCOPES"].split(","),
"nonce": session["nonce"],
"redirect_uri": client.registration_response["redirect_uris"][0],
"redirect_uri": client.redirect_uris[0],
"state": session["state"],
"claims": ClaimsRequest(id_token=Claims(acr=None, amr=None)),
}
@@ -59,6 +66,8 @@ def index():
@app.route("/redirect_uri")
def oidc_callback():
client = create_client()
response = request.query_string.decode("utf-8")
aresp = client.parse_response(
AuthorizationResponse, info=response, sformat="urlencoded"
@@ -71,7 +80,6 @@ def oidc_callback():
error_response=aresp.to_dict(),
)
code = aresp["code"]
logging.info("got auth code=%s", code)
@@ -90,7 +98,20 @@ def oidc_callback():
logging.info("got userinfo=%s", userinfo)
return jsonify(
access_token_response=access_token_response.to_dict(), userinfo=userinfo.to_dict()
access_token_response=access_token_response.to_dict(),
userinfo=userinfo.to_dict(),
)
@app.errorhandler(InternalServerError)
def handle_server_exception(e):
exc = e.original_exception
import traceback
return (
f"""<h1>Internal Server Error</h1>
<pre>{"".join(traceback.format_exception(exc))}</pre>""",
500,
)
@@ -98,6 +119,6 @@ def oidc_callback():
def health():
return "OK"
if __name__ == "__main__":
app.run(host="0.0.0.0")
+2 -1
View File
@@ -1,2 +1,3 @@
# Python
PYTHONPATH=/app
LOG_LEVEL=DEBUG
LOG_LEVELS='{ "satosa.backends.saml2": "DEBUG" }'
+1 -1
Submodule secrets updated: aa2de36cd8...4e6030feee
File diff suppressed because one or more lines are too long
@@ -0,0 +1,44 @@
image:
repository: localhost:5001/oidc2fer
pullPolicy: Always
tag: "latest"
satosa:
replicas: 1
workingDir: /app/config/cnb
envVars:
BASE_URL: https://oidc2fer.127.0.0.1.nip.io
GUNICORN_CMD_ARGS: --workers=3
LOG_LEVEL: debug
SAML2_ENTITY_ID: https://oidc2fer.127.0.0.1.nip.io/Saml2/proxy_saml2_backend.xml
SAML2_IDP_METADATA: { secretKeyRef: { name: oidc2fer, key: SAML2_IDP_METADATA } }
STATE_ENCRYPTION_KEY: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
SAML2_BACKEND_CERT: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
SAML2_BACKEND_KEY: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
OIDC_FRONTEND_KEY: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
OIDC_DB_URI: "redis://:pass@redis-master:6379"
CLIENT_DB_JSON: |-
{
"oidc-test-client": {
"response_types": [
"id_token",
"code"
],
"redirect_uris": [
"https://oidc-test-client.traefik.me/redirect_uri",
"https://oidc-test-client.traefik.me:8443/redirect_uri"
],
"client_secret": "oidc-test-secret",
"token_endpoint_auth_method": "client_secret_post"
}
}
ingress:
enabled: true
host: oidc2fer.127.0.0.1.nip.io
annotations:
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
+1
View File
@@ -0,0 +1 @@
../../../../secrets/numerique-gouv/oidc2fer/env/cnb-staging/secrets.enc.yaml
@@ -0,0 +1,34 @@
image:
repository: ghcr.io/proconnect-gouv/oidc2fer
pullPolicy: Always
tag: "main"
satosa:
replicas: 2
workingDir: /app/config/cnb
envVars:
BASE_URL: https://oidc2cnb-staging.beta.numerique.gouv.fr
GUNICORN_CMD_ARGS: --workers=3
LOG_LEVEL: DEBUG
LOG_LEVELS: '{ "satosa.backends.saml2": "DEBUG" }'
SAML2_IDP_METADATA: { secretKeyRef: { name: oidc2fer, key: SAML2_IDP_METADATA } }
SAML2_ENTITY_ID: https://oidc2cnb-staging.beta.numerique.gouv.fr/Saml2/proxy_saml2_backend.xml
STATE_ENCRYPTION_KEY: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
SAML2_BACKEND_CERT: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
SAML2_BACKEND_KEY: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
OIDC_FRONTEND_KEY: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
CLIENT_DB_JSON: { secretKeyRef: { name: oidc2fer, key: CLIENT_DB_JSON } }
OIDC_DB_URI: { secretKeyRef: { name: redis.redis.libre.sh, key: url } }
ingress:
enabled: true
host: oidc2cnb-staging.beta.numerique.gouv.fr
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
@@ -1,22 +0,0 @@
image:
repository: localhost:5001/oidc-test-client
pullPolicy: Always
tag: "latest"
ingress:
enabled: true
host: oidc-test-client.127.0.0.1.nip.io
env:
- name: OIDC_ROOT_URL
value: https://oidc-test-client.127.0.0.1.nip.io
- name: OIDC_PROVIDER
value: https://oidc2fer.127.0.0.1.nip.io
- name: OIDC_CLIENT_ID
value: oidc-test-client
- name: OIDC_CLIENT_SECRET
value: oidc-test-secret
- name: OIDC_SCOPES
value: openid,uid,given_name,usual_name,email,siret
- name: EXTRA_ROOT_CA
value: {{ exec "mkcert" (list "-CAROOT") | trim | printf "%s/rootCA.pem" | readFile | quote }}
+31 -46
View File
@@ -5,57 +5,42 @@ image:
satosa:
replicas: 1
env:
- name: BASE_URL
value: https://oidc2fer.127.0.0.1.nip.io
- name: GUNICORN_CMD_ARGS
value: --workers=3
workingDir: /app/config/fer
envVars:
BASE_URL: https://oidc2fer.127.0.0.1.nip.io
GUNICORN_CMD_ARGS: --workers=3
- name: LOG_LEVEL
value: debug
LOG_LEVEL: debug
- name: SAML2_DISCOVERY_URL
value: https://discovery.renater.fr/test/
- name: SAML2_METADATA_URL
value: https://pub.federation.renater.fr/metadata/test/idps.xml
- name: SAML2_ENTITY_ID
value: https://oidc2fer.127.0.0.1.nip.io/Saml2/proxy_saml2_backend.xml
SAML2_DISCOVERY_URL: https://discovery.renater.fr/test/
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/test/preview/preview-idps-test-metadata.xml
SAML2_ENTITY_ID: https://oidc2fer.127.0.0.1.nip.io/Saml2/proxy_saml2_backend.xml
- name: STATE_ENCRYPTION_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
- name: SAML2_BACKEND_CERT
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
- name: SAML2_BACKEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
- name: OIDC_FRONTEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
STATE_ENCRYPTION_KEY: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
SAML2_BACKEND_CERT: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
SAML2_BACKEND_KEY: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
OIDC_FRONTEND_KEY: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
- name: OIDC_DB_URI
value: "stateless://:$(STATE_ENCRYPTION_KEY)@localhost"
- name: CLIENT_DB_JSON
value: |-
{
"oidc-test-client": {
"response_types": [
"id_token",
"code"
],
"redirect_uris": [
"https://oidc-test-client.traefik.me/redirect_uri",
"https://oidc-test-client.traefik.me:8443/redirect_uri",
"https://oidc-test-client.127.0.0.1.nip.io/redirect_uri"
],
"client_secret": "oidc-test-secret",
"token_endpoint_auth_method": "client_secret_post"
}
}
- name: SIRET_MAP
value: |-
{
"https://test-idp.federation.renater.fr/idp/shibboleth": "12345678200010"
OIDC_DB_URI: "redis://:pass@redis-master:6379"
CLIENT_DB_JSON: |-
{
"oidc-test-client": {
"response_types": [
"id_token",
"code"
],
"redirect_uris": [
"https://oidc-test-client.traefik.me/redirect_uri",
"https://oidc-test-client.traefik.me:8443/redirect_uri"
],
"client_secret": "oidc-test-secret",
"token_endpoint_auth_method": "client_secret_post"
}
}
SIRET_MAP: |-
{
"https://test-idp.federation.renater.fr/idp/shibboleth": "12345678200010"
}
ingress:
enabled: true
@@ -1,172 +1,116 @@
image:
repository: ghcr.io/proconnect-gouv/oidc2fer
pullPolicy: Always
tag: "v1.0.13"
tag: "v1.0.10"
satosa:
replicas: 2
env:
- name: BASE_URL
value: https://renater.agentconnect.gouv.fr
- name: GUNICORN_CMD_ARGS
value: --workers=3
envVars:
BASE_URL: https://renater.agentconnect.gouv.fr
GUNICORN_CMD_ARGS: --workers=3
- name: LOG_LEVEL
value: INFO
- name: LOG_LEVELS
value: '{ "satosa.backends.saml2": "DEBUG" }'
LOG_LEVEL: INFO
LOG_LEVELS: '{ "satosa.backends.saml2": "DEBUG" }'
- name: SAML2_DISCOVERY_URL
value: https://discovery.renater.fr/agentconnect/
- name: SAML2_METADATA_URL
value: https://pub.federation.renater.fr/metadata/fer/idps.xml
- name: SAML2_ENTITY_ID
value: https://renater.agentconnect.gouv.fr/Saml2/proxy_saml2_backend.xml
SAML2_DISCOVERY_URL: https://discovery.renater.fr/agentconnect/
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/renater/main/main-idps-renater-metadata.xml
SAML2_ENTITY_ID: https://renater.agentconnect.gouv.fr/Saml2/proxy_saml2_backend.xml
- name: STATE_ENCRYPTION_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
- name: SAML2_BACKEND_CERT
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
- name: SAML2_BACKEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
- name: OIDC_FRONTEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
- name: CLIENT_DB_JSON
valueFrom: { secretKeyRef: { name: oidc2fer, key: CLIENT_DB_JSON } }
STATE_ENCRYPTION_KEY: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
SAML2_BACKEND_CERT: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
SAML2_BACKEND_KEY: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
OIDC_FRONTEND_KEY: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
CLIENT_DB_JSON: { secretKeyRef: { name: oidc2fer, key: CLIENT_DB_JSON } }
- name: OIDC_DB_URI
value: "stateless://:$(STATE_ENCRYPTION_KEY)@localhost"
OIDC_DB_URI: { secretKeyRef: { name: redis.redis.libre.sh, key: url } }
# As provided by RENATER
- name: SIRET_MAP
value: |-
{
"http://idp.univ-poitiers.fr": "19860856400375",
"https://apps.univ-lr.fr/idp/shibboleth": "19170032700015",
"https://auth.sso.vet-alfort.fr/saml/metadata": "19940608300014",
"https://auth.uttop.fr/saml/metadata": "19650048200019",
"https://authentification.inrae.fr/saml/metadata/idp": "18007003901803",
"https://federation.ens.psl.eu/idp/shibboleth": "19753459700012",
"https://federation.umontpellier.fr/idp/shibboleth": "13002979600013",
"https://federation.unimes.fr/idp/shibboleth": "93249157400012",
"https://federation.upf.pf/idp/shibboleth": "19987001500013",
"https://federation.utbm.fr/idp/shibboleth": "19900356700013",
"https://federation3.univ-brest.fr/idp/shibboleth": "94129831700012",
"https://idauthproxy.insa-lyon.fr/Saml2IDP/metadata": "19690192000013",
"https://ident-shib.ensc-rennes.fr/idp/shibboleth": "19350077400016",
"https://identification.univ-toulouse.fr": "13002132200016",
"https://identites.ec-lyon.fr/idp/shibboleth": "19690187000010",
"https://identites.ensea.fr/idp/shibboleth": "19951376300011",
"https://identities.univ-jfc.fr/idp/prod": "19811201300018",
"https://idp-genci.renater.fr/idp/shibboleth": "49468697500041",
"https://idp-ng.univ-st-etienne.fr/idp/shibboleth": "93850168100010",
"https://idp-septa.onisep.fr/idp/shibboleth": "18004302800653",
"https://idp-v4.univ-montp3.fr/idp/shibboleth": "93249089900014",
"https://idp.bnu.fr/idp/shibboleth": "18004406700015",
"https://idp.cirad.fr/idp/shibboleth": "33159627000016",
"https://idp.crous-reims.fr/idp/shibboleth": "18510200100327",
"https://idp.ec-nantes.fr/idp/shibboleth": "19440100600011",
"https://idp.ehesp.fr/idp/shibboleth": "13000362700010",
"https://idp.ens-lyon.fr/idp/shibboleth": "13000812100019",
"https://idp.ensam.eu/idp/shibboleth": "19753472000010",
"https://idp.ensfea.fr/idp/shibboleth": "19310143300012",
"https://idp.ensma.fr/idp/shibboleth": "19860073600021",
"https://idp.ent.dauphine.fr/idp/shibboleth": "19754692200018",
"https://idp.imt-atlantique.fr/idp/shibboleth": "18009202500121",
"https://idp.inha.fr/idp/shibboleth": "19754688000018",
"https://idp.inp-toulouse.fr/idp/shibboleth": "19311381800127",
"https://idp.insa-rennes.fr/idp/shibboleth": "19350097200016",
"https://idp.institut-agro.fr/idp": "13002622200013",
"https://idp.isae.fr/idp/shibboleth": "13000427800011",
"https://idp.lyon.archi.fr/idp/shibboleth": "19690184700018",
"https://idp.renater.fr/idp/shibboleth": "18008947600055",
"https://idp.rennes.archi.fr/idp/shibboleth": "19350089900029",
"https://idp.sciencespo-lyon.fr/idp/shibboleth": "19690173000024",
"https://idp.sciencespobordeaux.fr/idp/shibboleth": "19330192600039",
"https://idp.uca.fr/idp/shibboleth": "13002806100013",
"https://idp.uha.fr/idp/shibboleth": "19681166500013",
"https://idp.unistra.fr/idp/shibboleth": "13000545700010",
"https://idp.univ-avignon.fr/idp/shibboleth": "19840685200204",
"https://idp.univ-cotedazur.fr/idp/shibboleth": "13002566100013",
"https://idp.univ-eiffel.fr/idp/shibboleth": "13002612300013",
"https://idp.univ-lemans.fr/idp/shibboleth": "19720916600010",
"https://idp.univ-lille.fr/idp/shibboleth": "13002975400012",
"https://idp.univ-lyon2.fr/idp/shibboleth": "19691775100014",
"https://idp.univ-lyon3.fr/idp/shibboleth": "19692437700282",
"https://idp.univ-orleans.fr/idp/shibboleth": "19450855200016",
"https://idp.univ-perp.fr/idp/shibboleth": "19660437500010",
"https://idp.univ-tln.fr/idp/shibboleth": "19830766200017",
"https://idp.univ-tlse3.fr/idp/shibboleth": "93827139200012",
"https://idp.univ-tours.fr/idp/shibboleth": "19370800500478",
"https://idp.universite-paris-saclay.fr/idp": "13002602400054",
"https://idp1.agroparistech.fr/idp/shibboleth": "13000285000134",
"https://idp1.ens-paris-saclay.fr/idp/shibboleth": "19940607500036",
"https://idp1.univ-fcomte.fr/idp/shibboleth": "93810656400017",
"https://idp2.amue.fr/idp/shibboleth": "18004312700091",
"https://idp2.brgm.fr/idp/shibboleth": "58205614900120",
"https://idp2.emse.fr/idp/shibboleth": "18009202500105",
"https://idp2.univ-paris8.fr/idp/shibboleth": "19931827000014",
"https://idp3.univ-lorraine.fr/idp/shibboleth": "13001550600012",
"https://idp3.ut-capitole.fr/idp/shibboleth": "13003061200019",
"https://idp4.unicaen.fr/idp/shibboleth": "19141408500016",
"https://idpv3.univ-amu.fr/idp/shibboleth": "13001533200013",
"https://janus.cnrs.fr/idp": "18008901303720",
"https://multipass.imt-nord-europe.fr/idp/shibboleth": "18009202500139",
"https://papangue.vetagro-sup.fr/idp/shibboleth": "13000858400018",
"https://prod-idp.inria.fr": "18008904700013",
"https://ruhnu.univ-tlse2.fr/idp/shibboleth": "19311383400017",
"https://shib.mines-albi.fr/idp/shibboleth": "18009202500097",
"https://shib.univ-lehavre.fr/idp/shibboleth": "19762762300097",
"https://identite.univ-reims.fr/idp/shibboleth": "19511296600799",
"https://shib2.unc.nc/idp/shibboleth": "13000322100012",
"https://shibboleth.ens2m.fr/idp/shibboleth": "19250082500026",
"https://shibboleth.grenoble-inp.fr/idp/shibboleth": "19381912500017",
"https://shibboleth.insa-rouen.fr/idp/shibboleth": "19760165100023",
"https://shibboleth.ube.fr/idp/shibboleth": "93823061200013",
"https://shibboleth.univ-corse.fr/idp/shibboleth": "19202664900264",
"https://shibboleth.univ-evry.fr/idp/shibboleth": "19911975100014",
"https://shibboleth.univ-grenoble-alpes.fr/idp/shibboleth": "13002608100013",
"https://shibboleth.univ-savoie.fr/idp/shibboleth": "19730858800015",
"https://shibboleth03.chartes.psl.eu/idp/shibboleth": "19753478700043",
"https://shibboleth3.utt.fr/idp/shibboleth": "19101060200032",
"https://srv-fii.insa-toulouse.fr/idp/shibboleth": "19310152400018",
"https://sso-ciation-saclay.centralesupelec.fr/idp/shibboleth": "13002076100016",
"https://sso.bordeaux-inp.fr/idp/shibboleth": "13000635600013",
"https://sso.ird.fr/idp/shibboleth": "18000602500159",
"https://upnidp2.parisnanterre.fr/idp/shibboleth": "19921204400010",
"https://vip.espci.fr/saml2/idp/metadata.php": "20000068500012",
"urn:mace:cru.fr:federation:uhb.fr": "19350937900015",
"urn:mace:cru.fr:federation:unilim.fr": "19870669900321",
"urn:mace:cru.fr:federation:univ-nantes.fr": "13002974700016",
"urn:mace:cru.fr:federation:univ-paris1.fr": "19751717000019",
"urn:mace:cru.fr:federation:univ-rennes1.fr": "13003051300019",
"urn:mace:cru.fr:federation:univ-rouen.fr": "19761904200017",
"urn:mace:cru.fr:federation:univ-ubs.fr": "19561718800600",
"https://idp.marseille.archi.fr/idp/shibboleth": "19130236300020",
"https://idp.inalco.fr/idp/shibboleth": "19753488600092",
"https://idp.sigma-clermont.fr/idp/shibboleth": "13002191800011",
"https://idp.univ-artois.fr/idp/shibboleth": "19624401600016",
"https://idp2.ensai.fr/idp/shibboleth": "13001422800055",
"urn:mace:cru.fr:federation:univ-lyon1.fr": "19691774400019",
"https://idp.enitab.fr/idp/shibboleth": "19330203100011",
"https://idp.oca.eu/idp/shibboleth": "19061563300012",
"https://idp.univ-paris13.fr/idp/shibboleth": "19931238000017",
"https://idp.ens-rennes.fr/idp/shibboleth": "13001848400019",
"https://idp.uphf.fr/idp/shibboleth": "13002574500014",
"https://idp.college-de-france.fr/idp/shibboleth": "19753480300014",
"https://shibboleth.csi.uvsq.fr/idp/shibboleth": "19781944400013",
"https://idp.esaip.org/idp/shibboleth": "37920438100014",
"https://idp.eskn.fr/idp/shibboleth": "13002617200010",
"https://auth.centrale-marseille.fr/idp/shibboleth": "19133340000015",
"https://idp-insa-cvl.renater.fr/idp/shibboleth": "13001833600011",
"https://shibboleth3.obspm.fr/idp/shibboleth": "19753496900013",
"https://idp-ecole-air.renater.fr/idp/shibboleth": "13002454000010",
"https://idp.enpc.fr/saml/metadata": "19753501600020",
"https://idp.paris-malaquais.archi.fr/idp/shibboleth": "18009221500011",
"https://idp.univ-pau.fr/idp/shibboleth": "19640251500270",
"https://idp4.cereq.fr/idp/shibboleth": "18004303600037",
"urn:mace:cru.fr:federation:univ-angers.fr": "19490970100303"
}
# As provided by RENATER on 2025-09-19
SIRET_MAP: |-
{
"https://shibboleth.grenoble-inp.fr/idp/shibboleth": "19381912500017",
"https://identites.ensea.fr/idp/shibboleth": "19951376300011",
"https://idp.ent.dauphine.fr/idp/shibboleth": "19754692200018",
"https://idp.univ-lyon2.fr/idp/shibboleth": "19691775100014",
"https://shibboleth.insa-rouen.fr/idp/shibboleth": "19760165100023",
"https://idp1.univ-fcomte.fr/idp/shibboleth": "93810656400017",
"https://idp.univ-tours.fr/idp/shibboleth": "19370800500478",
"https://apps.univ-lr.fr/idp/shibboleth": "19170032700015",
"https://shib.mines-albi.fr/idp/shibboleth": "18009202500097",
"https://federation.upf.pf/idp/shibboleth": "19987001500013",
"https://federation.utbm.fr/idp/shibboleth": "19900356700013",
"urn:mace:cru.fr:federation:univ-paris1.fr": "19751717000019",
"https://idp.sciencespobordeaux.fr/idp/shibboleth": "19330192600039",
"https://vip.espci.fr/saml2/idp/metadata.php": "20000068500012",
"urn:mace:cru.fr:federation:univ-nantes.fr": "13002974700016",
"https://shibboleth.univ-corse.fr/idp/shibboleth": "19202664900264",
"https://srv-fii.insa-toulouse.fr/idp/shibboleth": "19310152400018",
"urn:mace:cru.fr:federation:univ-rouen.fr": "19761904200017",
"https://ident-shib.ensc-rennes.fr/idp/shibboleth": "19350077400016",
"urn:mace:cru.fr:federation:unilim.fr": "19870669900321",
"https://idp.inha.fr/idp/shibboleth": "19754688000018",
"https://federation.unimes.fr/idp/shibboleth": "93249157400012",
"urn:mace:cru.fr:federation:univ-rennes1.fr": "13003051300019",
"urn:mace:cru.fr:federation:univ-ubs.fr": "19561718800600",
"https://idp.univ-orleans.fr/idp/shibboleth": "19450855200016",
"https://shibboleth.univ-savoie.fr/idp/shibboleth": "19730858800015",
"https://idp.cirad.fr/idp/shibboleth": "33159627000016",
"https://sso.ird.fr/idp/shibboleth": "18000602500159",
"https://idp.ensma.fr/idp/shibboleth": "19860073600021",
"https://idp.renater.fr/idp/shibboleth": "18008947600055",
"https://idp.inp-toulouse.fr/idp/shibboleth": "19311381800127",
"https://idp.unistra.fr/idp/shibboleth": "13000545700010",
"https://idp1.agroparistech.fr/idp/shibboleth": "13000285000134",
"https://janus.cnrs.fr/idp": "18008901303720",
"https://federation.umontpellier.fr/idp/shibboleth": "13002979600013",
"https://idp.sciencespo-lyon.fr/idp/shibboleth": "19690173000024",
"https://shibboleth.univ-grenoble-alpes.fr/idp/shibboleth": "13002608100013",
"https://idp.bnu.fr/idp/shibboleth": "18004406700015",
"https://ruhnu.univ-tlse2.fr/idp/shibboleth": "19311383400017",
"https://idp2.amue.fr/idp/shibboleth": "18004312700091",
"https://idpv3.univ-amu.fr/idp/shibboleth": "13001533200013",
"https://idp-ng.univ-st-etienne.fr/idp/shibboleth": "93850168100010",
"https://identities.univ-jfc.fr/idp/prod": "19811201300018",
"https://idp3.univ-lorraine.fr/idp/shibboleth": "13001550600012",
"https://idp.univ-lemans.fr/idp/shibboleth": "19720916600010",
"https://idp.univ-lille.fr/idp/shibboleth": "13002975400012",
"https://idp.univ-tln.fr/idp/shibboleth": "19830766200017",
"https://idp.uca.fr/idp/shibboleth": "13002806100013",
"https://shibboleth3.utt.fr/idp/shibboleth": "19101060200032",
"https://idp3.ut-capitole.fr/idp/shibboleth": "13003061200019",
"https://idp.imt-atlantique.fr/idp/shibboleth": "18009202500121",
"https://shib.univ-lehavre.fr/idp/shibboleth": "19762762300097",
"https://idp2.univ-paris8.fr/idp/shibboleth": "19931827000014",
"https://shib2.unc.nc/idp/shibboleth": "13000322100012",
"https://upnidp2.parisnanterre.fr/idp/shibboleth": "19921204400010",
"https://idp.ensfea.fr/idp/shibboleth": "19310143300012",
"https://idp.univ-eiffel.fr/idp/shibboleth": "13002612300013",
"https://idp.insa-rennes.fr/idp/shibboleth": "19350097200016",
"https://idp.univ-tlse3.fr/idp/shibboleth": "93827139200012",
"https://idp.universite-paris-saclay.fr/idp": "13002602400054",
"https://shibboleth.ens2m.fr/idp/shibboleth": "19250082500026",
"https://sso-ciation-saclay.centralesupelec.fr/idp/shibboleth": "13002076100016",
"https://federation.ens.psl.eu/idp/shibboleth": "19753459700012",
"https://authentification.inrae.fr/saml/metadata/idp": "18007003901803",
"https://idp.ensam.eu/idp/shibboleth": "19753472000010",
"https://idp1.ens-paris-saclay.fr/idp/shibboleth": "19940607500036",
"https://idp2.emse.fr/idp/shibboleth": "18009202500105",
"https://idp-septa.onisep.fr/idp/shibboleth": "18004302800653",
"https://papangue.vetagro-sup.fr/idp/shibboleth": "13000858400018",
"https://multipass.imt-nord-europe.fr/idp/shibboleth": "18009202500139",
"https://idp4.unicaen.fr/idp/shibboleth": "19141408500016",
"https://sso.bordeaux-inp.fr/idp/shibboleth": "13000635600013",
"https://auth.uttop.fr/saml/metadata": "19650048200019",
"https://idp.univ-cotedazur.fr/idp/shibboleth": "13002566100013",
"https://idp2.brgm.fr/idp/shibboleth": "58205614900120",
"https://idp.crous-reims.fr/idp/shibboleth": "18510200100327",
"https://idp.univ-avignon.fr/idp/shibboleth": "19840685200204",
"https://idp-genci.renater.fr/idp/shibboleth": "49468697500041",
"https://auth.sso.vet-alfort.fr/saml/metadata": "19940608300014",
"https://idp.univ-perp.fr/idp/shibboleth": "19660437500010",
"https://idp.institut-agro.fr/idp": "13002622200013",
"https://prod-idp.inria.fr": "18008904700013",
"https://idp.ec-nantes.fr/idp/shibboleth": "19440100600011"
}
ingress:
enabled: true
@@ -5,43 +5,30 @@ image:
satosa:
replicas: 2
env:
- name: BASE_URL
value: https://oidc2fer-staging.beta.numerique.gouv.fr
- name: GUNICORN_CMD_ARGS
value: --workers=3
workingDir: /app/config/fer
envVars:
BASE_URL: https://oidc2fer-staging.beta.numerique.gouv.fr
GUNICORN_CMD_ARGS: --workers=3
- name: LOG_LEVEL
value: DEBUG
- name: LOG_LEVELS
value: '{ "satosa.backends.saml2": "DEBUG" }'
LOG_LEVEL: DEBUG
LOG_LEVELS: '{ "satosa.backends.saml2": "DEBUG" }'
- name: SAML2_DISCOVERY_URL
value: https://discovery.renater.fr/test/
- name: SAML2_METADATA_URL
value: https://pub.federation.renater.fr/metadata/test/idps.xml
- name: SAML2_ENTITY_ID
value: https://oidc2fer-staging.beta.numerique.gouv.fr/Saml2/proxy_saml2_backend.xml-test
SAML2_DISCOVERY_URL: https://discovery.renater.fr/test/
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/test/preview/preview-idps-test-metadata.xml
SAML2_ENTITY_ID: https://oidc2fer-staging.beta.numerique.gouv.fr/Saml2/proxy_saml2_backend.xml-test
- name: STATE_ENCRYPTION_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
- name: SAML2_BACKEND_CERT
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
- name: SAML2_BACKEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
- name: OIDC_FRONTEND_KEY
valueFrom: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
- name: CLIENT_DB_JSON
valueFrom: { secretKeyRef: { name: oidc2fer, key: CLIENT_DB_JSON } }
STATE_ENCRYPTION_KEY: { secretKeyRef: { name: oidc2fer, key: STATE_ENCRYPTION_KEY } }
SAML2_BACKEND_CERT: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_CERT } }
SAML2_BACKEND_KEY: { secretKeyRef: { name: oidc2fer, key: SAML2_BACKEND_KEY } }
OIDC_FRONTEND_KEY: { secretKeyRef: { name: oidc2fer, key: OIDC_FRONTEND_KEY } }
CLIENT_DB_JSON: { secretKeyRef: { name: oidc2fer, key: CLIENT_DB_JSON } }
- name: OIDC_DB_URI
value: "stateless://:$(STATE_ENCRYPTION_KEY)@localhost"
OIDC_DB_URI: { secretKeyRef: { name: redis.redis.libre.sh, key: url } }
- name: SIRET_MAP
value: |-
{
"https://test-idp.federation.renater.fr/idp/shibboleth": "12345678200010"
}
SIRET_MAP: |-
{
"https://test-idp.federation.renater.fr/idp/shibboleth": "12345678200010"
}
ingress:
enabled: true
+5
View File
@@ -0,0 +1,5 @@
apiVersion: v2
name: extra
description: A Helm chart to add some manifests to oidc2fer
type: application
version: 0.1.0
+7
View File
@@ -0,0 +1,7 @@
apiVersion: core.libre.sh/v1alpha1
kind: Redis
metadata:
name: redis
namespace: {{ .Release.Namespace | quote }}
spec:
disableAuth: false
+29 -8
View File
@@ -4,11 +4,21 @@ environments:
- version: 0.0.1
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
cnb-dev:
values:
- version: 0.0.1
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
staging:
values:
- version: 0.0.1
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
cnb-staging:
values:
- version: 0.0.1
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
outscale-production:
values:
- version: 0.0.1
@@ -21,6 +31,25 @@ repositories:
oci: true
releases:
- name: redis
installed: {{ or (eq .Environment.Name "dev") (eq .Environment.Name "cnb-dev") | toYaml }}
namespace: {{ .Namespace }}
chart: bitnami/redis
version: 18.19.2
values:
- auth:
password: pass
architecture: standalone
image:
repository: bitnamilegacy/redis
- name: extra
installed: {{ and (ne .Environment.Name "dev") (ne .Environment.Name "cnb-dev") | toYaml }}
namespace: {{ .Namespace }}
chart: ./extra
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
- name: oidc2fer
version: {{ .Values.version }}
namespace: {{ .Namespace }}
@@ -29,11 +58,3 @@ releases:
- env.d/{{ .Environment.Name }}/values.oidc2fer.yaml.gotmpl
secrets:
- env.d/{{ .Environment.Name }}/secrets.enc.yaml
- name: oidc-test-client
installed: {{ eq .Environment.Name "dev" }}
version: {{ .Values.version }}
namespace: {{ .Namespace }}
chart: ./oidc-test-client
values:
- env.d/{{ .Environment.Name }}/values.oidc-test-client.yaml.gotmpl
-24
View File
@@ -1,24 +0,0 @@
apiVersion: v2
name: oidc-test-client
description: Test OIDC client
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"
@@ -1,51 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "oidc-test-client.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "oidc-test-client.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "oidc-test-client.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "oidc-test-client.labels" -}}
helm.sh/chart: {{ include "oidc-test-client.chart" . }}
{{ include "oidc-test-client.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "oidc-test-client.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oidc-test-client.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
@@ -1,71 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "oidc-test-client.fullname" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "oidc-test-client.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "oidc-test-client.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "oidc-test-client.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
{{ with .Values.livenessProbe }}
livenessProbe: {{ toJson . }}
{{- end }}
{{ with .Values.readinessProbe }}
readinessProbe: {{ toJson . }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.env }}
env:
{{- toYaml . | nindent 12 }}
{{- end }}
command:
- sh
- -ec
- |-
printenv EXTRA_ROOT_CA >> $(python -m certifi)
exec python app.py
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -1,38 +0,0 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "oidc-test-client.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "oidc-test-client.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.className }}
{{- if .Values.ingress.tls.enabled }}
tls:
{{- if .Values.ingress.host }}
- secretName: {{ $fullName }}-tls
hosts:
- {{ .Values.ingress.host | quote }}
{{- end }}
{{- end }}
rules:
{{- if .Values.ingress.host }}
- host: {{ .Values.ingress.host | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
@@ -1,16 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "oidc-test-client.fullname" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "oidc-test-client.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "oidc-test-client.selectorLabels" . | nindent 4 }}
-71
View File
@@ -1,71 +0,0 @@
# Default values for oidc-test-client.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: oidc-test-client
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
podAnnotations: {}
podLabels: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 5000
ingress:
enabled: true
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts: []
tls:
enabled: true
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
livenessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 30
readinessProbe: null
nodeSelector: {}
tolerations: []
affinity: {}
env: []
+40
View File
@@ -50,6 +50,46 @@ app.kubernetes.io/name: {{ include "oidc2fer.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
transform dictionnary of environment variables
Usage : {{ include "oidc2fer.env.transformDict" .Values.envVars }}
Example:
envVars:
# Using simple strings as env vars
ENV_VAR_NAME: "envVar value"
# Using a value from a configMap
ENV_VAR_FROM_CM:
configMapKeyRef:
name: cm-name
key: "key_in_cm"
# Using a value from a secret
ENV_VAR_FROM_SECRET:
secretKeyRef:
name: secret-name
key: "key_in_secret"
*/}}
{{- define "oidc2fer.env.transformDict" -}}
{{- range $key, $value := . }}
- name: {{ $key | quote }}
{{- if $value | kindIs "map" }}
valueFrom: {{ $value | toYaml | nindent 4 }}
{{- else }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{/*
oidc2fer env vars
*/}}
{{- define "oidc2fer.common.env" -}}
{{- $topLevelScope := index . 0 -}}
{{- $workerScope := index . 1 -}}
{{- include "oidc2fer.env.transformDict" $workerScope.envVars -}}
{{- end }}
{{/*
Common labels
@@ -1,3 +1,4 @@
{{- $envVars := include "oidc2fer.common.env" (list . .Values.satosa) -}}
{{- $fullName := include "oidc2fer.satosa.fullname" . -}}
{{- $component := "satosa" -}}
apiVersion: apps/v1
@@ -37,13 +38,17 @@ spec:
command:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.satosa.workingDir }}
workingDir: {{ . | quote }}
{{- end }}
{{- with .Values.satosa.args }}
args:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.satosa.env }}
env: {{ toJson . }}
{{- end }}
env:
{{- if $envVars}}
{{- $envVars | indent 12 }}
{{- end }}
{{- with .Values.satosa.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
@@ -1,3 +1,4 @@
{{- $envVars := include "oidc2fer.common.env" (list . .Values.satosa) -}}
{{- $fullName := include "oidc2fer.satosa.fullname" . -}}
{{- $component := "satosa" -}}
apiVersion: v1
+1
View File
@@ -5,6 +5,7 @@ metadata:
namespace: {{ .Release.Namespace | quote }}
stringData:
STATE_ENCRYPTION_KEY: {{ .Values.STATE_ENCRYPTION_KEY | quote }}
SAML2_IDP_METADATA: {{ .Values.SAML2_IDP_METADATA | toYaml | indent 8 }}
SAML2_BACKEND_CERT: {{ .Values.SAML2_BACKEND_CERT | toYaml | indent 8 }}
SAML2_BACKEND_KEY: {{ .Values.SAML2_BACKEND_KEY | toYaml | indent 8 }}
OIDC_FRONTEND_KEY: {{ .Values.OIDC_FRONTEND_KEY | toYaml | indent 8 }}
+13 -2
View File
@@ -21,6 +21,10 @@ image:
nameOverride: ""
fullnameOverride: ""
## @skip commonEnvVars
commonEnvVars: &commonEnvVars
<<: []
## @param ingress.enabled whether to enable the Ingress or not
## @param ingress.className IngressClass to use for the Ingress
## @param ingress.host Host for the Ingress
@@ -75,8 +79,15 @@ satosa:
## @param satosa.securityContext Configure satosa Pod security context
securityContext: null
## @param satosa.env Configure satosa container environment variables
env: []
## @param satosa.envVars Configure satosa container environment variables
## @extra satosa.envVars.BY_VALUE Example environment variable by setting value directly
## @extra satosa.envVars.FROM_CONFIGMAP.configMapKeyRef.name Name of a ConfigMap when configuring env vars from a ConfigMap
## @extra satosa.envVars.FROM_CONFIGMAP.configMapKeyRef.key Key within a ConfigMap when configuring env vars from a ConfigMap
## @extra satosa.envVars.FROM_SECRET.secretKeyRef.name Name of a Secret when configuring env vars from a Secret
## @extra satosa.envVars.FROM_SECRET.secretKeyRef.key Key within a Secret when configuring env vars from a Secret
## @skip satosa.envVars
envVars:
<<: *commonEnvVars
## @param satosa.podAnnotations Annotations to add to the satosa Pod
podAnnotations: {}
@@ -0,0 +1,24 @@
attributes:
givenname:
openid:
- given_name
saml:
- cnb_prenom
email:
openid:
- email
saml:
- cnb_email
usual_name:
openid:
- usual_name
saml:
- cnb_nom
acr:
openid:
- acr
uid:
openid:
- uid
saml:
- cnb_id
@@ -0,0 +1,49 @@
module: satosa.backends.saml2.SAMLBackend
name: Saml2
config:
entityid_endpoint: true
mirror_force_authn: false
memorize_idp: false
use_memorized_idp_when_force_authn: false
send_requester_id: false
enable_metadata_reload: false
acs_selection_strategy: prefer_matching_host
sp_config:
name: Passerelle ProConnect vers CNB
description: Passerelle ProConnect vers CNB
key_file: /tmp/backend.key
cert_file: /tmp/backend.crt
organization:
name: DINUM
display_name: DINUM
url: https://beta.gouv.fr/incubateurs/dinum_produits_interministeriels.html
metadata:
local:
- /tmp/idp_metadata.xml
entityid: !ENV SAML2_ENTITY_ID
accepted_time_diff: 60
allow_unknown_attributes: true
service:
sp:
ui_info:
display_name:
- lang: fr
text: Passerelle ProConnect vers CNB
logo:
text: https://beta.gouv.fr/img/incubators/logo_dinum.png
width: '200'
height: '200'
authn_requests_signed: true
want_response_signed: false
want_assertions_signed: false
want_assertions_or_response_signed: true
signing_algorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
allow_unsolicited: true
name_id_format:
- urn:oasis:names:tc:SAML:2.0:nameid-format:transient
endpoints:
assertion_consumer_service:
- - <base_url>/<name>/acs/post
- 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
name_id_format_allow_create: true
@@ -0,0 +1,58 @@
module: oidc2fer.frontends.jwt_userinfo_openid_connect.JWTUserInfoOpenIDConnectFrontend
name: OIDC
config:
signing_key_path: /tmp/frontend.key
signing_key_id: frontend.key1
# Defines the database connection URI for the databases:
# - authz_code_db
# - access_token_db
# - refresh_token_db
# - sub_db
# - user_db
#
# supported storage backends:
# - In-memory dictionary
# - MongoDB (e.g. mongodb://db.example.com)
# - Redis (e.g. redis://example/0)
# - Stateless (eg. stateless://user:encryptionkey?alg=aes256)
#
# This configuration is optional.
# By default, the in-memory storage is used.
db_uri: !ENV OIDC_DB_URI
# Where to store clients.
#
# If client_db_uri is set, the database connection is used.
# Otherwise, if client_db_path is set, the JSON file is used.
# By default, an in-memory dictionary is used.
# client_db_uri: mongodb://db.example.com
client_db_path: /tmp/client_db.json
# if not specified, it is randomly generated on every startup
sub_hash_salt: randomSALTvalue
sub_mirror_public: yes
provider:
client_registration_supported: no
response_types_supported: ["code", "id_token token"]
subject_types_supported: ["public"]
scopes_supported:
- openid
- email
- uid
- given_name
- usual_name
# Set code/token lifetimes as short as possible
authorization_code_lifetime: 60
access_token_lifetime: 60
id_token_lifetime: 60
extra_scopes:
uid:
- uid
given_name:
- given_name
usual_name:
- usual_name
@@ -0,0 +1,12 @@
module: satosa.micro_services.attribute_processor.AttributeProcessor
name: AttributeProcessor
config:
process:
# Internally SATOSA represents most attributes as lists of strings.
# The SATOSA OIDC frontend automatically flattens standard OIDC attributes
# (like 'given_name' or 'email') to single strings when possible, but
# doesn't do that for custom attributes (like 'usual_name').
- attribute: usual_name
processors:
- module: oidc2fer.attribute_processors.flattening_processor
name: FlatteningProcessor
@@ -0,0 +1,22 @@
module: satosa.micro_services.primary_identifier.PrimaryIdentifier
name: PrimaryIdentifier
config:
# The ordered identifier candidates are searched in order
# to find a candidate primary identifier. The search ends
# when the first candidate is found. The identifier or attribute
# names are the internal SATOSA names for the attributes as
# defined in internal_attributes.yaml.
ordered_identifier_candidates:
- attribute_names: [uid]
# The internal SATOSA attribute into which to place the primary
# identifier value once found from the above configured ordered
# candidates.
primary_identifier: uid
# Whether or not to clear the input attributes after setting the
# primary identifier value.
clear_input_attributes: no
# Whether to replace subject_id with the constructed primary identifier
replace_subject_id: yes
@@ -0,0 +1,7 @@
module: satosa.micro_services.attribute_modifications.AddStaticAttributes
name: AddAttributes
config:
static_attributes:
acr: eidas1
# FIXME temporary hardcoded email for testing
email: ["test@cnb.avocat.fr"] # SATOSA wants this to be an array
+22
View File
@@ -0,0 +1,22 @@
BASE: !ENV BASE_URL
COOKIE_STATE_NAME: SATOSA_STATE
CONTEXT_STATE_DELETE: 'yes'
STATE_ENCRYPTION_KEY: !ENV STATE_ENCRYPTION_KEY
cookies_samesite_compat:
- - SATOSA_STATE
- SATOSA_STATE_LEGACY
INTERNAL_ATTRIBUTES: internal_attributes.yaml
BACKEND_MODULES:
- plugins/backends/saml2_backend.yaml
FRONTEND_MODULES:
- plugins/frontends/openid_connect_frontend.yaml
- plugins/frontends/ping_frontend.yaml
MICRO_SERVICES:
- plugins/microservices/primary_identifier.yaml
- plugins/microservices/static_attributes.yaml
- plugins/microservices/attribute_processor.yaml
LOGGING:
# All the logging configuration is done in the Gunicorn config, this is just
# here to avoid overwriting it with the default SATOSA config
version: 1
incremental: true

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+9
View File
@@ -0,0 +1,9 @@
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="1; url=https://proconnect.gouv.fr/">
</head>
<body>
<h1>Passerelle ProConnect vers CNB. Redirection en cours…</h1>
</body>
</html>
@@ -0,0 +1,3 @@
module: satosa.frontends.ping.PingFrontend
name: ping
config: null
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

+21 -11
View File
@@ -11,23 +11,30 @@ version = "0.1.0"
authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: End Users/Desktop",
"Intended Audience :: System Administrators",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.11",
]
description = "A gateway from RENATER's FER to ProConnect's OIDC provider, built on top of SATOSA."
description = "An application to handle contacts and teams."
keywords = ["OIDC", "SAML", "Shibboleth", "FER", "RENATER"]
license = { file = "LICENSE" }
readme = "README.md"
requires-python = ">=3.14"
requires-python = ">=3.11"
dependencies = [
"SATOSA==8.5.1",
"gunicorn==25.1.0",
"JSON-log-formatter==1.1.1",
"WhiteNoise==6.12.0",
"gunicorn==23.0.0",
"redis==5.0.4",
"JSON-log-formatter==1.0",
"WhiteNoise==6.7.0",
# Use the most recent pysaml2 that doesn't have the recurrence of
# https://github.com/IdentityPython/pysaml2/issues/819
# (AuthNRequests signed twice)
"pysaml2==7.1.0",
# Pin xmlschema like pysaml2 did in release 7.5.1, see
# https://github.com/IdentityPython/pysaml2/issues/947#issuecomment-1916767026
"xmlschema==2.5.1",
]
[project.urls]
@@ -40,15 +47,18 @@ dependencies = [
dev = [
"pylint==3.1.0",
"pytest-cov==4.1.0",
"pytest==9.0.2",
"ruff==0.15.4",
"pytest-playwright==0.7.2",
"pytest==8.0.2",
"ruff==0.2.2",
"pytest-playwright==0.4.4",
]
[tool.setuptools]
packages = { find = { where = ["."], exclude = ["tests"] } }
zip-safe = true
[tool.distutils.bdist_wheel]
universal = true
[tool.ruff]
exclude = [
".git",
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env python
"""Setup file for the oidc2fer module. All configuration stands in the setup.cfg file."""
# coding: utf-8
from setuptools import setup
setup()
+6 -46
View File
@@ -1,9 +1,5 @@
import concurrent.futures
import json
import logging
import os
import time
import urllib.request
import pytest
from playwright.sync_api import Browser, Page, expect
@@ -36,7 +32,7 @@ def oidc_to_renater(
expected_given_name="Georges",
expected_usual_name="Grospieds",
):
page.goto("https://oidc-test-client.127.0.0.1.nip.io")
page.goto("https://oidc-test-client.traefik.me")
renater_wayf(page)
renater_test_idp(page, login=login)
@@ -45,7 +41,6 @@ def oidc_to_renater(
result = json.loads(text)
id_token = result["access_token_response"]["id_token"]
access_token = result["access_token_response"]["access_token"]
assert {"acr": "eidas1"}.items() <= id_token.items()
userinfo = result["userinfo"]
assert {
@@ -56,7 +51,7 @@ def oidc_to_renater(
"usual_name": expected_usual_name,
"siret": "12345678200010",
}.items() <= userinfo.items()
return id_token, access_token
return id_token
@pytest.mark.skipif(
@@ -64,53 +59,18 @@ def oidc_to_renater(
)
def test_oidc_to_renater_keeps_sub(browser: Browser):
with browser.new_context().new_page() as page:
id_token1, _ = oidc_to_renater(page)
id_token1 = oidc_to_renater(page)
with browser.new_context().new_page() as page:
id_token2, _ = oidc_to_renater(page)
id_token2 = oidc_to_renater(page)
assert id_token1["sub"] == id_token2["sub"]
@pytest.mark.skipif(
"BENCH_E2E" not in os.environ, reason="Benchmark runs only if requested"
)
def test_benchmark_userinfo(browser: Browser):
with browser.new_context().new_page() as page:
_, access_token = oidc_to_renater(page)
request_count = int(os.environ.get("BENCH_E2E_N", "100"))
client_count = int(os.environ.get("BENCH_E2E_P", "2"))
start = time.time()
def make_request():
return urllib.request.urlopen(
urllib.request.Request(
"https://oidc2fer.127.0.0.1.nip.io/OIDC/userinfo",
headers={"Authorization": f"Bearer {access_token}"},
)
)
with concurrent.futures.ThreadPoolExecutor(max_workers=client_count) as executor:
futures = []
for _ in range(request_count):
futures.append(executor.submit(make_request))
for future in concurrent.futures.as_completed(futures):
with future.result() as resp:
assert resp.status == 200
end = time.time()
logging.info(
"Average userinfo request time with %d parallel requests: \
%.2f seconds",
client_count,
(end - start) / request_count,
)
@pytest.mark.skipif(
"TEST_E2E" not in os.environ, reason="Depends on app running locally"
)
def test_oidc_to_renater_student_not_allowed(page: Page):
page.goto("https://oidc-test-client.127.0.0.1.nip.io")
page.goto("https://oidc-test-client.traefik.me")
renater_wayf(page)
renater_test_idp(page, login="etudiant1")
@@ -175,5 +135,5 @@ def test_pro_connect_to_renater_student_not_allowed(page: Page):
"TEST_E2E" not in os.environ, reason="Depends on app running locally"
)
def test_serve_static_assets(page: Page):
page.goto("https://oidc2fer.127.0.0.1.nip.io/images/logo.svg")
page.goto("https://satosa.traefik.me/images/logo.svg")
expect(page.locator("svg")).to_be_visible()
+5 -14
View File
@@ -26,8 +26,7 @@ fi
# https://github.com/kubernetes-sigs/kind/issues/2875
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
kind --name=oidc2fer delete cluster || true
cat <<EOF | kind --name=oidc2fer create cluster --config=-
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
@@ -36,6 +35,7 @@ containerdConfigPatches:
config_path = "/etc/containerd/certs.d"
nodes:
- role: control-plane
image: kindest/node:v1.27.3
kubeadmConfigPatches:
- |
kind: InitConfiguration
@@ -50,7 +50,9 @@ nodes:
hostPort: 443
protocol: TCP
- role: worker
image: kindest/node:v1.27.3
- role: worker
image: kindest/node:v1.27.3
EOF
# 3. Add the registry config to the nodes
@@ -62,7 +64,7 @@ EOF
# We want a consistent name that works from both ends, so we tell containerd to
# alias localhost:${reg_port} to the registry container when pulling images
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
for node in $(kind --name=oidc2fer get nodes); do
for node in $(kind get nodes); do
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
[host."http://${reg_name}:5000"]
@@ -89,17 +91,6 @@ data:
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
# Patch the CoreDNS configmap to rewrite requests for *.127.0.0.1.nip.io to the Ingress Controller service
kubectl -n kube-system get configmap coredns -o yaml |
yq '.data.Corefile |= (
trim
| split("\n")
| .[-1] = " rewrite name regex .*\\.127\\.0\\.0\\.1\\.nip\\.io ingress-nginx-controller.ingress-nginx.svc.cluster.local answer auto\n"
+ .[-1]
| join("\n")
)' |
kubectl replace -f -
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
kubectl -n ingress-nginx create secret tls mkcert --key /tmp/127.0.0.1.nip.io+1-key.pem --cert /tmp/127.0.0.1.nip.io+1.pem
kubectl -n ingress-nginx patch deployments.apps ingress-nginx-controller --type 'json' -p '[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--default-ssl-certificate=ingress-nginx/mkcert"}]'