Secret Management and Credential Safety - hmislk/hmis GitHub Wiki
Secret Management and Credential Safety
Audience: All developers contributing to hmislk/hmis
Why this matters: hmislk/hmis is an open-source repository. Any credential, password, or customer-identifying information committed to git is permanently public, even after deletion from the latest branch. Git history is immutable and anyone can have already cloned it.
What Must Never Be Committed
| Category | Examples |
|---|---|
| Database passwords | MySQL passwords, JNDI datasource passwords |
| Application server credentials | Payara admin password, master-password file |
| API keys | Anthropic API key, Cloudflare API token |
| Customer infrastructure | Production IP addresses, server hostnames |
| TLS/SSL material | .pem, .jks, .p12, .key, .cer files |
| Environment files | .env, secrets.properties, credentials.xml |
| Payara domain config | domain.xml, glassfish-resources.xml (already in .gitignore) |
How the Project Is Protected
1. .gitignore blocks known sensitive files
The project .gitignore (root of repo) blocks:
domain.xml
glassfish-resources.xml
*.jks *.p12 *.pem *.key
.env secrets.properties *-credentials.properties
These files are never tracked. If you need to share config, use a password manager or a private channel — never a GitHub comment or commit.
2. persistence.xml uses JNDI — not hardcoded credentials
Our src/main/resources/META-INF/persistence.xml only references JNDI names:
<jta-data-source>jdbc/coop</jta-data-source>
The actual database URL, username, and password are defined only in the Payara admin console (domain.xml), which is never committed. This is the correct pattern — never change it to hardcode credentials.
3. Pre-commit hook with gitleaks
Every developer should install the project's git security hooks. These run gitleaks on every git commit attempt and block the commit if secrets are detected.
Developer Setup (Required)
Run this once after cloning the repo:
chmod +x scripts/install-dev-hooks.sh
./scripts/install-dev-hooks.sh
This script:
- Installs
gitleaksto~/bin/if not present - Installs
pre-commitvia pip if not present - Installs the pre-commit hook into
.git/hooks/pre-commit
After this, every git commit will be automatically scanned.
Manual test
gitleaks detect --config=.gitleaks.toml -v
Config Files That Are Safe to Commit
| File | Why It's Safe |
|---|---|
persistence.xml |
Contains only JNDI name, no credentials |
web.xml |
No credentials |
beans.xml |
CDI config, no credentials |
| Migration SQL files | Schema changes only, no data |
pom.xml |
Build config, no credentials |
The Correct Pattern for Each Credential Type
Database credentials → Payara JDBC Connection Pool
Never do this:
<!-- WRONG — never hardcode -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.1.50/hmis"/>
<property name="javax.persistence.jdbc.password" value="MyPassword123"/>
Always do this:
<!-- CORRECT — JNDI reference only -->
<jta-data-source>jdbc/coop</jta-data-source>
Configure the actual connection in the Payara Admin Console under Resources → JDBC → Connection Pools.
API keys → Database config table
API keys (e.g. Anthropic, Cloudflare) are stored in the application's configuration table, managed via the admin UI. Example: the AI Chat feature reads AI Chat - Claude API Key from the database at runtime. Never hardcode these in Java source or properties files.
Local development overrides → ignored files
If you need a local override (e.g. a different DB URL for your laptop), create:
src/main/resources/application-local.properties
This pattern is in .gitignore. Never commit it.
What To Do If You Accidentally Commit a Secret
Act immediately — assume the credential is already compromised.
- Rotate/revoke the credential right now. Change the password, revoke the API key. Do not wait.
- Notify the team lead.
- Remove from git history:
# Remove a specific file from all history git filter-repo --path path/to/secret-file --invert-paths - Force-push after coordinating with the team.
- File a GitHub issue documenting what was exposed and when it was rotated.
Note: Force-pushing does not protect anyone who already cloned or forked the repo before the fix. Rotation is the only real remediation.
GitHub Repository Settings (Admins Only)
These settings should be enabled in github.com/hmislk/hmis → Settings → Security and analysis:
| Setting | Status |
|---|---|
| Secret scanning | Should be enabled |
| Push protection | Should be enabled — blocks pushes containing known secret patterns |
| Dependabot alerts | Recommended |
Push protection acts as a final safety net even if a developer's local hooks are not installed.
Gitleaks False Positives
If gitleaks blocks a commit that is not actually a secret (e.g. a test fixture, a placeholder value), you can add an allowlist entry in .gitleaks.toml:
[allowlist]
regexes = [
'''my_specific_false_positive_pattern''',
]
Always prefer fixing the allowlist over bypassing gitleaks with --no-verify. If you must bypass: never use --no-verify on a commit that touches config files or connection strings.
Related
- GitHub issue #19638 — tracking implementation
.gitleaks.toml— project-specific gitleaks rules.pre-commit-config.yaml— pre-commit hook configurationscripts/install-dev-hooks.sh— one-command developer setup- Persistence Configuration Guide