This example describes how to deploy 1Password SCIM Bridge as a stack using Docker Swarm. The stack includes two services (one each for the SCIM bridge container and the required Redis cache), a Docker secret for the scimsession
credentials, a Docker config for configuring Redis, and optional secrets and configuration required only for customers integrating with Google Workspace.
README.md
: the document that you are reading. 👋😃compose.template.yaml
: a Compose Specification format Compose file for 1Password SCIM Bridge.compose.gw.yaml
: an override configuration to merge the configuration necessary for customers integrating with Google Workspace.compose.http.yaml
: optional configuration for exposing an HTTP port on the Docker host for forwarding plain-text traffic within a private network from a public TLS termination endpointcompose.tls.yaml
: optional configuration for enabling a self-managed TLS certificateredis.conf
: a Redis configuration file to load the Redis cache with the base configuration required for SCIM bridgescim.env
: an environment file used to customize the SCIM bridge configuration
The open source Docker Engine tooling can be used to deploy 1Password SCIM Bridge on any supported Linux distribution. A single-node swarm is sufficient for most deployments. This example assumes that the Linux server is exposed directly to the public internet with Docker acting as a reverse proxy to the SCIM bridge container.
- AMD64 VM or bare metal server with a Docker-supported Linux distribution (e.g. Ubuntu, Debian, Fedora, etc.)
- Docker Engine (see Docker Engine installation overview) installed on the Linux server
- a public DNS A record pointing to the Linux server
- SSH access to the Linux server
- Docker Desktop or Docker Engine installed on a machine with access to the Linux server and credentials from your 1Password account
Note
📚 Before proceeding, review the Preparation Guide at the root of this repository.
Create a public DNS A record that points to the public IP address of the Linux server for your SCIM bridge. For example, scim.example.com
.
On the Linux machine that you will be using as the Docker host for your SCIM bridge:
- If you haven't already done so, install Docker Engine on the Linux server. Follow the Server instructions; Docker Desktop is not needed for the Linux server.
- Follow the post-install steps as noted in the documentation to enable running Docker as a non-root user and ensure that Docker Engine starts when the Linux server boots.
All following steps should be run on the same computer where you are already using 1Password, or another machine that can access the Linux server using SSH and has access to the scimsession
file from the integration setup:
-
If you haven't already done so, install Docker. You can use Docker Desktop, install Docker Engine from binaries, or install Docker using your favourite package manager.
-
Open your preferred terminal. Clone this repository and switch to this directory:
git clone https://github.com/1Password/scim-examples.git cd ./scim-examples/beta/docker
-
Save the
scimsession
credentials file from the Automated User Provisioning setup to this working directory.Note
💻 If you saved your
scimsession
file as an item in your 1Password account, you can use 1Password CLI to save the file to this directory. For example:op read "op://Private/scimsession file/scimsession" --out-file ./scimsession
-
Open
scim.env
in your favourite text editor. Set the value ofOP_TLS_DOMAIN
to the fully qualififed domain name of the public DNS record for your SCIM bridge created in Get started. For example:# ... OP_TLS_DOMAIN=scim.example.com # ...
Save the file.
-
Create a Docker context to use for connecting to the Linux server:
Example command:
docker context create op-scim-bridge \ --description "1Password SCIM Bridge Docker host" \ --docker host=ssh://user@scim.example.com
Copy the example command to a text editor. Replace
user
with the appropriate username for your Linux server andscim.example.com
with the host name or IP address used for SSH access to the Linux server before running the command in your terminal.Note
🔑 You can store your SSH keys in 1Password and authenticate this and other SSH workflows without writing a private key to disk using the 1Password SSH agent.
-
Switch to the Docker context you just created to connect to the Docker host:
docker context use op-scim-bridge
Run this command to create the swarm:
docker swarm init # --advertise-addr 192.0.2.1
Note
Additional nodes may be optionally added to a swarm for fault tolerance. This command adds the Linux server as the first (and only) node in the swarm, but Docker requires a unique IP address to advertise to other nodes (even if no other nodes will be added). See How nodes work in the Docker documentation for more details.
If multiple IP addresses are detected, Docker returns an error; uncomment the
--advertise-addr
parameter (delete#
), replace the example IP (192.0.2.1
) with the appropriate IP address, and run the command again.
Additional configuration and credentials are required to integrate to integrate your 1Password account with Google Workspace.
Warning
⏩ This section is only for customers who are integrating 1Password with Google Workspace for automated user provisioning. If you are not integrating with Workspace, skip the steps in this section and deploy your SCIM bridge
See Connect Google Workspace to 1Password SCIM Bridge for instructions to create the service account, key, and API client.
-
Save the Google Workspace service account key to the working directory.
-
Make sure the service account key is named
workspace-credentials.json
. -
Open the
workspace-settings.json
file in a text editor and replace the values for each key:actor
: the email address for the administrator that the service account is acting on behalf ofbridgeAddress
: the URL for your SCIM bridge based on the fully qualified domain name of the DNS record created in Get started
{ "actor":"admin@example.com", "bridgeAddress":"https://scim.example.com" }
Save the file.
Use the Compose template to output a canonical configuration for use with Docker Swarm and create the stack from this configuration inline. Your SCIM bridge should automatically acquire and manage a TLS certificate from Let's Encrypt on your behalf:
docker stack config \
--compose-file ./compose.template.yaml |
docker stack deploy --compose-file - op-scim-bridge
If you are integrating with Google Workspace, use the compose.gw.yaml
override Compose file.
Warning
⏩ This section is only for customers who are integrating 1Password with Google Workspace for automated user provisioning. If you are not integrating with Workspace, skip this section and test your SCIM bridge.
Merge the configuration to create and use the additional Docker secrets needed for Workspace into the canonical configuration:
docker stack config \
--compose-file ./compose.template.yaml \
--compose-file ./compose.gw.yaml |
docker stack deploy --compose-file - op-scim-bridge
Run this command to retrieve logs from the service for the SCIM bridge container:
docker service logs op-scim-bridge_scim --raw
Your SCIM bridge URL is based on the fully qualified domain name of the DNS record created in Get started, for example https://scim.example.com/
. You can access your SCIM bridge in a web browser at this URL by signing in using your bearer token.
You can also test your SCIM bridge by sending an authenticated SCIM API request.
Example command:
curl --header "Authorization: Bearer mF_9.B5f-4.1JqM" https://scim.example.com/Users
Copy the example command to a text editor. Replace mF_9.B5f-4.1JqM
with your bearer token and scim.example.com
with the fully qualified domain name of the DNS record created in Get started before running the command in your terminal.
Note
💻 If you saved your bearer token as an item in your 1Password account, you can use 1Password CLI to securely pass the bearer token instead of writing it out in the console. For example:
--header "Authorization: Bearer $(op read "op://Private/bearer token/credential")"
Example JSON response
{ "Resources": [ { "active": true, "displayName": "Eggs Ample", "emails": [ { "primary": true, "type": "", "value": "eggs.ample@example.com" } ], "externalId": "", "groups": [ { "value": "f7eqriu7ht27mq5zmm63gf2dhq", "ref": "https://scim.example.com/Groups/f7eqriu7ht27mq5zmm63gf2dhq" } ], "id": "FECPUMYBHZB2PB6K4WKM4Q2HAU", "meta": { "created": "", "lastModified": "", "location": "", "resourceType": "User", "version": "" }, "name": { "familyName": "Ample", "formatted": "Eggs Ample", "givenName": "Eggs", "honorificPrefix": "", "honorificSuffix": "", "middleName": "" }, "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User" ], "userName": "eggs.ample@example.com" }, ... ] }
Use your SCIM bridge URL and bearer token to connect your identity provider to 1Password SCIM Bridge.
Swarm mode in Docker Engine uses a declarative service model. Services will automatically restart tasks when updating their configuration.
Use the Docker context from Prepare your desktop to connect to your Docker host and manage your stack.
Update the op-scim-bridge_scim
service with the new image tag from the 1password/scim
repository on Docker Hub to update your SCIM bridge to a new version:
docker service update op-scim-bridge_scim \
--image 1password/scim:v2.8.4
Note
You can find details about the changes in each release of 1Password SCIM Bridge on our Release Notes website. The most recent version should be pinned in the
compose.template.yaml
file (and in the command above in this file) in the main branch of this GitHub repository.
Your SCIM bridge should automatically reboot using the specified version, typically in a few moments.
Many SCIM bridge configuration changes can be made by adding or removing environment variables. These can be customized by making changes to scim.env
(that can be commited to your source control) before deploying (or redeploying) your SCIM bridge using the docker stack deploy
command. For some use cases, it may be desirable to update the configuration "on the fly" from your terminal.
For example, to reboot your SCIM bridge with debug logging enabled:
docker service update op-scim-bridge_scim \
--env-add OP_DEBUG=1
To turn off debug logging and inject some colour into the logs in your console:
docker service update op-scim-bridge_scim \
--env-rm OP_DEBUG \
--env-add OP_PRETTY_LOGS=1
Pretty logs pair nicely with the --raw
parameter of the docker service logs
command). 🤩
Docker secrets are immutable and cannot be removed while in use by a Swarm service. To use new secret values in your stack, you must remove the existing secret from the service configuration, replace the Docker secret (or add a new one), and update the service configuration to mount the new secret value.
For example, if you regenerate credentials for the automated user provisioning integration:
-
Scale down the
op-scim-bridge_scim
service to shut down the running SCIM bridge task.docker service scale op-scim-bridge_scim=0
-
Update the service definition to unnmount the the
scimsession
Docker secret:docker service update op-scim-bridge_scim \ --secret-rm scimsession
-
Remove the secret from the swarm:
docker secret rm scimsession
-
Copy the regenerated
scimsession
file from your 1Password account to your working directory. Create a newscimsession
Docker secret using the new file:docker secret create scimsession ./scimsession
Note
💻 If you saved your
scimsession
file as an item in your 1Password account, you can use 1Password CLI to create the new Docker secret instead (without saving it to disk on your machine). For example:op read "op://Private/scimsession file/scimsession" | docker secret create scimsession -
-
Update the service to mount the new
scimsession
secret:docker service update op-scim-bridge_scim \ --secret-add source=scimsession,target=scimsession,uid="999",gid="999",mode=0440
-
Scale the
op-scim-bridge_scim
service back up to reboot your SCIM bridge:docker service scale op-scim-bridge_scim=1
Test your SCIM bridge using the new bearer token associated with the regenerated scimsession
file. Update your identity provider configuration with the new bearer token.
A similar process can be used to update the values for any other Docker secrets used in your configuration.
Identity providers strictly require an HTTPS endpoint with a vlid TLS certificate to use for the SCIM bridge URL. SCIM Bridge includes an optional CertificateManager component that (by default) acquires and manages a TLS certificate using Let's Encrypt, and terminates TLS traffic at the SCIM bridge container using this certificate. This requires port 443 of the Docker host to be publicly accessible to ensure Let's Encrypt can initiate an inbound connection to your SCIM bridge.
Other supported options include:
To terminate TLS traffic at another public endpoint and redirect private traffic to a Docker host in your private network, SCIM bridge can be configured to disable the CertificateManager component and serve plain-text HTTP traffic on port 80 of the Docker host. CertificateManager will be enabled if a value is set for the OP_TLS_DOMAIN
variable, so any value set in scim.env
must be removed (or this line must be commented out). The included compose.http.yaml
file can be used to set up the port mapping when deploying (or redeploying) SCIM bridge:
docker stack config \
--compose-file ./compose.template.yaml \
--compose-file ./compose.http.yaml |
docker stack deploy --compose-file - op-scim-bridge
You may supply your own TLS certificate with CertificateManager instead of invoking Let's Encrypt. The value set for OP_TLS_DOMAIN
must match the common name of the certificate.
Save the public and private certificate key files as certificate.pem
and key.pem
(respectively) to the working directory and use the included compose.tls.yaml
file when deploying SCIM bridge to create Docker secrets and configure SCIM bridge use this certificate when terminating TLS traffic:
docker stack config \
--compose-file ./compose.template.yaml \
--compose-file ./compose.tls.yaml |
docker stack deploy --compose-file - op-scim-bridge