You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+75-27
Original file line number
Diff line number
Diff line change
@@ -1,24 +1,28 @@
1
1
# SATOSA based SAML to Kanidm OIDC proxy
2
2
3
3
i.e. How to connect legacy web apps that only support SAML to be backed by Kanidm OIDC. While the configs in this repo can be educational for rolling your own SATOSA setup, an opinionated ENV configurable container image is also provided.
4
+
This example on purpose only supports a 1:1 proxy config where a single SAML supporting web service auths via a single OIDC endpoint. To limit blast radius, just deploy multiple if you have multiple SAML-only services.
4
5
5
-
> [!CAUTION]
6
-
> This is an early version that only supports a 1:1 proxy config where a single SAML supporting web service auths via a single OIDC endpoint.
7
-
> The intent is to morph into a "v2" that allows a dynamic mapping of multiple systems to multiple OIDC endpoints via a single SAML proxy. The simpler version will be preserved for educational purposes but is intended to become "legacy".
6
+
> [!NOTE]
7
+
> If you want to just skip to the part where we use this with Kanidm, you could jump straight to the practical example: [Ceph SSO via Kanidm](#practical-example-ceph-sso-via-kanidm)
8
8
9
9
## TODO items on the roadmap
10
-
1. Add log level configuration via ENV. It's now hardcoded to debug.
11
-
2. Rewrite env config & the SATOSA configs for dynamic routing so that multiple apps can be routed to different OIDC clients. In the meanwhile you can configure multiple apps to use the same proxy, but then you can't control via claim maps on the Kanidm side who is eligible for what app.
12
-
3. Get rid of the idpyoidc PR fork use once they no longer force RS256.
10
+
1. Get rid of the idpyoidc git build once there's a release that contains ES256 support.
11
+
2. Get rid of any manual jiggery with idpyoidc once SATOSA requires a sufficiently high version to support ES256.
13
12
14
13
## The container
15
14
16
15
The container built at `ghcr.io/jinnatar/satosa-saml-proxy:latest` is a proof of concept using the SATOSA configs in the repo. The guides below will assume you are using it, but nothing prevents you from using the same configs and ENV config with any other supported SATOSA installation method. I am using the container myself in my environment and have a vested interest in keeping it going and tested.
17
16
18
-
The caveats with the container and/or trying to go without it:
19
-
- The currently released version of SATOSA, 8.4.0 is over a year old and does not include their new and improved OIDC module. The better module is required for PKCE support, which is why the container is built from their git HEAD instead of a release.
20
-
- The main dependency for their new OIDC module is idpy-oidc. Unfortunately it has an issue that prevents using ES256 for signing. The container has a patch that instead enforces ES256, but it's unsuitable to upstream as a proper fix. This patching will be removed once https://github.com/IdentityPython/idpy-oidc/issues/110 is resolved. You could use `ES256.patch` to replicate this bubblegum fix outside the container.
21
-
- The containers are not version tagged, since there is no upstream version of SATOSA that fulfills the requirements. They are however tagged to specific commits for your convenience if you do not wish to follow `:latest`.
17
+
### The caveats with the container and/or trying to go without it:
18
+
- While recent releases of SATOSA support PKCE, they depend on the Python library `idpyoidc` for this. Unfortunately it has an issue that prevents using `ES256` for signing with released versions. The container thus uses [a branch from git](https://github.com/IdentityPython/idpy-oidc/tree/issuer_metadata) that contains the fix for this. Once a full release is made with said fix that will be used specifically. Once SATOSA requires a high enough release of `idpyoidc` that contains a fix, we can stop with this nonsense altogether.
19
+
- The containers are now version tagged as per SATOSA upstream versions. However, due to the above nonsense those tags will be updated later when better build provenance is available.
20
+
21
+
### Container config options
22
+
The container contains minimal config options via environment variables for ease of use.
23
+
-`LOG_LEVEL`: defaults to `INFO`. You may want to raise this to `DEBUG` for troubleshooting, but be aware logs will then leak tokens. Affects gunicorn and all SATOSA modules (if using the env based default config).
24
+
-`LISTEN_ADDR`: defaults to `0.0.0.0:80`. You may need to alter this depending on your container orchestration and proxying needs.
25
+
- Any other gunicorn flags can be passed as arguments.
22
26
23
27
## Step by step guides for usage
24
28
@@ -35,14 +39,35 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
35
39
1. Once you have your metadata XML file, make it available to your container, for example via a volume. The dummy data is already available.
36
40
2. Configure the ENV variables that will tweak the provided SATOSA configs. You can edit the provided `example.env` file and feed it to Docker via the `--env-file` flag. Make sure to **not** quote values if using that flag. Explanations below:
37
41
```shell
38
-
ENCRYPTION_KEY=0xDEADBEEF # Key used to encrypt state in transit. Could generate with `openssl rand -base64 32`
39
-
OIDC_CLIENT_ID=your-client-id # The OIDC client id in Kanidm is the name of the integration, for example `ceph`
42
+
# Enables debug logging for troubleshooting.
43
+
# Change this to "INFO" when everything works!
44
+
LOG_LEVEL=DEBUG # Enables debug logging for troubleshooting. Change this to "INFO" when everything works!
45
+
46
+
# Key used to encrypt state in transit. Use a key of your own choosing!
47
+
# For example, generate one with `openssl rand -base64 32`
48
+
ENCRYPTION_KEY=0xDEADBEEF
49
+
# The OIDC client id in Kanidm is the name of the integration, for example `ceph`.
50
+
OIDC_CLIENT_ID=your-client-id
40
51
OIDC_CLIENT_SECRET=your-oidc-client-secret
41
-
OIDC_ISSUER_URL=https://idm.example.com/oauth2/openid/your-client-id # Full URL to the discovery endpoint
42
-
OIDC_NAME=unique_oidc_name # A unique id used for this OIDC backend in SATOSA. Uniqueness becomes relevant if you configure multiple on the same proxy.
43
-
PROXY_BASE_URL=https://saml.example.com # Where your proxy lives. **must** be https, must be the root of a host, must match the CN in your cert from step 1.
44
-
SAML_METADATA="dummy-metadata.xml"# A path to your app SAML metadata file. The working directory of the provided image is `/etc/satosa` so the relative path example here would expect the file to be on the container at `/etc/satosa/dummy-metadata.xml`. If you can't get this until the proxy is running and you've registered it in the app, use dummy-metadata.xml as a workaround to boot the proxy without it.
45
-
SAML_NAME=unique_saml_name # A unique id used for this SAML frontend in SATOSA. Uniqueness becomes relevant if you configure multiple on the same proxy.
# A unique id used for the OIDC side in SATOSA, used in the callback URL: `https://ceph.example.com/unique_oidc_name`
57
+
OIDC_NAME=unique_oidc_name
58
+
# A unique id used for the SAML side in SATOSA, used in URLs.
59
+
SAML_NAME=unique_saml_name
60
+
61
+
# Where your proxy lives. **must** be https, must be the root of a host with no subdir,
62
+
# must match the CN in your cert from step 1, must be unique per app you're integrating.
63
+
PROXY_BASE_URL=https://saml.example.com
64
+
65
+
# A path to your app SAML metadata file.
66
+
# The working directory of the provided image is `/etc/satosa`,
67
+
# so the relative path example here would expect the file to be on the container at `/etc/satosa/dummy-metadata.xml`.
68
+
# If you can't get this until the proxy is running and you've registered it in the app, use dummy-metadata.xml as a workaround to boot the proxy without it.
69
+
SAML_METADATA=dummy-metadata.xml
70
+
46
71
```
47
72
3. Launch the proxy. This depends on your container orchestration, but a simple testing example is provided below. **This is not enough, you need to get https working which is outside the scope of this guide.
48
73
```shell
@@ -62,22 +87,42 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
62
87
### Practical example: Ceph SSO via Kanidm
63
88
1. Pre-create your users in Ceph to give them the correct authz. In this example we'll use short usernames for simplicity so that needs to match.
64
89
1. Create your Kanidm OIDC configuration the usual way, no need to disable PKCE!
90
+
```shell
91
+
# **Important** give the upstream Ceph landing page URL here:
92
+
kanidm system oauth2 create ceph Ceph https://ceph.example.com
93
+
94
+
# **Important** give the proxy callback URL here. The full value depends on $OIDC_NAME:
95
+
kanidm system oauth2 add-redirect-url ceph https://ceph-saml.example.com/oidc_ceph
96
+
97
+
# Use short usernames for convenience
98
+
kanidm system oauth2 prefer-short-username ceph
99
+
100
+
# Create the scope map, don't forget to create the group and add your Ceph admins to it.
101
+
kanidm system oauth2 update-scope-map ceph ceph_admins openid profile email
102
+
103
+
# Get your client_secret for use later on:
104
+
kanidm system oauth2 show-basic-secret ceph
65
105
```
66
-
kanidm system oauth2 create ceph Ceph https://saml.example.com # **Important**, give the proxy URL here.
67
-
kanidm system oauth2 prefer-short-username ceph # Use short usernames for convenience
68
-
kanidm system oauth2 update-scope-map ceph ceph_admins openid profile email # Create the scope map, don't forget to create the group and add your Ceph admins to it.
69
-
kanidm system oauth2 show-basic-secret ceph # Get your client_secret for use later on.
106
+
1. Create your SAML2 certs and set their permissions, remember to set the correct `SN`:
0 commit comments