-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Podman Deployment #311
Open
muhwagwa
wants to merge
12
commits into
main
Choose a base branch
from
add-podman-deployment
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
d623d61
create podman dir and add config files
muhwagwa 0a43e01
add README.md with instructions
muhwagwa 9e78657
revise README.md
muhwagwa 6abd81e
add update instruction and advanced scim.env options to README
muhwagwa e411796
add warning for gw users + resource rec
muhwagwa 0a143b3
updating with podman-compose files
ag-rdoucette e26ecb8
update README
muhwagwa 61bb8fa
delete files & add advanced deployment options
muhwagwa ac47615
Updating podman deployment to remove scripting dependency
ag-rdoucette c57abfa
Removing files no longer needed
ag-rdoucette 7646515
Making the image version configurable through the scim.env file.
ag-rdoucette 621baed
Fixing yamls as there was some extra items added that would cause iss…
ag-rdoucette File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
# [Beta] Deploy 1Password SCIM Bridge using Podman | ||
|
||
This example describes how to deploy 1Password SCIM Bridge using [Podman](https://podman.io/) and [Podman-compose](https://github.com/containers/podman-compose). The deployment includes two containers, one each for the SCIM bridge container and the required Redis cache. This deployment is recommended for users who can only use Red Hat Enterprise Linux (RHEL) VM for their on-prem deployment since Docker will have issues running on these VMs. | ||
Podman-compose is a community developed package that enables Podman to achieve the same functionality as Docker Compose. It allows users to specify all the necessary details inside a single file. | ||
|
||
> **Before you move on** | ||
> | ||
> If you are using Google Workspace or need to send more than 1000 provisioning requests at a time, please reach out to 1Password support team as these are not supported with Podman deployment yet. | ||
|
||
## In this folder | ||
|
||
- [`README.md`](./README.md): the document that you are reading. 👋😃 | ||
- [`podman.template.yaml`](./compose.template.yaml): a [Compose Specification](https://docs.docker.com/compose/compose-file/) format compose file for 1Password SCIM Bridge. | ||
- [`podman.gw.yaml`](./compose.gw.yaml): an override configuration to merge the configuration necessary for customers integrating with Google Workspace. | ||
- [`podman.http.yaml`](./compose.http.yaml): optional configuration for exposing an HTTP port on the Podman host for forwarding plain-text traffic within a private network from a public TLS termination endpoint | ||
- [`podman.tls.yaml`](./compose.http.yaml): optional configuration for enabling a self-managed TLS certificate | ||
- [`scim.env`](./scim.env): an environment file used to customize the SCIM bridge configuration | ||
|
||
## Prerequisites | ||
|
||
> **Note** | ||
> | ||
> 📚 Before proceeding, review the [Preparation Guide](/PREPARATION.md) at the root of this repository. | ||
|
||
- AMD64/ARM64 VM or bare metal server with a Podman-supported Linux distribution (usually RHEL) | ||
- 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`. | ||
- SSH access to the Linux server | ||
|
||
## Get started | ||
### 🛠️ Install Podman and Podman-compose | ||
|
||
On the Linux machine that you will be using as the Podman host for your SCIM bridge: | ||
|
||
1. [Install Podman](https://podman.io/docs/installation) on the Linux server. | ||
2. [Install podman-compose](https://github.com/containers/podman-compose?tab=readme-ov-file#installation) on the Linux server. | ||
> **`sudo dnf install podman-compose` not working?** | ||
> | ||
> Dnf package manager may be missing some python libraries including podman-compose on some versions of VMs. If that's the case, run `pip3 install podman-compose`. | ||
|
||
### 👨💻 Start the deployment | ||
|
||
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: | ||
|
||
1. Open your preferred terminal. Clone this repository and switch to this directory: | ||
|
||
```sh | ||
git clone https://github.com/1Password/scim-examples.git | ||
cd ./scim-examples/beta/podman | ||
``` | ||
|
||
2. Run the commands below to make the shell script files executable. | ||
|
||
```sh | ||
chmod u+x deploy.sh | ||
chmod u+x teardown.sh | ||
``` | ||
|
||
3. Save the `scimsession` credentials file from [the Automated User Provisioning setup](https://start.1password.com/integrations/directory/) to this working directory. | ||
Once this is done, you should be able to see `scimsession` listed when you run `ls`. | ||
|
||
|
||
4. Run the `deploy.sh` script by using the command below. | ||
|
||
> **Warning** | ||
> | ||
> ⏩ If you're using Google Workspace for automated user provisioning, | ||
> skip this step and move to the section below | ||
|
||
```sh | ||
./deploy.sh --file podman.http.yaml | ||
``` | ||
|
||
Continue from [Test your SCIM bridge](#test-your-scim-bridge). | ||
|
||
### If you're using Google Workspace as your IdP | ||
Additional configuration and credentials are required 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 | ||
> [Test your SCIM bridge](#test-your-scim-bridge) | ||
|
||
See [Connect Google Workspace to 1Password SCIM Bridge](https://support.1password.com/scim-google-workspace/#step-1-create-a-google-service-account-key-and-api-client) for instructions to create the service account, key, and API client. | ||
|
||
1. Save the Google Workspace service account key to the working directory. | ||
2. Make sure the service account key is named `workspace-credentials.json`. | ||
3. Open the [`workspace-settings.json`](./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 of | ||
- `bridgeAddress`: the URL for your SCIM bridge based on the fully qualified domain name of the DNS record created in [Get started](#get-started) | ||
|
||
```json | ||
{ | ||
"actor": "[email protected]", | ||
"bridgeAddress": "https://scim.example.com" | ||
} | ||
``` | ||
|
||
4. Open `scim.env` in your favourite text editor. Uncomment `OP_WORKSPACE_CREDENTIALS` and `OP_WORKSPACE_SETTINGS` in the last paragraph of the file. | ||
|
||
```dotenv | ||
... | ||
# (GOOGLE WORKSPACE) the options below are intended for users of our Google Workspace integration | ||
# OP_WORKSPACE_CREDENTIALS should be base64-encoded Google Service Account credentials JSON | ||
OP_WORKSPACE_CREDENTIALS=/run/secrets/workspace-credentials | ||
# OP_WORKSPACE_SETTINGS is a base64-encoded string containing Workspace settings JSON for your bridge | ||
OP_WORKSPACE_SETTINGS=/run/secrets/workspace-settings | ||
... | ||
``` | ||
|
||
5. Run the `deploy.sh` script by using the command below | ||
|
||
```sh | ||
./deploy.sh --file podman.http.yaml --file podman.gw.yaml | ||
``` | ||
|
||
|
||
## Test your SCIM bridge | ||
|
||
Run this command to view logs from the service for the SCIM bridge container: | ||
|
||
```sh | ||
podman logs scim | ||
``` | ||
|
||
Your **SCIM bridge URL** is based on the fully qualified domain name of the DNS record created in [Get started](#get-started). For example: `https://scim.example.com`. Replace `mF_9.B5f-4.1JqM` with your bearer token and `https://scim.example.com` with your SCIM bridge URL to test the connection and view status information. | ||
|
||
```sh | ||
curl --silent --show-error --request GET --header "Accept: application/json" \ | ||
--header "Authorization: Bearer mF_9.B5f-4.1JqM" \ | ||
https:/scim.example.com/health | ||
``` | ||
|
||
<details> | ||
<summary>Example JSON response:</summary> | ||
|
||
```json | ||
{ | ||
"build": "209031", | ||
"version": "2.9.3", | ||
"reports": [ | ||
{ | ||
"source": "ConfirmationWatcher", | ||
"time": "2024-04-25T14:06:09Z", | ||
"expires": "2024-04-25T14:16:09Z", | ||
"state": "healthy" | ||
}, | ||
{ | ||
"source": "RedisCache", | ||
"time": "2024-04-25T14:06:09Z", | ||
"expires": "2024-04-25T14:16:09Z", | ||
"state": "healthy" | ||
}, | ||
{ | ||
"source": "SCIMServer", | ||
"time": "2024-04-25T14:06:56Z", | ||
"expires": "2024-04-25T14:16:56Z", | ||
"state": "healthy" | ||
}, | ||
{ | ||
"source": "StartProvisionWatcher", | ||
"time": "2024-04-25T14:06:09Z", | ||
"expires": "2024-04-25T14:16:09Z", | ||
"state": "healthy" | ||
} | ||
], | ||
"retrievedAt": "2024-04-25T14:06:56Z" | ||
} | ||
``` | ||
|
||
</details> | ||
<br /> | ||
|
||
To view this information in a visual format, visit your SCIM bridge URL in a web browser. Sign in with your bearer token, then you can view status information and download container log files. | ||
|
||
## Connect your identity provider | ||
|
||
Use your SCIM bridge URL and bearer token to [connect your identity provider to 1Password SCIM Bridge](https://support.1password.com/scim/#step-3-connect-your-identity-provider). | ||
|
||
## Update your SCIM bridge | ||
|
||
👍 Check for 1Password SCIM Bridge updates on the [SCIM bridge releases notes website](https://releases.1password.com/provisioning/scim-bridge/). | ||
|
||
To upgrade your SCIM bridge, `git pull` the latest versions from this repository. Then re-apply the `.yml` file. For example: | ||
|
||
```bash | ||
cd scim-examples/ | ||
git pull | ||
cd beta/podman/ | ||
podman-compose up --build -d | ||
``` | ||
|
||
After 2-3 minutes, the bridge should come back online with the latest version. | ||
|
||
## Appendix: Customize your SCIM bridge | ||
|
||
Many SCIM bridge configuration changes can be made by adding or removing environment variables. These can be customized by making changes to [`scim.env`](./scim.env) (that can be commited to your source control) before deploying (or redeploying) your SCIM bridge. For some use cases, it may be desirable to update the configuration "on the fly" from your terminal. | ||
|
||
### 🔒 Advanced TLS options | ||
|
||
Identity providers strictly require an HTTPS endpoint with a vlid TLS certificate to use for the SCIM bridge URL. 1Password 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 Podman host to be publicly accessible to ensure Let's Encrypt can initiate an inbound connection to your SCIM bridge. | ||
|
||
Other supported options include: | ||
|
||
#### External load balancer or reverse proxy | ||
|
||
To terminate TLS traffic at another public endpoint and redirect private traffic to a Podman 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 Podman 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 `podman.http.yaml` file can be used to set up the port mapping when deploying (or redeploying) SCIM bridge: | ||
|
||
#### Self-managed TLS certificate | ||
|
||
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 `podman.custom-tls.yaml` file when deploying SCIM bridge to configure SCIM bridge using this certificate when terminating TLS traffic. So the command you should be running when deploying the SCIM bridge is as follows. | ||
|
||
``` | ||
./deploy.sh --file podman.custom-tls.yml | ||
``` | ||
|
||
### Custom Redis Options | ||
|
||
- `OP_REDIS_URL`: You can specify a `redis://` or `rediss://` (for TLS) URL here to point towards a different Redis host. You can then remove the sections in `podman.template.yml` that refer to Redis to not deploy that container. Redis is still required for the SCIM bridge to function. | ||
|
||
As of 1Password SCIM Bridge `v2.8.5`, additional Redis configuration options are available. `OP_REDIS_URL` must be unset for any of these environment variables to be read. These environment variables may be especially helpful if you need support for URL-unfriendly characters in your Redis credentials. These can be set in `scim.env`. | ||
|
||
> **Note** | ||
> `OP_REDIS_URL` must be unset, otherwise the following environment variables will be ignored. | ||
|
||
- `OP_REDIS_HOST`: overrides the default hostname of the redis server (default: `redis`). It can be either another hostname, or an IP address. | ||
- `OP_REDIS_PORT`: overrides the default port of the redis server connection (default: `6379`). | ||
- `OP_REDIS_USERNAME`: sets a username, if any, for the redis connection (default: `(null)`) | ||
- `OP_REDIS_PASSWORD`: Sets a password, if any, for the redis connection (default: `(null)`). Can accommodate URL-unfriendly characters that `OP_REDIS_URL` may not accommodate. | ||
- `OP_REDIS_ENABLE_SSL`: Optionally enforce SSL on redis server connections (default: `false`). (Boolean `0` or `1`) | ||
- `OP_REDIS_INSECURE_SSL`: Set whether to allow insecure SSL on redis server connections when `OP_REDIS_ENABLE_SSL` is set to `true`. This may be useful for testing or self-signed environments (default: `false`) (Boolean `0` or `1`). | ||
|
||
### Advanced `scim.env` options | ||
|
||
The following options are available for advanced or custom deployments. Unless you have a specific need, these options do not need to be modified. | ||
|
||
* `OP_PORT`: When `OP_TLS_DOMAIN` is set to blank, you can use `OP_PORT` to change the default port from 3002 to one you choose. | ||
* `OP_PRETTY_LOGS`: You can set this to `1` if you'd like the SCIM bridge to output logs in a human-readable format. This can be helpful if you aren't planning on doing custom log ingestion in your environment. | ||
* `OP_DEBUG`: You can set this to `1` to enable debug output in the logs, which is useful for troubleshooting or working with 1Password Support to diagnose an issue. | ||
* `OP_TRACE`: You can set this to `1` to enable trace-level log output, which is useful for debugging Let’s Encrypt integration errors. | ||
* `OP_PING_SERVER`: You can set this to `1` to enable an optional `/ping` endpoint on port `80`, which is useful for health checks. It's disabled if `OP_TLS_DOMAIN` is unset and TLS is not in use. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#!/bin/bash | ||
|
||
log_error() { | ||
echo "****************************" | ||
echo "ERROR: $1" | ||
echo "****************************" >&2 | ||
} | ||
|
||
# Function to create a secret if it doesn't already exist | ||
create_or_update_secret() { | ||
local secret_name=$1 | ||
local secret_file=$2 | ||
podman secret rm "$secret_name" 2>/dev/null | ||
if ! podman secret create "$secret_name" "$secret_file"; then | ||
log_error "Failed to create secret $secret_name from file $secret_file" | ||
exit 1 | ||
fi | ||
} | ||
|
||
# Function to create the secrets | ||
create_secrets() { | ||
echo "****************************" | ||
echo "Creating secrets." | ||
echo "****************************" | ||
create_or_update_secret scimsession ./scimsession | ||
|
||
if [ "$CUSTOM_TLS" = true ]; then | ||
echo "****************************" | ||
echo "Creating TLS secrets." | ||
echo "****************************" | ||
create_or_update_secret op-tls-cert ./cert.pem | ||
create_or_update_secret op-tls-key ./key.pem | ||
fi | ||
|
||
if [ "$EXTRA_SECRETS" = true ]; then | ||
echo "****************************" | ||
echo "Creating extra secrets for workspace." | ||
echo "****************************" | ||
create_or_update_secret workspace-credentials ./workspace-credentials.json | ||
create_or_update_secret workspace-settings ./workspace-settings.json | ||
fi | ||
|
||
# Check for additional secrets in the specified compose files | ||
for FILE in "${ADDITIONAL_FILES[@]}"; do | ||
if grep -q "workspace-credentials" "$FILE"; then | ||
echo "****************************" | ||
echo "Creating workspace-credentials secret from $FILE." | ||
echo "****************************" | ||
create_or_update_secret workspace-credentials ./workspace-credentials.json | ||
fi | ||
if grep -q "workspace-settings" "$FILE"; then | ||
echo "****************************" | ||
echo "Creating workspace-settings secret from $FILE." | ||
echo "****************************" | ||
create_or_update_secret workspace-settings ./workspace-settings.json | ||
fi | ||
done | ||
} | ||
|
||
# Function to deploy the services | ||
deploy_services() { | ||
echo "****************************" | ||
echo "Deploying services." | ||
echo "****************************" | ||
COMPOSE_FILES="-f podman.template.yaml" | ||
if [ "$CUSTOM_TLS" = true ]; then | ||
COMPOSE_FILES="$COMPOSE_FILES -f podman.custom-tls.yaml" | ||
fi | ||
if [ "$EXTRA_SECRETS" = true ]; then | ||
COMPOSE_FILES="$COMPOSE_FILES -f compose.gw.yaml" | ||
fi | ||
for FILE in "${ADDITIONAL_FILES[@]}"; do | ||
COMPOSE_FILES="$COMPOSE_FILES -f $FILE" | ||
done | ||
if ! podman-compose $COMPOSE_FILES up -d; then | ||
log_error "Failed to deploy services with podman-compose" | ||
exit 1 | ||
fi | ||
} | ||
|
||
# Parse arguments | ||
EXTRA_SECRETS=false | ||
CUSTOM_TLS=false | ||
ADDITIONAL_FILES=() | ||
while [ "$1" != "" ]; do | ||
case $1 in | ||
--file ) | ||
shift | ||
if [ "$1" = "podman.custom-tls.yaml" ]; then | ||
CUSTOM_TLS=true | ||
elif [ "$1" = "compose.gw.yaml" ]; then | ||
EXTRA_SECRETS=true | ||
else | ||
ADDITIONAL_FILES+=("$1") | ||
fi | ||
;; | ||
* ) | ||
log_error "Invalid option: $1" | ||
exit 1 | ||
;; | ||
esac | ||
shift | ||
done | ||
|
||
# Main script execution | ||
echo "****************************" | ||
echo "Setting vm.overcommit_memory." | ||
echo "****************************" | ||
if ! sudo sysctl vm.overcommit_memory=1; then | ||
log_error "Failed to set vm.overcommit_memory" | ||
exit 1 | ||
fi | ||
|
||
create_secrets | ||
deploy_services | ||
|
||
echo "****************************" | ||
echo "Fetching logs from the scim container." | ||
echo "****************************" | ||
if podman ps --format "{{.Names}}" | grep -q "^scim$"; then | ||
podman logs --tail 50 scim || log_error "Failed to fetch logs from the scim container" | ||
else | ||
log_error "scim container is not running or not found." | ||
fi | ||
|
||
echo -e "\n" | ||
echo "****************************" | ||
echo "Deployment complete." | ||
echo "****************************" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
services: | ||
scim: | ||
secrets: | ||
- op-tls-cert | ||
- op-tls-key | ||
ports: | ||
- 443:8443 | ||
secrets: | ||
op-tls-cert: | ||
external: true | ||
op-tls-key: | ||
external: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
services: | ||
scim: | ||
secrets: | ||
- workspace-credentials | ||
- workspace-settings | ||
|
||
secrets: | ||
workspace-credentials: | ||
external: true | ||
workspace-settings: | ||
external: true |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ag-rdoucette Would this have to change to redeploying the bridge using deploy.sh?