Skip to content

Commit f64b8ae

Browse files
committed
docs: Update instructions for latest Kanidm security requirements
Also general doc updates and better formatting for readability.
1 parent 125896e commit f64b8ae

File tree

1 file changed

+67
-25
lines changed

1 file changed

+67
-25
lines changed

README.md

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# SATOSA based SAML to Kanidm OIDC proxy
22

33
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.
45

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)
88
99
## TODO items on the roadmap
1010
1. Get rid of the idpyoidc git build once there's a release that contains ES256 support.
@@ -14,13 +14,13 @@ i.e. How to connect legacy web apps that only support SAML to be backed by Kanid
1414

1515
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.
1616

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.
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.
1919
- 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.
2020

2121
### Container config options
2222
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).
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).
2424
- `LISTEN_ADDR`: defaults to `0.0.0.0:80`. You may need to alter this depending on your container orchestration and proxying needs.
2525
- Any other gunicorn flags can be passed as arguments.
2626

@@ -39,15 +39,35 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
3939
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.
4040
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:
4141
```shell
42-
LOG_LEVEL=debug # Enables debug logging for troubleshooting. Change this to "info" when everything works!
43-
ENCRYPTION_KEY=0xDEADBEEF # Key used to encrypt state in transit. Could generate with `openssl rand -base64 32`
44-
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
4551
OIDC_CLIENT_SECRET=your-oidc-client-secret
46-
OIDC_ISSUER_URL=https://idm.example.com/oauth2/openid/your-client-id # Full URL to the discovery endpoint
47-
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.
48-
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.
49-
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.
50-
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.
52+
53+
# Full URL to the discovery endpoint
54+
OIDC_ISSUER_URL=https://idm.example.com/oauth2/openid/your-client-id
55+
56+
# 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+
5171
```
5272
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.
5373
```shell
@@ -67,23 +87,42 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
6787
### Practical example: Ceph SSO via Kanidm
6888
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.
6989
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
70105
```
71-
kanidm system oauth2 create ceph Ceph https://saml.example.com # **Important**, give the proxy URL here.
72-
kanidm system oauth2 prefer-short-username ceph # Use short usernames for convenience
73-
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.
74-
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`:
107+
```shell
108+
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
109+
-keyout saml.key -out saml.crt -subj "/SN=ceph-saml.example.com/"
110+
chown :999 saml.key
111+
chmod g+r saml.key
75112
```
76-
1. Create your SAML2 certs and set their permissions as per the generic steps above, nothing special here.
77113
1. We can't get Ceph to spit out it's metadata XML before the proxy is functioning so we skip ahead.
78114
1. Config your ENV variables into a new env file, `ceph.env`. If you don't change the ENCRYPTION_KEY value you deserve everything you get as a result.
79115
```shell
80-
LOG_LEVEL=debug # Enables debug logging for troubleshooting. Change this to "info" when everything works!
81-
ENCRYPTION_KEY=+OSDGTYdWxesiUwcMEzaGzwCx81YHhzOFgsitMn9A/c=
116+
# Enables debug logging for troubleshooting. Change this to "INFO" when everything works!
117+
LOG_LEVEL=DEBUG
118+
# Generate this for example with: `openssl rand -base64 32`
119+
ENCRYPTION_KEY=
82120
OIDC_CLIENT_ID=ceph
83-
OIDC_CLIENT_SECRET=# You got this above from kanidm
121+
# The client secret you got in a previous step:
122+
OIDC_CLIENT_SECRET=
84123
OIDC_ISSUER_URL=https://idm.example.com/oauth2/openid/ceph
85124
OIDC_NAME=oidc_ceph
86-
PROXY_BASE_URL=https://saml.example.com
125+
PROXY_BASE_URL=https://ceph-saml.example.com
87126
SAML_METADATA=dummy-metadata.xml
88127
SAML_NAME=saml_ceph
89128
```
@@ -96,7 +135,10 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
96135
```
97136
1. Register the proxy with Ceph, giving it the Ceph URL, SAML metadata endpoint and an attribute field name to expect for the username.
98137
```shell
99-
ceph dashboard sso setup saml2 https://ceph.example.com https://saml.example.com/saml_ceph/metadata.xml urn:oid:0.9.2342.19200300.100.1.1
138+
ceph dashboard sso setup saml2 \
139+
https://ceph.example.com \
140+
https://ceph-saml.example.com/saml_ceph/metadata.xml \
141+
urn:oid:0.9.2342.19200300.100.1.1
100142
```
101143
1. Assuming registration was succesful, we can now get the Ceph side SAML metadata:
102144
```shell
@@ -111,4 +153,4 @@ SAML is a bit *involved* so we need to prep a persistent certificate and provide
111153
ghcr.io/jinnatar/satosa-saml-proxy:latest
112154
```
113155

114-
1. Restart the proxy and go test Ceph SSO!
156+
1. Restart the proxy and go test Ceph SSO! Once it's all working, amend your env one more time to set `LOG_LEVEL=INFO`!

0 commit comments

Comments
 (0)