Credentials Reference¶
This page does NOT contain actual passwords
This document only describes where credentials are stored and who manages them. Never put actual passwords, tokens, or keys in documentation or git repositories.
Credential Locations¶
Infrastructure Access¶
| Credential | Storage Location | Managed By |
|---|---|---|
| NUC user password | Not stored digitally -- ask Hari directly | Hari |
| Cloud root password | Contabo control panel | Hari |
| Cloud user passwords | /etc/shadow on the cloud server | Hari |
Application Credentials¶
| Credential | Storage Location | Managed By |
|---|---|---|
| AstraPBX API admin token | /opt/astrapbx/.env on cloud server | Hari |
| Zoiper user passwords | Database (did_numbers / extensions table) | Generated per user |
| Database password | /opt/astrapbx/.env on cloud server | Hari |
VPN and Tunnel¶
| Credential | Storage Location | Managed By |
|---|---|---|
| WireGuard private keys | /etc/wireguard/wg0.conf on each server | Hari |
| WireGuard public keys | Exchanged between peers in wg0.conf | Hari |
| Cloudflare Tunnel token | Cloudflare Zero Trust dashboard | Hari |
Third-Party Accounts¶
| Service | Account | Managed By |
|---|---|---|
| Cloudflare | Hariandprojects@gmail.com | Hari |
| GitHub (astradial) | astradial org | Hari |
| Netdata Cloud | Hari's Netdata account | Hari |
| Contabo | Contabo customer portal | Hari |
Retrieving Credentials¶
AstraPBX API Token¶
Zoiper User Password¶
Query the database on the cloud server:
ssh root@89.116.31.109
psql -U astrapbx -d astrapbx_db -c "SELECT username, password FROM extensions WHERE username = 'org_mna9x47k_1001';"
WireGuard Keys¶
Security Policies¶
Mandatory rules for all team members
Never do these:
- Never commit passwords, tokens, or private keys to git
- Never share credentials over Slack, email, or any unencrypted channel
- Never store credentials in plain text files outside of the designated locations above
- Never reuse passwords across services
Always do these:
- Share credentials only through secure, ephemeral channels (in person, encrypted messaging, or a secrets manager)
- Rotate shared credentials when a freelancer or contractor's access is revoked
- Use SSH keys instead of passwords for server access
- Use unique, generated passwords for each Zoiper user account
Access Revocation Checklist¶
When a freelancer or contractor finishes their engagement:
- [ ] Remove their SSH user account from the cloud server
- [ ] Remove their SSH user account from the NUC (if applicable)
- [ ] Remove their SSH public key from all
authorized_keysfiles - [ ] Remove their email from Cloudflare Access policies
- [ ] Disable or delete their Zoiper extension credentials
- [ ] Rotate the AstraPBX API token if they had access to it
- [ ] Rotate any other shared secrets they may have seen
- [ ] Revoke GitHub access if they were added to the
astradialorg - [ ] Review and remove any WireGuard peer configurations they used
Rotation History¶
A running log of credential rotations. Why this exists: when a rotation happens because of a leak, future-you needs to know what was in scope (so you can stop trusting any artefact dated before the rotation).
Entries are most-recent-first. Don't put actual rotated values here — only state what was rotated and where the new value lives now.
2026-05-17 — leaked-secret sweep¶
Audit driven by gitleaks scan of internal-docs + astradial-platform. Found several real credentials committed to repos. Rotated all that were live on prod or staging; documented value still hot but pending for the one we can't rotate without customer access (V7 SIP trunk).
| Credential | Where it was leaked | Where it was rotated | Verified | New value lives in |
|---|---|---|---|---|
| MSG91 auth key (Hindi-Tutoring org) | internal-docs/docs/guides/hindi-daily-word-setup.md | Staging DB — organizations.settings.msg91_authkey for org 9dede1af-... | ✅ DB row updated, length matches new key | DB only (Hindi-Tutoring side project, no env) |
Staging ODBC password (pbx_user) | astradial-platform/sip-gateway/cloud-staging/res_odbc.conf | mariadb -uroot ALTER USER on staging | ✅ old rejected, new auths, Asterisk ODBC reconnected | /etc/asterisk/res_odbc.conf + /opt/astrapbx/.env on staging VPS |
Prod ODBC password (pbx_api) | Was pbx_secure_password (literal weak string) — astradial-platform/sip-gateway/cloud-prod/res_odbc.conf and api/database/README.md and api/config/config.js fallback and api/docs/deployment/SESSION_LOG.md | mariadb -uroot ALTER USER on prod | ✅ old rejected, new auths, Asterisk ODBC + Node API reconnected | /etc/asterisk/res_odbc.conf + /opt/astrapbx/.env on prod VPS |
| Prod AMI secret | Was also pbx_secure_password — astradial-platform/api/docs/deployment/SESSION_LOG.md:61 | Updated /etc/asterisk/manager.conf + /opt/astrapbx/.env AMI_SECRET on prod | ✅ AMI login test with new secret, old rejected | /etc/asterisk/manager.conf + /opt/astrapbx/.env on prod VPS |
| Grand Estancia org API key | internal-docs/docs/guides/grandestancia-setup.md (7 hits) + whatsapp-bridge.md (2) + org-onboarding.md (1) + .claude/settings.local.json (4) | organizations.api_key UPDATE for org ba50c665-... | ✅ HTTP 401 on old key, HTTP 200 on new key | Prod DB row only |
| V7 cloud SIP trunk password | internal-docs/docs/customers/v7-setup.md:194, v7-ucm-trunk-change.md:18 | Cloud Asterisk /etc/asterisk/pjsip_vseven_hotels.conf [org_moijhj2l_trunk1777732151626_auth] + V7 UCM6301 trunk AstradialCloud | ✅ cloud config updated, UCM updated via web UI through SSH tunnel (ssh -L 8089:192.168.0.60:8089 root@89.116.31.109 → wg1 → V7 LAN). Leaked literal verified gone from cloud config. | Cloud /etc/asterisk/pjsip_vseven_hotels.conf (mode 640, root-only) + V7 UCM6301 admin config |
Note on V7 trunk registration state at time of rotation: The trunk was already Unavailable (UCM not actively registering) for ~20 hours before the rotation — matches the existing "trunk-to-trunk gating" issue tracked in v7-setup.md. The rotation succeeded at the security layer (leaked password no longer accepted by cloud), but verifying end-to-end registration with the new password requires the trunk to recover from the pre-existing operational issue, which is separate work (Grandstream + BSNL meeting).
Residual scrub TODO: /etc/asterisk/pjsip_vseven_hotels.conf on prod has a doc-comment line ; Password: eb5b4c952... that's still plaintext on disk. Not security-active (Asterisk ignores comments) but should be auto-cleaned on next API-driven config regen for V7.
Audit-trail also affected (rotated as side-effects)¶
- Audited
pbx_api_user@localhost(second MariaDB user) — not vulnerable to the leaked weak password (different hash). Left alone. - Audited
pipecat_org_config.google_api_keyfor all orgs — never leaked to any repo. Left alone (still cleartext in DB; future hardening item). - Audited
org_api_keystable — empty, no rotation needed. - Removed
api/config/config.jsfallback topbx_secure_password— the code now requiresDB_PASSWORDenv var (no insecure default). - Untracked
internal-docs/.claude/settings.local.json(added to.gitignore) — the file held cached curl commands with the leaked GE API key in Bash permissions strings.
Hardening follow-ups (future work, not rotations)¶
These came up during the audit and are worth tracking:
res_odbc.confshould be env-templated, not have literal passwords committed. Convert deploy pipeline to substitute${ODBC_PASSWORD}from/opt/astrapbx/.envat deploy time. Same for cloud-prod and cloud-staging variants.- Cleartext secrets in prod DB (data at rest):
users.sip_password,sip_trunks.password,customer_tunnels.preshared_key,organizations.api_secret,webhooks.secret,pipecat_org_config.google_api_key. Anyone with DB access can read them all. Eventual fix: encrypt-at-rest with a KMS-managed key, or at minimum tighten DB-user grants. api/docs/deployment/SESSION_LOG.md+VPS_DEPLOYMENT.md— contain full prod SSH playbook + DB-delete commands. They're scrubbed ofpbx_secure_passwordnow but still expose prod VPS IP, hostnames, and operational layout. Consider moving content to this repo (docs/operations/) and deleting fromastradial-platform.pbx_user/pbx_apishare their password with the API .env. If the API leaks its env, the ODBC password leaks too. Eventually want separate users with separate passwords for Asterisk-side ODBC vs. Node API connection.
Discipline going forward¶
- Never commit a real password to either repo, even on staging. Treat
.env-style values as "lives only on the VPS." Use templates like__ODBC_PASSWORD__placeholders in committed config files and let the deploy pipeline substitute them. - For local-only
mariadbrotations, always usemariadb -uroot(socket auth on the Linux root), feed SQL via stdin from amktempfile with mode 600, redirect stderr to/dev/null. The-e "ALTER USER ..."form echoes the SQL on errors, which can expose the new password value back to stdout — that's how this audit's first attempt leaked the new staging password into a chat transcript. - When a credential is committed, rotating is the only thing that makes the value worthless. Git history rewriting / force-push is cosmetic — it doesn't reach existing clones, cached commit URLs, or anyone who already read the page. Rotation is the load-bearing step; scrubbing is hygiene.