diff --git a/.github/workflows/release-keystone-shibd.yml b/.github/workflows/release-keystone-shibd.yml
new file mode 100644
index 000000000..cd297d871
--- /dev/null
+++ b/.github/workflows/release-keystone-shibd.yml
@@ -0,0 +1,116 @@
+#
+name: Create and publish a the Keystone Shib compatible image
+
+# Configures this workflow to run every time a change is pushed to the branch called `release`.
+on:
+ workflow_dispatch:
+ inputs:
+ imageTag:
+ description: 'Set tag for the image'
+ required: true
+ default: 'master-ubuntu_jammy'
+ type: choice
+ options:
+ - master-ubuntu_jammy
+ - 2024.1-ubuntu_jammy
+ - 2025.1-ubuntu_nobel
+ pluginTag:
+ description: 'Set release used for the build environment'
+ required: true
+ default: 'master'
+ type: choice
+ options:
+ - "master"
+ - "2024.1"
+ - "2025.1"
+
+# DShibnes two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
+jobs:
+ build-and-push-image:
+ outputs:
+ MY_DATE: ${{ steps.mydate.outputs.MY_DATE }}
+ MY_CONTAINER: ${{ steps.mycontainer.outputs.MY_CONTAINER }}
+ runs-on: ubuntu-latest
+ # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account dShibned here.
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
+ # It uses the `context` parameter to dShibne the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
+ # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
+ - name: Dynamically set MY_DATE environment variable
+ run: echo "MY_DATE=$(date +%s)" >> $GITHUB_ENV
+ - name: Build and push Docker image
+ uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ with:
+ context: .
+ file: Containerfiles/KeystoneShib-Containerfile
+ push: true
+ tags: |
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/keystone-shib:${{ github.event.inputs.imageTag }}
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/keystone-shib:${{ github.event.inputs.imageTag }}-${{ env.MY_DATE }}
+ labels: ${{ steps.meta.outputs.labels }}
+ build-args: |
+ VERSION=${{ github.event.inputs.imageTag }}
+ PLUGIN_VERSION=${{ github.event.inputs.pluginTag }}
+ - name: Dynamically set MY_CONTAINER output option
+ id: mycontainer
+ run: echo "MY_CONTAINER=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/keystone-shib:${{ github.event.inputs.imageTag }}-${{ env.MY_DATE }}" >> $GITHUB_OUTPUT
+ - name: Dynamically set MY_DATE output option
+ id: mydate
+ run: echo "MY_DATE=${{ env.MY_DATE }}" >> $GITHUB_OUTPUT
+
+ change-original-images:
+ runs-on: ubuntu-latest
+ needs: [build-and-push-image]
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Dynamically update the original images file
+ run: jq '. + ["${{ needs.build-and-push-image.outputs.MY_CONTAINER }}"] | sort' .original-images.json | tee .original-images.json.new
+ - name: Rewrite original images file
+ run: mv .original-images.json.new .original-images.json
+ - name: Create Pull Request
+ id: cpr
+ uses: peter-evans/create-pull-request@v7
+ with:
+ commit-message: Update original images with new container
+ committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
+ author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
+ signoff: false
+ branch: ${{ needs.build-and-push-image.outputs.MY_DATE }}
+ sign-commits: true
+ delete-branch: true
+ title: 'chore: Update original images'
+ body: |
+ Update container image
+ - Updated original image file with container ${{needs.build-and-push-image.outputs.MY_CONTAINER}}
+ change request Auto-generated
+ labels: |
+ container images
+ automated pr
+ draft: false
diff --git a/.github/workflows/smoke-keystone-shibd.yml b/.github/workflows/smoke-keystone-shibd.yml
new file mode 100644
index 000000000..f9aa31d8d
--- /dev/null
+++ b/.github/workflows/smoke-keystone-shibd.yml
@@ -0,0 +1,42 @@
+#
+name: Run build check for the Nova EFI compatible image
+
+on:
+ pull_request:
+ paths:
+ - Containerfiles/NovaEFI-Containerfile
+
+# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
+jobs:
+ build-and-push-image:
+ runs-on: ubuntu-latest
+ # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
+ permissions:
+ contents: read
+ packages: read
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Build Docker image
+ uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ with:
+ context: .
+ file: Containerfiles/NovaEFI-Containerfile
+ push: false
+ tags: |
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/nova-efi:master-ubuntu_jammy
+ build-args: |
+ VERSION=master-ubuntu_jammy
+ PLUGIN_VERSION=master
diff --git a/.original-images.json b/.original-images.json
index dc36705e2..f250c73fc 100644
--- a/.original-images.json
+++ b/.original-images.json
@@ -11,9 +11,10 @@
"docker.io/openstackhelm/designate:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/glance:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/horizon:2023.1-ubuntu_jammy",
+ "docker.io/openstackhelm/ironic:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/magnum:2024.1-ubuntu_jammy",
- "docker.io/openstackhelm/masakari:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/masakari-monitors:2024.1-ubuntu_jammy",
+ "docker.io/openstackhelm/masakari:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy",
"docker.io/openstackhelm/osh-selenium:latest-ubuntu_jammy",
"docker.io/openstackhelm/ospurge:latest",
@@ -22,6 +23,7 @@
"docker.io/wrouesnel/postgres_exporter:v0.4.6",
"docker.io/xrally/xrally-openstack:2.0.0",
"gcr.io/google_containers/hyperkube-amd64:v1.11.6",
+ "ghcr.io/cloudnull/genestack/keystone-shib:2024.1-ubuntu_jammy-1747935846",
"ghcr.io/rackerlabs/genestack/ceilometer:2024.1-ubuntu_jammy-1738626813",
"ghcr.io/rackerlabs/genestack/cinder-volume-rxt:2024.1-ubuntu_jammy-1731085441",
"ghcr.io/rackerlabs/genestack/glance:2024.1-ubuntu_jammy-1740121591",
@@ -32,9 +34,8 @@
"ghcr.io/rackerlabs/genestack/neutron-oslodb:2024.1-ubuntu_jammy-1742943886",
"ghcr.io/rackerlabs/genestack/nova-efi:2024.1-ubuntu_jammy-1737928811",
"ghcr.io/rackerlabs/genestack/octavia-ovn:2024.1-ubuntu_jammy-1737651745",
- "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1739377879",
+ "ghcr.io/rackerlabs/keystone-rxt:2024.1-ubuntu_jammy-1747061260",
"ghcr.io/rackerlabs/skyline-rxt:master-ubuntu_jammy-1739967315",
- "docker.io/openstackhelm/ironic:2024.1-ubuntu_jammy",
"ghcr.io/vexxhost/netoffload:v1.0.1",
"quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy",
"quay.io/airshipit/porthole-postgresql-utility:latest-ubuntu_bionic"
diff --git a/Containerfiles/KeystoneShib-Containerfile b/Containerfiles/KeystoneShib-Containerfile
new file mode 100644
index 000000000..8f89302a0
--- /dev/null
+++ b/Containerfiles/KeystoneShib-Containerfile
@@ -0,0 +1,4 @@
+# syntax=docker/dockerfile:1
+
+FROM ubuntu:24.04
+RUN apt update && apt install -y shibboleth-sp-utils && apt clean && rm -rf /var/lib/apt/lists/* /tmp/*.deb
diff --git a/base-helm-configs/keystone/keystone-helm-overrides.yaml b/base-helm-configs/keystone/keystone-helm-overrides.yaml
index 690ea3592..06fea1b58 100644
--- a/base-helm-configs/keystone/keystone-helm-overrides.yaml
+++ b/base-helm-configs/keystone/keystone-helm-overrides.yaml
@@ -26,6 +26,13 @@ dependencies:
- keystone-fernet-setup
conf:
+ software:
+ apache2:
+ a2enmod:
+ - headers
+ - rewrite
+ - shib2
+ - ssl
keystone_api_wsgi:
wsgi:
processes: 2
@@ -108,9 +115,13 @@ conf:
WSGIDaemonProcess keystone-public processes={{ .Values.conf.keystone_api_wsgi.wsgi.processes }} threads={{ .Values.conf.keystone_api_wsgi.wsgi.threads }} user=keystone group=keystone display-name=%{GROUP}
WSGIProcessGroup keystone-public
WSGIScriptAlias / /var/www/cgi-bin/keystone/keystone-wsgi-public
+ WSGIScriptAliasMatch ^(/v3/OS-FEDERATION/identity_providers/.*?/protocols/.*?/auth)$ /var/www/keystone/main/$1
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
LimitRequestBody 114688
+
+ Proxypass Shibboleth.sso !
+
= 2.4>
ErrorLogFormat "%{cu}t %M"
@@ -119,6 +130,41 @@ conf:
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
CustomLog /dev/stdout combined env=!forwarded
CustomLog /dev/stdout proxy env=forwarded
+
+
+ SetHandler shib
+
+
+
+ Require valid-user
+ AuthType shibboleth
+ ShibRequestSetting requireSession 1
+ ShibExportAssertion off
+
+ ShibRequireSession On
+ ShibRequireAll On
+
+
+
+ Require valid-user
+ AuthType shibboleth
+ ShibRequestSetting requireSession 1
+ ShibExportAssertion off
+
+ ShibRequireSession On
+ ShibRequireAll On
+
+
+
+ Require valid-user
+ AuthType shibboleth
+ ShibRequestSetting requireSession 1
+ ShibExportAssertion off
+
+ ShibRequireSession On
+ ShibRequireAll On
+
+
secrets:
diff --git a/base-kustomize/keystone/federation/kustomization.yaml b/base-kustomize/keystone/federation/kustomization.yaml
new file mode 100644
index 000000000..d5d70437e
--- /dev/null
+++ b/base-kustomize/keystone/federation/kustomization.yaml
@@ -0,0 +1,33 @@
+sortOptions:
+ order: fifo
+resources:
+ - ../base
+
+patches:
+ - target:
+ kind: Deployment
+ name: keystone-api
+ patch: |-
+ - op: add
+ path: /spec/template/spec/containers/[0]/volumeMounts
+ value:
+ - mountPath: "/etc/shibboleth"
+ name: keystone-shibd-etc
+ readOnly: true
+ - op: add
+ path: /spec/template/spec/containers
+ value:
+ - command:
+ - shibd
+ image: ghcr.io/rackerlabs/genestack/Keystone-Shib:2024.1-ubuntu_jammy
+ imagePullPolicy: IfNotPresent
+ volumeMounts:
+ - mountPath: "/etc/shibboleth"
+ name: keystone-shibd-etc
+ readOnly: true
+ - op: add
+ path: /spec/template/spec/volumes
+ value:
+ - name: keystone-shibd-etc
+ secret:
+ secretName: keystone-shibd-etc
diff --git a/docs/openstack-keystone-federation.md b/docs/openstack-keystone-federation.md
index 2cceffc03..c9ec3831f 100644
--- a/docs/openstack-keystone-federation.md
+++ b/docs/openstack-keystone-federation.md
@@ -1,18 +1,20 @@
-# Setup the Keystone Federation Plugin
+# Setup the Keystone Federation Plugins
-## Create the domain
+## Create the Rackspace Domain
``` shell
openstack --os-cloud default domain create rackspace_cloud_domain
```
-## Create the identity provider
+## Global Auth Identity Provider
+
+First step is to create the identity provider and connect it to a domain.
``` shell
openstack --os-cloud default identity provider create --remote-id rackspace --domain rackspace_cloud_domain rackspace
```
-### Create the mapping for our identity provider
+### Create the Global Auth mapping for our identity provider
You're also welcome to generate your own mapping to suit your needs; however, if you want to use the example mapping (which is suitable for production) you can.
@@ -34,19 +36,19 @@ The example mapping **JSON** file can be found within the genestack repository a
openstack --os-cloud default role create creator
```
-## Now register the mapping within Keystone
+### Register the Global Auth mapping within Keystone
``` shell
openstack --os-cloud default mapping create --rules /tmp/mapping.json --schema-version 2.0 rackspace_mapping
```
-## Create the federation protocol
+### Create the Global Auth federation protocol
``` shell
openstack --os-cloud default federation protocol create rackspace --mapping rackspace_mapping --identity-provider rackspace
```
-## Rackspace Configuration Options
+### Rackspace Global Auth Configuration Options
The `[rackspace]` section can also be used in your `keystone.conf` to allow you to configure how to anchor on
roles.
@@ -55,3 +57,49 @@ roles.
| --- | ----- | ------- |
| `role_attribute` | A string option used as an anchor to discover roles attributed to a given user | **os_flex** |
| `role_attribute_enforcement` | When set `true` will limit a users project to only the discovered GUID for the defined `role_attribute` | **false** |
+
+## SAML Identity Provider
+
+First step is to create the identity provider and connect it to a domain.
+
+``` shell
+openstack --os-cloud default identity provider create --remote-id rackspace_saml --domain rackspace_cloud_domain rackspace_saml
+```
+
+### Generate the SAML metadata and configure the SAML identity provider
+
+The files will be created and stored in a kubernetes secret named `keystone-shib-etc` and mounted to `/etc/shibboleth` in the `keystone` pod. The files are:
+
+* `sp-metadata.xml`
+* `shibboleth2.xml`
+* `attribute-map.xml`
+
+``` shell
+cat << EOF >> /tmp/sp-metadata.xml
+...
+EOF
+```
+
+``` shell
+cat << EOF > /tmp/shibboleth2.xml
+
+
+
+EOF
+```
+
+``` shell
+cat << EOF > /tmp/attribute-map.xml
+
+
+EOF
+```
+
+Now ingest all files into the kubernetes secret as a secrete, which will be mounted to the keystone pod.
+
+``` shell
+kubectl -n openstack create secret generic keystone-shib-etc \
+ --from-file=/tmp/sp-metadata.xml \
+ --from-file=/tmp/shibboleth2.xml \
+ --from-file=/tmp/attribute-map.xml
+```
diff --git a/etc/keystone/mapping.json b/etc/keystone/mapping.json
index f8272a882..5a4408ee8 100644
--- a/etc/keystone/mapping.json
+++ b/etc/keystone/mapping.json
@@ -29,20 +29,7 @@
"project_tag": "{3}"
}
],
- "roles": [
- {
- "name": "member"
- },
- {
- "name": "load-balancer_member"
- },
- {
- "name": "heat_stack_user"
- },
- {
- "name": "creator"
- }
- ]
+ "roles": []
}
]
}
@@ -63,10 +50,9 @@
{
"type": "RXT_orgPersonType",
"any_one_of": [
- "admin",
- "default",
- "user-admin",
- "tenant-access"
+ "creator",
+ "member",
+ "reader"
]
}
]