Skip to content

Add integrations-hub Helm chart for Kubernetes deployment#614

Merged
chuckbutkus merged 15 commits into
mainfrom
add-integrations-hub-chart
May 15, 2026
Merged

Add integrations-hub Helm chart for Kubernetes deployment#614
chuckbutkus merged 15 commits into
mainfrom
add-integrations-hub-chart

Conversation

@chuckbutkus
Copy link
Copy Markdown
Contributor

@chuckbutkus chuckbutkus commented May 6, 2026

  • Add integrations-hub chart with deployment, service, and service account templates
  • Configure environment variables for Next.js, PostgreSQL, Auth.js, and OpenHands auth
  • Add health/ready probe endpoints at /api/health and /api/ready
  • Support both GCP Cloud SQL and in-cluster PostgreSQL configurations
  • Add integrations-hub as optional dependency in openhands chart
  • Add ingress template for integrations-hub in openhands chart
  • Update GitHub workflows to include integrations-hub chart publishing

Description

Helm Chart Checklist

  • I have updated the version field in Chart.yaml for each modified chart
  • I have tested the chart upgrade path from the previous version
  • I have verified backwards compatibility with existing values.yaml configurations
  • I have updated the chart's README.md if there are any breaking changes or new required values

Additional Notes

openhands-agent and others added 13 commits May 6, 2026 04:16
- Add integrations-hub chart with deployment, service, and service account templates
- Configure environment variables for Next.js, PostgreSQL, Auth.js, and OpenHands auth
- Add health/ready probe endpoints at /api/health and /api/ready
- Support both GCP Cloud SQL and in-cluster PostgreSQL configurations
- Add integrations-hub as optional dependency in openhands chart
- Add ingress template for integrations-hub in openhands chart
- Update GitHub workflows to include integrations-hub chart publishing

Co-authored-by: openhands <openhands@all-hands.dev>
Changes for openhands-auth-python branch:
- Change default port from 3000 to 8000
- Update health check paths from /api/health to /health
- Replace Node.js/NextAuth env vars with INTEGRATIONS_HUB_* prefix
- Add OpenHands cookie auth configuration
- Add CORS and DB pool settings
- Remove auth.js/NextAuth configuration

Co-authored-by: openhands <openhands@all-hands.dev>
Run alembic migrations before starting the main container to ensure
database tables exist. This follows the same pattern as the automation
service.
Default INTEGRATIONS_HUB_APP_ADMIN_EMAILS to:
chuck@openhands.dev,chuck@all-hands.dev,graham@openhands.dev,graham@all-hands.dev

Co-authored-by: openhands <openhands@all-hands.dev>
…kend

The chart previously exported a Next.js-era `INTEGRATIONS_HUB_*` env var
prefix plus separate INTEGRATIONS_HUB_DB_HOST/PORT/USER/PASS/NAME values,
none of which the FastAPI backend on the development branch actually reads.
Rewrite `_env.yaml` to match what backend/app/config.py and oauth_flow.py
look for so the pod can actually start and reach Postgres:

- Use the canonical `INTHUB_*` prefix (with legacy unprefixed fallbacks
  the backend already accepts) for: POSTGRES_URL, OPENHANDS_BASE_URL,
  OPENHANDS_AUTH_COOKIE_NAME, INTERNAL_AUTH_SECRET, CRON_SECRET,
  CREDENTIAL_ENCRYPTION_KEY, DISABLE_AUTH.
- Build a single `INTHUB_POSTGRES_URL` from the configured DB
  host/port/user/name plus the password secret using Kubernetes
  $(VAR_NAME) expansion. `database.url` is a new opt-in escape hatch
  for callers that want to supply a pre-formed URL.
- Use the unprefixed `APP_ADMIN_EMAILS` (per backend/README.md, the
  prefixed form is JSON-decoded by the SDK env parser and would require
  list syntax).
- Add optional `AUTH_REDIRECT_PROXY_URL` / `AUTH_URL` for the OAuth
  preview-deployment proxy that backend/app/oauth_flow.py honours.
- Drop unused env vars (HOST, SERVER_PORT, LOG_LEVEL, BASE_URL, GCP_*,
  CORS_ORIGINS) the FastAPI app never reads.

Also fix the health probes -- the FastAPI app exposes `/api/health` and
has no `/ready` endpoint, so the previous `/health` and `/ready` probes
would fail. Reuse `/api/health` for startup/liveness/readiness.

Finally, correct the umbrella chart's stale `service.port: 3000`
(Next.js) to `8000` (FastAPI `EXPOSE 8000`), mirror the new optional
fields, and rename the in-cluster wait-for-postgres init container's
PGPASSWORD reference to $INTHUB_DB_PASS so it lines up with the renamed
env var.

Verified with helm template + helm lint against several value matrices
(defaults, database.url override, OAuth proxy, internal auth secret,
disableAuth=true, datadog enabled, in-cluster postgresql).

Co-authored-by: openhands <openhands@all-hands.dev>
The Replicated lint job (.github/workflows/lint-replicated-release.yml,
Makefile target `build/openhands-0.7.15.tgz`) rewrites every umbrella
dependency that has a sibling directory under `charts/` to use a
`file://../<dep>` repository before running `helm package -u`. For that
rewrite to resolve, the umbrella's `version:` constraint must match the
sibling's local `Chart.yaml` version. With

  charts/integrations-hub/Chart.yaml      version: 0.1.0
  charts/openhands/Chart.yaml             integrations-hub: 0.1.0-alpha.614

helm fails with "can't get a valid version for repositories
integrations-hub" because the local sibling has no pre-release version
matching the alpha constraint -- which is exactly the failure on
run 25837636609 (#614).

Point the umbrella's integrations-hub dep at 0.1.0 to match the local
sibling, mirroring how runtime-api/plugin-directory/crd-check are wired
today. The preview-helm-charts workflow already calls

  yq -i '(.dependencies[] | select(.name == "integrations-hub")).version
         = "${INTEGRATIONS_HUB_PREVIEW}"' charts/openhands/Chart.yaml

before publishing, so the OCI-published umbrella will still carry the
alpha pin (0.1.0-alpha.<PR_NUMBER>) when consumers pull it.

Verified by running the Makefile recipe locally (yq dep rewrite + helm
package -u): "Successfully packaged chart and saved it to
build/openhands-0.7.15.tgz".

Co-authored-by: openhands <openhands@all-hands.dev>
…ations-hub)

Background
----------

The integrations-hub image is a single FastAPI container that serves
both its Next.js SPA bundle and the /api/* routes. On the
`development` branch we now bake the SPA with
`NEXT_PUBLIC_BASE_PATH=/integrations-hub` and ship
`INTHUB_ROOT_PATH=/integrations-hub` as the runtime default, so the
image is ready to live behind `<oh_host>/integrations-hub/...` without
any ingress-level rewrite.

This change exposes that path as a single chart value -- `rootPath` --
and threads it through every place that needed to agree on it.

Changes
-------

charts/integrations-hub/values.yaml
  * New top-level `rootPath: "/integrations-hub"` field, with a long
    comment explaining what it controls (subchart probes, INTHUB_ROOT_PATH
    env var, parent ingress, image NEXT_PUBLIC_BASE_PATH).
  * Setting it to "" deliberately clears the image default so the hub
    serves from the cluster root.

charts/integrations-hub/templates/_env.yaml
  * Always render `INTHUB_ROOT_PATH` from `.Values.rootPath` (including
    the empty-string case, so an override actually wins over the image
    default).
  * Documented the variable in the file header next to the other
    INTHUB_* env vars.

charts/integrations-hub/templates/deployment.yaml
  * Probe paths are now prefixed by `.Values.rootPath` so they hit
    `/integrations-hub/api/health` by default and `/api/health` when
    rootPath is empty -- matching whatever path the backend just
    mounted. Defining `$healthPath` once keeps the three probe
    declarations from drifting apart.

charts/openhands/templates/ingress-integrations-hub.yaml
  * Drop the stale `/api/integrations-hub` rule -- the backend never
    serves anything there; its API routes live under
    `/integrations-hub/api/...` thanks to INTHUB_ROOT_PATH. Keeping the
    second rule routed to the same service was harmless in practice
    but confusing.
  * The remaining rule's path is sourced from
    `(index .Values "integrations-hub" "rootPath")` (defaulting to
    `/integrations-hub`) so the ingress, the container env, and the
    SPA bundle stay in lockstep.
  * Added a block comment up top explaining why we deliberately do NOT
    set an ingress-level `rewrite-target` annotation.

charts/openhands/values.yaml
  * Mirrored the new `rootPath` field into the parent values so cloud
    deployments can override it just like other integrations-hub knobs,
    with a comment pointing at all three places it has to agree.

Validation
----------

* `helm lint charts/integrations-hub` -> 0 failures (only the
  pre-existing "icon is recommended" note).
* `helm template intg charts/integrations-hub` with the default
  rootPath: `INTHUB_ROOT_PATH=/integrations-hub` and all three probe
  paths render as `/integrations-hub/api/health`.
* Same template with `--set rootPath=""`:
  `INTHUB_ROOT_PATH=""` and probes fall back to plain
  `/api/health`, confirming the empty-override path works end-to-end.
* `helm template oh charts/openhands -s
  templates/ingress-integrations-hub.yaml` (run against a locally-built
  copy of the subchart, since the OCI 0.1.0 release isn't published
  yet): renders a single Ingress with `path: "/integrations-hub"` by
  default and `path: "/foo"` when overridden via
  `--set integrations-hub.rootPath=/foo`.

Co-authored-by: openhands <openhands@all-hands.dev>
@chuckbutkus chuckbutkus marked this pull request as ready for review May 15, 2026 03:16
@chuckbutkus chuckbutkus requested a review from all-hands-bot May 15, 2026 03:16
Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

🟡 Acceptable - Solid Helm chart structure following best practices, but needs security fixes and checklist completion before merge.

Comment thread charts/integrations-hub/templates/deployment.yaml Outdated
Comment thread charts/integrations-hub/templates/_env.yaml
Comment on lines +110 to +111
admin:
# Comma-separated list of admin email addresses.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 Important - Default Values: Hardcoded production email addresses in chart defaults.

Default values should use placeholders or be empty. Real email addresses create confusion about whether these are required values or just examples.

Suggested change
admin:
# Comma-separated list of admin email addresses.
# Comma-separated list of admin email addresses.
emails: ""

Add documentation in the (missing) README.md showing an example configuration.

Comment thread charts/integrations-hub/values.yaml
Comment on lines +27 to +32
{{- if .Values.ingress.root.annotations }}
{{ .Values.ingress.root.annotations | toYaml | nindent 4 }}
{{- else }}
{{ .Values.ingress.annotations | toYaml | nindent 4 }}
{{- end }}
spec:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion - Documentation: Clarify when ingress.root.annotations differs from ingress.annotations.

This fallback pattern exists but isn't documented. Add a brief comment explaining when root.annotations would be set differently (e.g., different ingress classes for root vs subpaths, different auth requirements).

If they're always the same, simplify to just use .Values.ingress.annotations.

@@ -0,0 +1,11 @@
apiVersion: v2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 Important - Missing Documentation: No README.md for the new chart.

Helm charts should include a README.md with:

  • Overview of what the chart deploys
  • Prerequisites (PostgreSQL setup, required secrets)
  • Installation instructions
  • Configuration examples (GCP Cloud SQL vs in-cluster PostgreSQL)
  • Values documentation (or auto-generated from values.yaml comments)
  • Upgrade notes

This is especially important for a new chart where users need guidance on the GCP vs non-GCP configurations, secret creation, and the rootPath / NEXT_PUBLIC_BASE_PATH coordination.

@all-hands-bot
Copy link
Copy Markdown
Contributor

Review Summary

[CRITICAL ISSUES] (Must fix before merge)

  • [charts/integrations-hub/templates/deployment.yaml, Line 62-66] Security: Password exposure in command substitution - see inline comment for fix
  • [charts/integrations-hub/values.yaml, Line 111] Default Values: Hardcoded production email addresses should be removed from defaults
  • [charts/integrations-hub/] Missing Documentation: No README.md for the new chart

[IMPROVEMENT OPPORTUNITIES] (Should fix)

  • [charts/integrations-hub/templates/_env.yaml, Line 150-190] Complexity: Deduplication logic needs inline documentation explaining WHY
  • [charts/integrations-hub/values.yaml, Line 196-199] Security: Legacy PostgreSQL image requires allowInsecureImages: true - document or upgrade
  • [charts/openhands/templates/ingress-integrations-hub.yaml, Line 27-32] Documentation: Clarify when root.annotations differs from base annotations

[TESTING GAPS]

  • [PR Description] No Evidence: The PR checklist is completely unchecked:

    • ❌ Chart version update not confirmed
    • ❌ Upgrade path not tested
    • ❌ Backward compatibility not verified
    • ❌ README.md not updated (because it doesn't exist yet)

    Add an Evidence section with:

    • helm install or helm template commands showing the chart renders correctly
    • helm lint charts/integrations-hub output
    • Deployment verification showing pods start and health checks pass
    • Database initialization logs confirming the init container works

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM

Factors increasing risk:

  • Security issue with password handling in init container
  • No testing evidence or completed checklist items
  • Missing documentation for a new infrastructure component
  • Legacy PostgreSQL image requires security policy override

Factors decreasing risk:

  • New optional chart with condition: integrations-hub.enabled (won't deploy unless explicitly enabled)
  • No breaking changes to existing openhands chart functionality
  • Good overall structure following Helm best practices
  • Proper security context configuration (runAsNonRoot, specific UID/GID)
  • Secrets properly referenced (not hardcoded)

Recommendation: Address the critical password security issue before merge. Complete the PR checklist items (especially testing upgrade path and adding README.md). The optional nature of the dependency limits blast radius, but the chart should be production-ready before initial release.


VERDICT:
⚠️ Needs rework: Fix critical security issue and complete checklist before merge. The core architecture is sound but implementation has security gaps.

KEY INSIGHT:
The Helm chart structure is well-designed with good separation of concerns, but the init container's database setup logic exposes passwords in process listings and the complete lack of documentation/testing evidence suggests this needs another iteration before it's ready for production use.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Co-authored-by: openhands <openhands@all-hands.dev>
@chuckbutkus chuckbutkus requested a review from all-hands-bot May 15, 2026 03:49
Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

Solid Helm chart implementation following best practices. The main issues are documentation gaps and configuration defaults that should be addressed before merge.

Comment thread charts/integrations-hub/Chart.yaml
Comment thread charts/integrations-hub/values.yaml
Comment thread charts/integrations-hub/values.yaml
Comment thread charts/openhands/templates/ingress-integrations-hub.yaml
Comment thread charts/integrations-hub/templates/_env.yaml
@chuckbutkus chuckbutkus requested a review from all-hands-bot May 15, 2026 04:25
Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

🟡 Acceptable - Solid Helm chart structure following best practices. The init container database setup logic could be simplified, and the PR checklist needs completion before merge.

[IMPROVEMENT OPPORTUNITIES]

  • [deployment.yaml, Init Containers] Complexity: Inline SQL script with heredocs is error-prone; consider ConfigMap approach (see inline comment)
  • [deployment.yaml, Line 103] Consistency: Two different wait strategies for init containers (see inline comment)
  • [PR Description] Incomplete Checklist: The Helm Chart Checklist is not completed - all boxes should be checked or marked N/A before merge

[UNRESOLVED FROM PREVIOUS REVIEWS]

These issues were flagged in previous reviews and still need attention:

  • Missing README.md for the chart (Important)
  • Legacy PostgreSQL image with global security bypass flag (Important)
  • Hardcoded production email addresses in chart defaults (Important)
  • Missing documentation for deduplication implementation and annotation fallback patterns (Suggestion)

[RISK ASSESSMENT]

⚠️ Risk Assessment: 🟡 MEDIUM

This PR adds a new optional infrastructure component (integrations-hub service + PostgreSQL dependency) with isolated blast radius. Medium risk due to:

  • New infrastructure dependency (PostgreSQL database)
  • Complex init container logic for database setup
  • Unresolved security/documentation issues from previous reviews
  • Incomplete PR checklist

Mitigating factors: Optional dependency (disabled by default), follows existing Helm chart patterns, no changes to core OpenHands functionality.

Recommendation: Address the incomplete PR checklist and consider the improvement suggestions before merge. The unresolved issues from previous reviews should also be tracked/addressed.

VERDICT:
Worth merging after checklist completion - Core chart structure is sound, follows best practices

KEY INSIGHT:
The chart architecture is solid, but init container database setup complexity could cause operational issues in edge cases - consider externalizing SQL scripts to ConfigMaps for better maintainability.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

if psql -h "$DB_HOST" -p "$DB_PORT" -U postgres -d postgres -c "SELECT 1;" 2>&1; then
echo "PostgreSQL is up!"

echo "Creating the database $DB_NAME if it doesn't exist..."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion - Complexity: The inline SQL script with heredocs and psql meta-commands is complex and error-prone.

Consider:

  1. Moving the SQL to a ConfigMap for easier testing and maintenance
  2. Adding clearer error messages that identify which step failed
  3. Using a more consistent wait strategy (the wait-for-postgres container below uses a different pattern)

Example ConfigMap approach:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: integrations-hub-init-sql
data:
  init.sql: |
    -- SQL commands here

Then mount and execute: psql ... -f /scripts/init.sql

- name: wait-for-postgres
image: bitnamilegacy/postgresql:latest
command: ['sh', '-c']
args:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Suggestion - Consistency: This init container uses a different wait strategy than create-db-user above (line 54):

  • create-db-user: 60 retries with 5 second sleep (5 minute timeout)
  • wait-for-postgres: Infinite until loop with 2 second sleep (no timeout)

Consider using a consistent pattern for both. The create-db-user approach with explicit timeout is safer.

@chuckbutkus chuckbutkus merged commit acfe18a into main May 15, 2026
24 checks passed
@chuckbutkus chuckbutkus deleted the add-integrations-hub-chart branch May 15, 2026 05:36
aivong-openhands added a commit that referenced this pull request May 19, 2026
Regenerates the lockfile via 'helm dependency update' to match the
dependency declarations on main:

- automation: 0.1.8 -> 0.1.9 (Chart.yaml has been at 0.1.9 since #634 etc.)
- adds integrations-hub: 0.1.0 (declared in Chart.yaml in #614, never
  reflected in the lockfile)
- digest + generated timestamp refreshed

The lockfile had been drifting because earlier dependency-bump PRs only
touched Chart.yaml. Same class of drift as #630.

No functional behavior change in this PR — it brings the recorded
lockfile into agreement with what helm dep update would produce
anyway at build time. Laminar dependency unchanged at 0.1.11; the
upgrade to 0.1.12 is tracked separately in #638.
aivong-openhands added a commit that referenced this pull request May 19, 2026
* PLTF-2687: sync Chart.lock with current Chart.yaml dependencies

Regenerates the lockfile via 'helm dependency update' to match the
dependency declarations on main:

- automation: 0.1.8 -> 0.1.9 (Chart.yaml has been at 0.1.9 since #634 etc.)
- adds integrations-hub: 0.1.0 (declared in Chart.yaml in #614, never
  reflected in the lockfile)
- digest + generated timestamp refreshed

The lockfile had been drifting because earlier dependency-bump PRs only
touched Chart.yaml. Same class of drift as #630.

No functional behavior change in this PR — it brings the recorded
lockfile into agreement with what helm dep update would produce
anyway at build time. Laminar dependency unchanged at 0.1.11; the
upgrade to 0.1.12 is tracked separately in #638.

* Bump openhands chart version to 0.7.18 for Chart.lock sync

Co-authored-by: openhands <openhands@all-hands.dev>

---------

Co-authored-by: openhands <openhands@all-hands.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants