Skip to content

fix: replace hardcoded credentials with placeholders and add gitleaks config#436

Merged
aurelianware merged 3 commits intomainfrom
copilot/fix-security-scan-failures
Mar 5, 2026
Merged

fix: replace hardcoded credentials with placeholders and add gitleaks config#436
aurelianware merged 3 commits intomainfrom
copilot/fix-security-scan-failures

Conversation

Copy link
Contributor

Copilot AI commented Mar 5, 2026

  • Replace real-looking Azure AD Client ID UUID in docs/testing/test-attachment-oauth.sh with placeholder your-client-id
  • Replace hardcoded SFTP password in infra/k8s/x12-275-upload-job.yaml (fallback default + Secret manifest) with placeholder changeme
  • Create .gitleaks.toml at repository root
  • Fix .gitleaks.toml: remove invalid [[rules]] blocks that lacked regex/path/keywords fields — gitleaks v8.24.3 fatally rejects such rules; consolidate all suppressions into the global [allowlist] section
Original prompt

The security scans failed.

  1. test-attachment-oauth.sh — verify the API_CLIENT_ID and token in there are either placeholders or already-expired OAuth tokens. If they were real, revoke them in whatever IdP issued them. I included the allowlist entry assuming they’re test values, but worth confirming.
  2. k8s/x12-275-upload-job.yaml — confirm the password field is a placeholder. If it’s a real dev credential, rotate it and swap in a Kubernetes secret reference.
    After committing, you can do a dry run with gitleaks detect --config .gitleaks.toml -v to confirm the findings are suppressed.​​​​​​​​​​​​​​​​

Add the following gitleaks tool file

.gitleaks.toml - Gitleaks configuration for Cloud Health Office

Suppresses known false positives from documentation examples,

Cosmos DB Emulator keys, test fixtures, and placeholder values.

title = "Cloud Health Office Gitleaks Config"

[allowlist]

---------------------------------------------------------------

Documentation & example files containing placeholder credentials

---------------------------------------------------------------

paths = [
'''docs/CMS-0057-F-COMPLIANCE.md''',
'''docs/SECRETS-INVENTORY.md''',
'''api/quickstarts/.*.md''',
'''.github/.copilot-instructions''',
]

Known safe patterns (Cosmos DB Emulator key, placeholder tokens, etc.)

regexes = [
# Azure Cosmos DB Emulator well-known key
'''C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==''',
# Common placeholder patterns
'''your-client-id''',
'''your-secret''',
'''your-api-key''',
'''changeme''',
'''UPDATE THIS IN P(RODUCTION)?''',
]

---------------------------------------------------------------

Per-rule allowlists for specific false positive patterns

---------------------------------------------------------------

README.md curl examples with Bearer token placeholders

[[rules]]
id = "curl-auth-header"
description = "curl Authorization header"
[rules.allowlist]
paths = [
'''README.md''',
'''src/portal/CloudHealthOffice.Portal/Pages/Apis.razor''',
]

TypeScript test imports misidentified as API keys

(e.g., mapX12278ToFhirPriorAuth export names)

[[rules]]
id = "generic-api-key"
description = "Generic API Key"
[rules.allowlist]
paths = [
'''src/fhir/mapping/tests/..test.ts''',
'''src/fhir/tests/.
.test.ts''',
]
regexes = [
# TypeScript named imports/exports flagged as keys
'''mapX12\d+To\w+''',
]

SECURITY.md example JSON showing secret format

[[rules]]
id = "generic-api-key-security-md"
description = "SECURITY.md example values"
[rules.allowlist]
paths = [
'''SECURITY.md''',
]
regexes = [
'''qnxt_api_key''',
'''claims_backend_api_key''',
]

Cosmos DB Emulator key in dev config and tests

[[rules]]
id = "generic-api-key-cosmos-emulator"
description = "Cosmos DB Emulator key in dev settings"
[rules.allowlist]
paths = [
'''services/./appsettings.Development.json''',
'''services/.
/appsettings.json''',
'''services/shared/.Tests/..cs''',
'''services/tenant-service/README.md''',
]

Stripe test keys in Argo workflow

[[rules]]
id = "curl-auth-user"
description = "curl -u auth (Stripe test keys)"
[rules.allowlist]
paths = [
'''argo-workflows/tenant-onboarding.yaml''',
]

Test script OAuth placeholders

[[rules]]
id = "generic-api-key-test-scripts"
description = "Test script placeholder credentials"
[rules.allowlist]
paths = [
'''test-attachment-oauth.sh''',
]

K8s manifest placeholder passwords

[[rules]]
id = "generic-api-key-k8s"
description = "K8s manifest placeholder passwords"
[rules.allowlist]
paths = [
'''k8s/.*.yaml''',
]


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…aks config

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix security scan failures and update gitleaks configuration fix: replace hardcoded credentials with placeholders and add gitleaks config Mar 5, 2026
@github-actions github-actions bot added documentation Improvements or additions to documentation github-config infrastructure size/M and removed size/M labels Mar 5, 2026
@aurelianware
Copy link
Owner

@copilot the gitleaks scans are still failing

Gitleaks v8.24.3 requires every [[rules]] entry to have a regex, path,
or keywords field. The previous config had bare [[rules]] blocks with
only allowlist sub-sections and no detection pattern, causing a fatal
config-load error before any scanning occurred.

Consolidate all per-file and per-pattern suppressions into the global
[allowlist] section (paths + regexes), which is fully valid in all
gitleaks v8 versions and doesn't require per-rule overrides.

Co-authored-by: aurelianware <194855645+aurelianware@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 5, 2026

@copilot the gitleaks scans are still failing

Fixed in e4a6f90. The root cause was that gitleaks v8.24.3 requires every [[rules]] entry to have a regex, path, or keywords field — the previous config had bare [[rules]] blocks containing only [rules.allowlist] sub-sections with no detection pattern, so gitleaks fatally rejected the config file before scanning anything.

Restructured .gitleaks.toml to consolidate all per-file and per-pattern suppressions into the global [allowlist] section (paths + regexes), which is valid across all gitleaks v8 versions.

@github-actions github-actions bot added the size/S label Mar 5, 2026
@aurelianware aurelianware marked this pull request as ready for review March 5, 2026 03:35
Copilot AI review requested due to automatic review settings March 5, 2026 03:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses security-scan findings by replacing real-looking credentials in test/deployment assets with placeholders and by introducing a repository-level Gitleaks configuration to suppress known false positives.

Changes:

  • Replaced hardcoded SFTP password values in the X12 275 upload CronJob manifest with a placeholder.
  • Replaced a real-looking Azure AD Client ID in the OAuth attachment test script with a placeholder.
  • Added a root .gitleaks.toml to suppress known false positives in docs/examples and test fixtures.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
infra/k8s/x12-275-upload-job.yaml Swaps hardcoded SFTP password values to placeholders in the workflow + inline Secret.
docs/testing/test-attachment-oauth.sh Replaces Azure AD client ID with your-client-id placeholder.
.gitleaks.toml Adds Gitleaks allowlist configuration to reduce false positives.

Comment on lines 94 to 98
# Use default password if secret doesn't exist
if [ -z "${SFTP_PASS}" ]; then
echo "⚠️ SFTP_PASS not set, using default (UPDATE IN PRODUCTION!)"
SFTP_PASS="sJ8p8WAsE4Es6PgMbUACErOs"
SFTP_PASS="changeme"
fi
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow still falls back to a hardcoded SFTP password when the Secret is missing. Even with a placeholder value, this can mask misconfiguration and encourages running with an insecure default. Safer behavior is to fail fast (exit non-zero) when SFTP_PASS isn’t provided, and keep any dev-only defaults out of the manifest.

Copilot uses AI. Check for mistakes.
Comment on lines 266 to 273
kind: Secret
metadata:
name: sftp-credentials
namespace: cho-workflows
type: Opaque
stringData:
password: "sJ8p8WAsE4Es6PgMbUACErOs" # UPDATE THIS IN PRODUCTION!
password: "changeme" # UPDATE THIS IN PRODUCTION!
username: "logicapp"
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This manifest defines a Kubernetes Secret with a known default password (changeme). Even as a placeholder, committing an apply-ready Secret with a weak default creates a footgun (it’s easy to deploy to a real cluster unchanged). Prefer removing this Secret from the manifest (create it out-of-band) or converting it to an explicit template value like REPLACE_WITH_SFTP_PASSWORD so it can’t be mistaken for a usable credential.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +30
'''services/.*/appsettings\.Development\.json''',
'''services/.*/appsettings\.json''',
'''services/shared/.*Tests/.*\.cs''',
'''services/tenant-service/README\.md''',
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The allowlist paths entries under services/... don’t match the repository layout (services live under src/services/...). As written, these patterns won’t apply to files like src/services/tenant-service/appsettings.json / appsettings.Development.json, so the intended suppressions may not work.

Suggested change
'''services/.*/appsettings\.Development\.json''',
'''services/.*/appsettings\.json''',
'''services/shared/.*Tests/.*\.cs''',
'''services/tenant-service/README\.md''',
'''src/services/.*/appsettings\.Development\.json''',
'''src/services/.*/appsettings\.json''',
'''src/services/shared/.*Tests/.*\.cs''',
'''src/services/tenant-service/README\.md''',

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +36
# Test scripts and K8s manifests use placeholder credentials
'''docs/testing/test-attachment-oauth\.sh''',
'''k8s/.*\.yaml''',
'''infra/k8s/.*\.yaml''',
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [allowlist].paths entries for '''infra/k8s/.*\.yaml''' (and '''k8s/.*\.yaml''') suppress gitleaks findings for entire Kubernetes manifest directories that currently contain real credentials such as MongoDb__ConnectionString and SFTP_PASS. Because these files hold actual connection strings and passwords, disabling secret scanning on them means newly committed or rotated secrets will not be detected, making credential leakage through the repo or its history much more likely. Restrict the allowlist to specific files or exact placeholder patterns (e.g., specific dummy values) instead of whole directories that include manifests with real secrets so gitleaks continues to flag any non-placeholder credentials.

Suggested change
# Test scripts and K8s manifests use placeholder credentials
'''docs/testing/test-attachment-oauth\.sh''',
'''k8s/.*\.yaml''',
'''infra/k8s/.*\.yaml''',
# Test scripts that intentionally use placeholder credentials
'''docs/testing/test-attachment-oauth\.sh''',

Copilot uses AI. Check for mistakes.
@aurelianware aurelianware merged commit 5544986 into main Mar 5, 2026
35 checks passed
@aurelianware aurelianware deleted the copilot/fix-security-scan-failures branch March 5, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants