Skip to main content

Password · API Key Rotation

The service accounts for the data lake (PostgreSQL · Cassandra · Valkey · MinIO · Kafka/MQTT …) and API keys start with the same default values on every installation. You must change them during commissioning, then rotate them according to policy thereafter.

The tool for rotation is a single bin/passwd.sh on the host.

cd /opt/kopens/plantpulse-platform-docker

bin/passwd.sh --list # 바꿀 수 있는 키 + 계정명 + 현재값(마스킹) + 정본 위치
bin/passwd.sh PP_PG_PASSWORD # 값을 생략하면 프롬프트 — 권장 (히스토리 · ps 에 안 남는다)
bin/passwd.sh PP_PG_PASSWORD=<새비밀번호> # 인라인
bin/passwd.sh PP_CASSANDRA_PASSWORD PP_MINIO_PASSWORD # 여러 개를 한 번에 — 재시작 1회
bin/passwd.sh --dry-run PP_MQ_PASSWORD # 계획만 — 아무것도 바꾸지 않는다
Do not edit the password lines in the file directly

Passwords exist in two places separately — the value the server accepts (PostgreSQL account, Cassandra role …) and the value the client presents (some 20 configuration files). They do not sync automatically. Changing only the sidecar causes all clients to fail authentication on the next restart, and changing only the server fails immediately.

passwd.sh runs ① server-side account change → ② sidecar refresh → ③ config re-render → ④ restart in sequence, within a single command.

Keys you can rotate

Keys use the environment variable name as-is. There are no aliases like postgres · mq — which key belongs to which component is shown by --list.

KeyComponentAccountSource of truth
PP_PG_PASSWORDPostgreSQLplantpulseCommandALTER ROLE (psql)
PP_TEMPORAL_PASSWORDTemporal backend PostgreSQL accounttemporalCommandALTER ROLE (psql)
PP_HIVE_PASSWORDHive metastore PostgreSQL account + Kyuubi inbound authhiveCommandALTER ROLE (psql) + re-render
PP_CASSANDRA_PASSWORDCassandracassandraCommandALTER ROLE (cqlsh)
PP_REDIS_PASSWORDValkeyFileplantpulse-storage/cache/valkey/conf/valkey.conf
PP_MINIO_PASSWORDMinIOminioStartup envMINIO_ROOT_PASSWORD
PP_MQ_PASSWORDKafka + HiveMQ — one shared valuemqFilekafka/config/jaas.conf + mqtt/conf/auth.properties
PP_CEP_API_KEYCEP API key (X-API-Key)Fileplantpulse-cep/config/plantpulse-cep.properties
PP_DATA_GATEWAY_API_KEYData gateway API keyFileplantpulse-data-gateway/config/plantpulse-jdbc.properties
PP_DATALAKE_ADMIN_PASSWORDAdmin console loginadminStartup env — admin-api reads from its own environment variable
PP_DATALAKE_ADMIN_API_KEYAdmin console log endpoint X-API-KeyStartup env

Three meanings:

  • Command — server account is the source of truth. Change it with SQL/CQL; the configuration file is only a client copy.
  • File — the rendered file itself is the source of truth. Changed only by re-render + restart.
  • Startup env — injected at process startup. No runtime change API exists; restart is the only way to apply changes.

Do not change account names (PP_*_USER). They appear only as labels in --list. Renaming accounts is a different task requiring server-side role creation and permission transfer.

If you don't see both admin console keys in --list

PP_DATALAKE_ADMIN_PASSWORD · PP_DATALAKE_ADMIN_API_KEY were added on 2026-09-05. Packages before then have only 9 keys. In that case, the console password has no server-side account, so edit the sidecar directly and restart → Web console login accounts

Procedure — first time

During commissioning, rotate all registered keys to random values. --all is not passwd.sh but an option of the rotation engine rotate-secret.sh.

cd /opt/kopens/plantpulse-platform-docker

bin/rotate-secret.sh --dry-run --all --generate # 어떤 키가 걸리는지 확인 — 아무것도 안 바꾼다
bin/rotate-secret.sh --all --generate # 실행. 키마다 20자 무작위 값
bin/passwd.sh --list --show # 결과 확인 — 값이 그대로 찍히니 화면 공유 중에는 치지 마세요
  • Do this in the maintenance window. There is one restart during rotation, and the Kafka/MQTT path is disconnected during that time.
  • Secure a backup before you start.
  • Rotated values exist only in the sidecar /etc/kopens/plantpulse-platform.env. In handover documentation, note not the values but «who stores them».

Procedure — during operations, one at a time

cd /opt/kopens/plantpulse-platform-docker
bin/passwd.sh --dry-run PP_PG_PASSWORD # 계획 확인
bin/passwd.sh PP_PG_PASSWORD # 프롬프트에 새 값 입력

When done, verify.

bin/status.sh # 0 = 정상
docker exec plantpulse-datalake pd node psql -c "SELECT 1;" # 새 비밀번호로 실제 접속되나
docker exec plantpulse-datalake pd node cql -e "SELECT now() FROM system.local;"
curl -kfsS https://<server-ip>:4950/api/health | jq .status # OK 또는 WARN

If it fails — run the same command again

Rotation does not roll back. At the point of failure, it is unclear which value is valid, and attempting to undo will corrupt the state further. Instead, recover forward.

The old and new values are pre-logged on the host in /etc/kopens/rotation.journal (0600). Run the same command again and each component will probe to determine which value it currently accepts, then proceed. What is already changed is skipped.

MessageMeaningAction
probe=NEITHERNeither new nor old value connectsAutomation has no basis to judge. Verify the component state by direct access
apply failsServer-side change failed; stop immediatelyFix the cause and re-run the same command
verify failsServer changed but new value won't connectMost dangerous. Journal is recorded as APPLIED — requires human review
configure failsStop without restartIntentional (booting on old config causes total auth failure). Fix the cause and retry
variable not in the registryUnregistered keySee Non-rotatable values below
If you have worker nodes, rotation is rejected

If cluster workers are configured, the rotation tool rejects and stops. Each worker has its own sidecar; rotating only the master leaves workers on old values, splitting the cluster. For environments with workers, follow the manual procedure and repeat sidecar refresh and restart on each worker.

PP_MQ_PASSWORD — Kafka and HiveMQ change together

One value serves as the server-side credential store for both brokers and the connection password for all clients. You cannot change them separately; the rotation tool's validation succeeds only when both accept the new value.

Static JAAS does not accept old and new values simultaneously, so the message queue path drops during sequential broker and consumer restarts. Zero-downtime rotation is not supported.

PP_HIVE_PASSWORD — one value flows both directions

It is the value that the Hive metastore presents when connecting to PostgreSQL, and at the same time the value that clients must authenticate with when connecting to Kyuubi. Therefore the rotation tool changes both the PostgreSQL account and re-renders the config. Done manually with only one change, either the metastore or Kyuubi dies.

Non-rotatable values — rotate manually

If you provide a key not in the registry, the tool does not silently skip it but rejects it. Below are those not yet registered; change them using the manual procedure.

VariableWhatKey point of manual change
PP_SPARK_PASSWORDSpark/Kyuubi client accountNo server account exists. hive-auth.properties creates the account with this value — sidecar refresh + restart
PP_TSE_PASSWORDTime series engine accountSidecar refresh + restart
PP_GRAVITINO_PASSWORD · PP_KESTRA_DB_PASSWORDRespective backend PostgreSQL accountsData lake syncs PostgreSQL role password to the sidecar value on every boot — sidecar refresh + restart
PP_KESTRA_ADMIN_PASSWORDKestra adminWeb console login accounts
PP_TLS_KEYSTORE_PASSWORD (+ derived truststore set)All certificatesIntertwined with certificate reissuance → Security configuration
PP_OPCUA_PASSWORDOPC-UA server (app container)Outside the data lake
PP_API_KEY · PP_FLOW_WEBHOOK_API_KEYExternal callers (app container)Outside the data lake
PP_DATA_GATEWAY_WEB_PASSWORD · PP_CEP_WEB_PASSWORDQuery console browser loginDeliberate decision not to rotate (2026-09-07). Sidecar refresh + restart → Web console login accounts

Do not

  • Do not edit pd secret rotate directly inside the container. Rotation journals and the sidecar must be on the host to survive container recreation. The host's passwd.sh invokes it.
  • Do not expect changes to bin/env.sh default password to take effect. The sidecar wins.
  • Do not paste --list --show output into tickets or chat.
  • Do not stop with Ctrl+C during rotation and restart with a different value. The journal remembers the first value. Re-run with the same value to finish, then change again.