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 # 계획만 — 아무것도 바꾸지 않는다
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.
| Key | Component | Account | Source of truth |
|---|---|---|---|
PP_PG_PASSWORD | PostgreSQL | plantpulse | Command — ALTER ROLE (psql) |
PP_TEMPORAL_PASSWORD | Temporal backend PostgreSQL account | temporal | Command — ALTER ROLE (psql) |
PP_HIVE_PASSWORD | Hive metastore PostgreSQL account + Kyuubi inbound auth | hive | Command — ALTER ROLE (psql) + re-render |
PP_CASSANDRA_PASSWORD | Cassandra | cassandra | Command — ALTER ROLE (cqlsh) |
PP_REDIS_PASSWORD | Valkey | — | File — plantpulse-storage/cache/valkey/conf/valkey.conf |
PP_MINIO_PASSWORD | MinIO | minio | Startup env — MINIO_ROOT_PASSWORD |
PP_MQ_PASSWORD | Kafka + HiveMQ — one shared value | mq | File — kafka/config/jaas.conf + mqtt/conf/auth.properties |
PP_CEP_API_KEY | CEP API key (X-API-Key) | — | File — plantpulse-cep/config/plantpulse-cep.properties |
PP_DATA_GATEWAY_API_KEY | Data gateway API key | — | File — plantpulse-data-gateway/config/plantpulse-jdbc.properties |
PP_DATALAKE_ADMIN_PASSWORD | Admin console login | admin | Startup env — admin-api reads from its own environment variable |
PP_DATALAKE_ADMIN_API_KEY | Admin console log endpoint X-API-Key | — | Startup 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.
--listPP_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.
| Message | Meaning | Action |
|---|---|---|
probe=NEITHER | Neither new nor old value connects | Automation has no basis to judge. Verify the component state by direct access |
apply fails | Server-side change failed; stop immediately | Fix the cause and re-run the same command |
verify fails | Server changed but new value won't connect | Most dangerous. Journal is recorded as APPLIED — requires human review |
configure fails | Stop without restart | Intentional (booting on old config causes total auth failure). Fix the cause and retry |
variable not in the registry | Unregistered key | See Non-rotatable values below |
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.
| Variable | What | Key point of manual change |
|---|---|---|
PP_SPARK_PASSWORD | Spark/Kyuubi client account | No server account exists. hive-auth.properties creates the account with this value — sidecar refresh + restart |
PP_TSE_PASSWORD | Time series engine account | Sidecar refresh + restart |
PP_GRAVITINO_PASSWORD · PP_KESTRA_DB_PASSWORD | Respective backend PostgreSQL accounts | Data lake syncs PostgreSQL role password to the sidecar value on every boot — sidecar refresh + restart |
PP_KESTRA_ADMIN_PASSWORD | Kestra admin | Web console login accounts |
PP_TLS_KEYSTORE_PASSWORD (+ derived truststore set) | All certificates | Intertwined with certificate reissuance → Security configuration |
PP_OPCUA_PASSWORD | OPC-UA server (app container) | Outside the data lake |
PP_API_KEY · PP_FLOW_WEBHOOK_API_KEY | External callers (app container) | Outside the data lake |
PP_DATA_GATEWAY_WEB_PASSWORD · PP_CEP_WEB_PASSWORD | Query console browser login | Deliberate decision not to rotate (2026-09-07). Sidecar refresh + restart → Web console login accounts |
Do not
- Do not edit
pd secret rotatedirectly inside the container. Rotation journals and the sidecar must be on the host to survive container recreation. The host'spasswd.shinvokes it. - Do not expect changes to
bin/env.shdefault password to take effect. The sidecar wins. - Do not paste
--list --showoutput into tickets or chat. - Do not stop with
Ctrl+Cduring rotation and restart with a different value. The journal remembers the first value. Re-run with the same value to finish, then change again.
Related documentation
- Web console login accounts
- Password change (credential rotation) — manual procedure — values not covered by the tool
- Initial password change — full commissioning checklist