Skip to content

Conversation

@b-long
Copy link
Contributor

@b-long b-long commented Dec 17, 2025

📘 Proposed Changes

Read the (new / rendered) getting started section here:

♻️ Rebuild "Getting Started"

If this PR (or something similar) is approved, we can use it as the basis to rebuild the getting started page:

Getting started will provide a single docker compose file (just like today), by rendering the file:

# Create the docker-compose file (opentdf team) to provide as an artifact to new users (external)
docker compose -f docker-compose.consumer.yaml config > docker-compose.yaml

:octocat: About Github Actions, etc.

At first, I made the Github Actions test fail, because I modified the docker-compose.yaml in this repo. On our main branch, that file has two different goals:

  1. It's used by engineering (and Github Actions) to perform software development, and
  2. It's used by the Quickstart section section on our main README, to help OpenTDF user's quickly bootstrap their own environment.

Later on, I split the docker-compose.yaml file into three parts:

  1. The original docker-compose.yaml , for the development use case.
  2. A new docker-compose.consumer.yaml file for the consumer use case.
  3. A new docker-compose.base.yaml file that is used by both developers and consumers.

You'll notice the difference between docker-compose.yaml and docker-compose.consumer.yaml is fairly small.

🤖 Testing Instructions

Follow the rendered instructions (linked above). Once the platform is running, you should be able to interact with it normally.

For instance:

# Getting healthz
curl -k https://platform.opentdf.local:8443/healthz | jq

# Getting the well-known endpoint
curl -k -s https://platform.opentdf.local:8443/.well-known/opentdf-configuration | jq -C . | head -n 15

# Performing encryption with otdfctl
echo "Hello world" | otdfctl encrypt --host https://platform.opentdf.local:8443 --tls-no-verify --with-client-creds '{"clientId":"opentdf","clientSecret":"secret"}' -o hello.tdf

# Performing decryption with otdfctl
otdfctl decrypt hello.tdf --host https://platform.opentdf.local:8443 --tls-no-verify --with-client-creds '{"clientId":"opentdf","clientSecret":"secret"}'

You can also access Keycloak, via http://localhost:8888/auth/ .

@github-actions github-actions bot added the docs Documentation label Dec 17, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @b-long, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the developer experience for setting up the OpenTDF platform locally by consolidating numerous manual configuration and provisioning steps into a single docker compose up command. It introduces several new Docker services to automate tasks such as downloading necessary configuration files, generating all required cryptographic keys and certificates, and provisioning Keycloak with initial settings and sample data, thereby greatly reducing the time and complexity involved in getting a functional development environment.

Highlights

  • Simplified docker compose workflow: The local development setup is now a single docker compose up command, automating configuration, key generation, and service provisioning.
  • Automated Key and Certificate Generation: A new generate-keys service automatically creates RSA, ECC, CA, localhost, and sample user certificates, converting them to PKCS12 and JKS formats.
  • Integrated Platform Provisioning: New services like platform-provision-keycloak and platform-provision-fixtures are added to automatically configure Keycloak and add sample data.
  • Streamlined Keycloak Configuration: The keycloak service in docker-compose.yaml now uses a shared keys volume and has removed several database-related environment variables, simplifying its setup.
  • Updated Documentation: The Consuming.md file has been revised to reflect the new, simplified setup process, guiding users through the single docker compose up command.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


Docker builds with ease, Keys and configs now flow free, Setup, swift and clean.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly improves the developer experience by automating the platform setup process within docker compose. The changes are well-structured, introducing several new services for key generation, configuration downloading, and provisioning. My review focuses on enhancing the security, robustness, and maintainability of this new automated setup. The main suggestions involve addressing insecure file permissions, removing hardcoded secrets, improving the efficiency of initialization services, and making the documentation more reliable.

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 201.289152ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 102.522733ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 367.69767ms
Throughput 271.96 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 38.847191277s
Average Latency 386.277904ms
Throughput 128.71 requests/second

NANOTDF Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 27.990271081s
Average Latency 278.960299ms
Throughput 178.63 requests/second

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 177.082825ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 100.739459ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 361.526434ms
Throughput 276.60 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.635445281s
Average Latency 394.910985ms
Throughput 126.15 requests/second

NANOTDF Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 28.179601862s
Average Latency 280.835388ms
Throughput 177.43 requests/second

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 170.182543ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 106.25145ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 388.848308ms
Throughput 257.17 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.345115887s
Average Latency 391.068871ms
Throughput 127.08 requests/second

NANOTDF Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 28.042444962s
Average Latency 279.088239ms
Throughput 178.30 requests/second

@b-long
Copy link
Contributor Author

b-long commented Dec 18, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly improves the user experience for running the platform locally by introducing a self-contained docker-compose.consumer.yaml that automates the entire setup process. The refactoring of the developer's docker-compose.yaml to use a new docker-compose.base.yaml is also a good step towards reducing configuration duplication. However, I've identified several areas for improvement, primarily concerning security and maintainability. There are numerous instances of hardcoded credentials across the new compose files, which should be externalized. The new docker-compose.consumer.yaml duplicates a lot of configuration, creating a maintenance challenge. Additionally, the developer docker-compose.yaml appears to be broken by the refactoring, and some of the setup scripts in the consumer file are fragile. My detailed comments provide specific suggestions to address these issues.

openssl x509 -req -in /tmp/sampleuser.req -CA /keys/keycloak-ca.pem -CAkey /keys/keycloak-ca-private.pem -CAcreateserial -out /keys/sampleuser.crt -days 3650
# Convert to PKCS12
openssl pkcs12 -export -in /keys/keycloak-ca.pem -inkey /keys/keycloak-ca-private.pem -out /keys/ca.p12 -nodes -passout pass:password
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

A password is hardcoded here for openssl pkcs12. This is a security risk. Please use an environment variable. You'll need to add KEY_PASSWORD to the environment section for this service.

        openssl pkcs12 -export -in /keys/keycloak-ca.pem -inkey /keys/keycloak-ca-private.pem -out /keys/ca.p12 -nodes -passout env:KEY_PASSWORD

environment:
POSTGRES_DB: ers_test
POSTGRES_USER: ers_test_user
POSTGRES_PASSWORD: ers_test_pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Hardcoded credentials should be avoided. Please use environment variables loaded from a .env file to manage secrets like database passwords.

      POSTGRES_PASSWORD: ${ERS_TEST_POSTGRES_PASSWORD:-ers_test_pass}

Comment on lines +91 to +95
LDAP_ADMIN_PASSWORD: "admin_password"
LDAP_CONFIG_PASSWORD: "config_password"
LDAP_READONLY_USER: "true"
LDAP_READONLY_USER_USERNAME: "readonly"
LDAP_READONLY_USER_PASSWORD: "readonly_password"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Hardcoded credentials for LDAP should be avoided. Please use environment variables loaded from a .env file to manage these secrets.

      LDAP_ADMIN_PASSWORD: ${LDAP_ADMIN_PASSWORD:-admin_password}
      LDAP_CONFIG_PASSWORD: ${LDAP_CONFIG_PASSWORD:-config_password}
      LDAP_READONLY_USER: "true"
      LDAP_READONLY_USER_USERNAME: "readonly"
      LDAP_READONLY_USER_PASSWORD: ${LDAP_READONLY_USER_PASSWORD:-readonly_password}

- ers_ldap_config:/etc/ldap/slapd.d
- ./service/entityresolution/integration/ldap_test_data:/container/service/slapd/assets/config/bootstrap/ldif/custom
healthcheck:
test: ["CMD-SHELL", "ldapsearch -x -H ldap://localhost:389 -b dc=opentdf,dc=test -D cn=admin,dc=opentdf,dc=test -w admin_password '(objectclass=*)' dn"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The healthcheck command contains a hardcoded password. This should also be replaced with an environment variable to avoid exposing secrets. Note the $$ is required to properly escape the variable for the shell.

      test: ["CMD-SHELL", "ldapsearch -x -H ldap://localhost:389 -b dc=opentdf,dc=test -D cn=admin,dc=opentdf,dc=test -w $${LDAP_ADMIN_PASSWORD:-admin_password} '(objectclass=*)' dn"]

KC_DB_URL_PORT: 5432
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: changeme
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Hardcoded database password for Keycloak. Please use an environment variable.

      KC_DB_PASSWORD: ${KC_DB_PASSWORD:-changeme}

- -c
- |
apk add --no-cache sed
sed -i 's|http://keycloak:8888|https://keycloak.opentdf.local:9443|g' /configs/opentdf.yaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using sed to patch a YAML file is fragile. If the structure or spacing of opentdf-example.yaml changes, this sed command could fail or have unintended side effects. Consider using a tool that understands YAML structure, like yq, for a more robust solution.

Comment on lines +572 to +612
command:
- -c
- |
apk add --no-cache openssl openjdk11-jre bash
cd /keys
# Generate KAS RSA private key
openssl genpkey -algorithm RSA -out /keys/kas-private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in /keys/kas-private.pem -pubout -out /keys/kas-cert.pem
# Generate ECC Key
openssl ecparam -name prime256v1 > /tmp/ecparams.tmp
openssl req -x509 -nodes -newkey ec:/tmp/ecparams.tmp -subj "/CN=kas" -keyout /keys/kas-ec-private.pem -out /keys/kas-ec-cert.pem -days 365
# Generate CA
openssl req -x509 -nodes -newkey RSA:2048 -subj "/CN=ca" -keyout /keys/keycloak-ca-private.pem -out /keys/keycloak-ca.pem -days 365
# Generate localhost certificate
printf "subjectAltName=DNS:localhost,IP:127.0.0.1" > /tmp/sanX509.conf
printf "[req]\ndistinguished_name=req_distinguished_name\n[req_distinguished_name]\n[alt_names]\nDNS.1=localhost\nIP.1=127.0.0.1" > /tmp/req.conf
openssl req -new -nodes -newkey rsa:2048 -keyout /keys/localhost.key -out /tmp/localhost.req -batch -subj "/CN=localhost" -config /tmp/req.conf
openssl x509 -req -in /tmp/localhost.req -CA /keys/keycloak-ca.pem -CAkey /keys/keycloak-ca-private.pem -CAcreateserial -out /keys/localhost.crt -days 3650 -sha256 -extfile /tmp/sanX509.conf
# Generate sample user certificate
openssl req -new -nodes -newkey rsa:2048 -keyout /keys/sampleuser.key -out /tmp/sampleuser.req -batch -subj "/CN=sampleuser"
openssl x509 -req -in /tmp/sampleuser.req -CA /keys/keycloak-ca.pem -CAkey /keys/keycloak-ca-private.pem -CAcreateserial -out /keys/sampleuser.crt -days 3650
# Convert to PKCS12
openssl pkcs12 -export -in /keys/keycloak-ca.pem -inkey /keys/keycloak-ca-private.pem -out /keys/ca.p12 -nodes -passout pass:password
# Convert PKCS12 to JKS using keytool (no Docker needed)
keytool -importkeystore \
-srckeystore /keys/ca.p12 \
-srcstoretype PKCS12 \
-destkeystore /keys/ca.jks \
-deststoretype JKS \
-srcstorepass "password" \
-deststorepass "password" \
-noprompt
echo "Keys generated successfully"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This large inline shell script for key generation is difficult to read, maintain, and test. It would be better to move this script to a separate .sh file that is downloaded by download-init-script and then executed by this service. This would significantly improve maintainability.


# Download platform configuration file
download-platform-config:
image: curlimages/curl:latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using the latest tag for Docker images is not recommended for distributable configurations as it can lead to unexpected behavior when the image is updated. It's better to pin to a specific version (e.g., curlimages/curl:8.8.0) to ensure reproducibility. This applies to all ...:latest images used for setup services in this file.

Comment on lines +404 to +406
chmod 777 /configs /keys
mkdir -p /configs/service/internal/fixtures
chmod -R 777 /configs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using chmod 777 is overly permissive and a potential security risk, as it gives read, write, and execute permissions to everyone. Please use more restrictive permissions. The fix-keys-permissions service later tightens these, but it's best practice to start with least privilege.

Comment on lines +171 to +192
test:
- CMD-SHELL
- |
[ -f /tmp/HealthCheck.java ] || echo "public class HealthCheck {
public static void main(String[] args) throws java.lang.Throwable {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance(\"SSL\");
sc.init(null, new javax.net.ssl.TrustManager[]{
new javax.net.ssl.X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}
}, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
java.net.HttpURLConnection conn = (java.net.HttpURLConnection)new java.net.URL(args[0]).openConnection();
System.exit(java.net.HttpURLConnection.HTTP_OK == conn.getResponseCode() ? 0 : 1);
}
}" > /tmp/HealthCheck.java && java ${JAVA_OPTS_APPEND} /tmp/HealthCheck.java https://localhost:9001/auth/health/live
timeout: 10s
retries: 3
start_period: 2m
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This inline Java class for the healthcheck is complex and hard to maintain within a YAML file. Consider moving this logic to a separate script file (e.g., healthcheck.sh) and mounting it into the container. This would improve readability and make it easier to test and update the healthcheck logic.

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 179.067188ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 103.543043ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 365.435067ms
Throughput 273.65 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.26574528s
Average Latency 400.590789ms
Throughput 124.18 requests/second

NANOTDF Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 29.076296489s
Average Latency 289.715231ms
Throughput 171.96 requests/second

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 180.277819ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 101.30836ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 364.853857ms
Throughput 274.08 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 38.574482698s
Average Latency 384.372204ms
Throughput 129.62 requests/second

NANOTDF Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 27.561908217s
Average Latency 274.499775ms
Throughput 181.41 requests/second

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants