Upgrading from 2026.1 to the 2026.2 Innovation Release Innovation Release
- Hybrid Manager dual release strategy
- Documentation for the current Long-term support release
Upgrade from 2026.1 to 2026.2.
Role: Infrastructure Engineer
Prerequisites
Administrative access to the Kubernetes cluster (
kubectl,helm).Access to the HM installation configuration file or
values.yamlfile used for the current installation. To save the contents of your current installation configuration:helm get values edbpgai-bootstrap -n edbpgai-bootstrap > values.yaml
Required Tools:
helm(Latest version recommended)kubectl,yq,base64,jq
Upgrade 2026.1 → 2026.2
This release introduces a redesigned Identity Provider (IdP) configuration system and new Custom Resource Definitions (CRDs) that require manual pre- and post-upgrade steps.
Changes from previous release: IdP migration
- the
config.yaml, which previously loaded from theupm-dexsecret, is now mounted from a ConfigMap. Static connector configurations are no longer supported — connectors must be provisioned using the IdP Management API. Env var values like$DB_USERand$DB_PASSWORDare now obtained from theupm-db-urlsecret, which is propagated to theupm-dexnamespace automatically. - A new
hm-portal-bootstrapsecret must be created in thedefaultnamespace. It is replicated to theupm-dexnamespace automatically via the reloader annotation. It contains:fernet-key— encryption key for sensitive connector config fieldsstatic-passwords.yaml— initial user accounts for bootstrap access
- New CRDs are introduced in 2026.2 and must be applied manually before the upgrade, as Helm skips CRD changes.
- After a successful migration, manually remove the
upm-dexanddex-fernet-keysecrets.
Back up the current IdP settings
From the HM portal, log in with an owner account and go to
https://<portal_dns_name>/settings/identity-providers. For each IdP, save all settings including fields that are only partially visible on screen.Warning
The HM IdP API does not return sensitive fields such as
clientSecret(OIDC) orBindPassword(LDAP). Retrieve these values directly from your actual Identity Provider (e.g., Okta, Google) before proceeding.For EDB Internal: back up the
upm-dexsecret directly:kubectl get secret upm-dex -n upm-dex -o yaml > upm-dex-backup.yaml
Optionally, export the IdP connector configuration from the CLI:
kubectl get hcp edbpgai -o json | jq .spec.pgai.portal.authentication.idpConnectors > idps.json
Generate a certificate file from the existing IdP configuration
Extract the certificate from your existing IdP connector:
kubectl get hybridcontrolplane edbpgai -o yaml \ | yq '.spec.pgai.portal.authentication.idpConnectors[0].config.caData' \ | base64 -d > okta-cert.pem
Note
Adjust the array index if you have multiple connectors. Keep
okta-cert.pem— you will need it in step 8.Extract the fernet key from the
dex-fernet-keysecret:
```shell
DEX_FERNET_KEY=$(kubectl get secret -n upm-dex dex-fernet-key \
-o jsonpath='{.data.fernet-key}' | base64 -d)
```- Extract the static user passwords from the
upm-dexsecret's decoded `config.yaml:
```shell
staticPasswords=$(kubectl get secret -n upm-dex upm-dex -o yaml \
| yq '.data."config.yaml"' | base64 -d \
| yq '.staticPasswords')
```- Create the
hm-portal-bootstrapsecret in thedefaultnamespace using the values from steps 3 and 4:
```shell
kubectl create secret generic hm-portal-bootstrap \
--namespace default \
--from-literal=fernet-key="$DEX_FERNET_KEY" \
--from-literal=static-passwords.yaml="staticPasswords:
$staticPasswords"
# Add the replicator annotation
kubectl annotate secret hm-portal-bootstrap --namespace default \
replicator.v1.mittwald.de/replicate-to=upm-dex
```The replicator annotation ensures it is propagated to the upm-dex namespace:
Apply the new CRDs using the appropriate method for your environment:
Warning
Helm skips CRD changes during upgrades. These must be applied before upgrading.
<details><summary>If using Helm packages from the remote CS Helm repo:</summary>
```shell
helm pull edbpgai/edb-hcp-operator --version 2026.2.0 --untar
kubectl apply -f edb-hcp-operator/crds/preflight-crd.yaml
kubectl apply -f edb-hcp-operator/crds/postflight-crd.yaml
```
</details>
<br/>
<details><summary>For EDB Internal — ephemeral clusters:</summary>
```shell
git clone -b 2026.2 git@github.com:EnterpriseDB/edb-hcp-operator.git
cd edb-hcp-operator/deploy/charts/edb-hcp-operator/crds
kubectl apply -f preflight-crd.yaml
kubectl apply -f postflight-crd.yaml
```
</details>
<br/>
* Annotate the CRDs for Helm management:
```shell
kubectl annotate crd preflights.edbpgai.edb.com postflights.edbpgai.edb.com \
meta.helm.sh/release-name=edbpgai-bootstrap \
meta.helm.sh/release-namespace=edbpgai-bootstrap \
--overwrite
kubectl label crd preflights.edbpgai.edb.com postflights.edbpgai.edb.com \
app.kubernetes.io/managed-by=Helm \
--overwrite
```Perform the upgrade
Bootstrap method installations
Update your Helm repository:
helm repo update
Perform the upgrade:
helm upgrade --install edbpgai-bootstrap enterprisedb-edbpgai/edbpgai-bootstrap \ --version 2026.2.0 \ --values values.yaml \ --namespace edbpgai-bootstrap \ --wait
Operator method installations
For installations using the Operator method, you must update the version specification within your
HybridControlPlaneresource.Edit the
HybridControlPlaneresource:kubectl edit hybridcontrolplane <resource-name>
Where
<resource-name>is the name you assigned during installation.In the YAML editor, locate the
spec.version(or equivalent version field) and update it to2026.2.0.Save the changes. Force a reconciliation by annotating the resource:
kubectl annotate hybridcontrolplane <resource-name> --overwrite edbpgai.com/ready-for-upgrade=true
The operator will then detect the version change and begin the rolling update. You can monitor the progress with:
kubectl get hybridcontrolplane <resource-name> -w
Delete the auto-discovered IdP configuration:
After the upgrade, connect to the application database and run:
kubectl exec svc/app-db-rw -c postgres -n upm-beaco-ff-base -- \ psql -U postgres upm -c \ "UPDATE upm_api_admin.idp SET deleted_at = NOW() WHERE deleted_at IS NULL;"
Migrate connectors using the IdP Management API:
Before proceeding, confirm that
hm-portal-bootstrapexists in theupm-dexnamespace and thatupm-dexpods are running:kubectl get pods -n upm-dexUsing the portal UI
Log in with native credentials and go to Settings → Identity Providers.
Create a new IdP configuration with the following values:
Field Value Name okta(ensures the existing user config is maintained)Assertion Consumer Service URL https://<Portal URL>/auth/callback/oktaAudience URI https://<Portal URL>/auth/samlentity/oktaConnector ID oktaSingle Sign-On URL From your backup in step 1 Signature Certificate File okta-cert.pem— generated in step 2NameID Format PERSISTENTUser Attribute nameEmail Attribute emailClick Save.
Note
Save & Test often fails until IT updates the ACS URL and Audience URI in your IdP with the new
/oktasuffix. Raise a ticket with IT to request this update before testing.
Using the REST API
Use the settings saved in step 1 to populate the request body:
curl -i -k -X POST 'https://<portal_url>/api/v1/idp' \ --header 'x-access-key: <HM_org_owner_access_key>' \ --header 'Content-Type: application/json' \ --data '{ "general": { "name": "okta", "description": "Okta Identity Provider", "protocol": "OIDC" }, "oidcSettings": { "issuer": "https://<your_okta_domain>.okta.com", "clientId": "your_client_id", "clientSecret": "your_client_secret" }, "dexConnectorId": "okta" }'
Restart Dex:
Restart the Dex deployment to apply all configuration changes:
kubectl rollout restart deploy upm-dex -n upm-dexValidate the migration:
Check that static user (native credentials) login works.
Check that the IdP-configured login works.
Clean up
After confirming both logins work, remove the old secrets:
kubectl delete secret upm-dex -n upm-dex kubectl delete secret dex-fernet-key -n upm-dex