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:

  1. Installs gitleaks to ~/bin/ if not present
  2. Installs pre-commit via pip if not present
  3. 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.

  1. Rotate/revoke the credential right now. Change the password, revoke the API key. Do not wait.
  2. Notify the team lead.
  3. Remove from git history:
    # Remove a specific file from all history
    git filter-repo --path path/to/secret-file --invert-paths
    
  4. Force-push after coordinating with the team.
  5. 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/hmisSettings → 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 configuration
  • scripts/install-dev-hooks.sh — one-command developer setup
  • Persistence Configuration Guide