secret-management: redact GitHub repository secret values from logs
- Dominant language
- C#
- Stars
- 135
- Forks
- 260
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 143
Description
## Summary
`tools/secret-management` can currently print GitHub repository secret values in logs/output when rendering access configs and during normal repository-secret reconciliation.
This can accidentally disclose configured secret values to local terminal output or CI/operator logs if `sync-access` is run with real `githubRepositorySecrets`.
I did not find a checked-in GitHub Actions or Azure Pipelines path in this repository that invokes `sync-access`, so this is best framed as a defense-in-depth/security hardening issue rather than an externally exploitable vulnerability.
## Affected areas
* `tools/secret-management/Azure.Sdk.Tools.SecretManagement.Cli/Commands/SyncAccessCommand.cs`
* `tools/secret-management/Azure.Sdk.Tools.AccessManagement/AccessManager.cs`
* `tools/secret-management/Azure.Sdk.Tools.AccessManagement/Config/AccessConfig.cs`
* `tools/secret-management/Azure.Sdk.Tools.AccessManagement/Config/GithubRepositorySecretsConfig.cs`
* `tools/secret-management/Azure.Sdk.Tools.AccessManagement/Config/BaseConfig.cs`
* `tools/secret-management/Azure.Sdk.Tools.AccessManagement/Reconciler.cs`
## Details
The CLI path calls `AccessManager.Run(...)`, which logs the rendered access config. That rendered config includes `githubRepositorySecrets`.
`GithubRepositorySecretsConfig.ToIndentedString()` currently prints both the secret name and the secret value.
Normal repository-secret reconciliation also logs `secret.Key:secret.Value` before and after setting a repository secret.
Template/property substitution can also convert placeholders into concrete values before logging, meaning templated secret values may also appear in output.
## Safe reproduction using dummy values
Use dummy values only, for example:
```json
{
"properties": {
"dummySecret": "DUMMY_SECRET_VALUE_DO_NOT_USE"
},
"githubRepositorySecrets": [
{
"repositories": ["example-owner/example-repo"],
"secrets": {
"DIRECT_DUMMY_SECRET": "DUMMY_SECRET_VALUE_DO_NOT_USE",
"TEMPLATE_DUMMY_SECRET": "{{ dummySecret }}"
}
}
]
}
```
When rendered/logged, the output can include values like:
```text
'DIRECT_DUMMY_SECRET': 'DUMMY_SECRET_VALUE_DO_NOT_USE'
'TEMPLATE_DUMMY_SECRET': 'DUMMY_SECRET_VALUE_DO_NOT_USE'
```
Normal sync logging can also include:
```text
Setting GitHub repository secret 'DIRECT_DUMMY_SECRET:DUMMY_SECRET_VALUE_DO_NOT_USE' ...
```
## Expected behavior
Logs should include repository names and secret names only.
Secret values should be omitted or redacted, for example:
```text
'DIRECT_DUMMY_SECRET': ''
'TEMPLATE_DUMMY_SECRET': ''
```
## Actual behavior
Rendered GitHub repository secret values can appear in logs/output.
## Impact
This can accidentally disclose repository secret values to local terminal output or any operator/CI logs where `sync-access` is run with real configs.
No external exposure path was identified in this repository’s checked-in workflows.
## Proposed fix
* Redact values in `GithubRepositorySecretsConfig.ToIndentedString()`
* Remove `secret.Value` from normal-mode `Reconciler` log messages
* Keep the actual secret-setting behavior unchanged
* Add tests proving dummy secret values do not appear in rendered config output or captured logs
## Suggested tests
Add focused tests under `Azure.Sdk.Tools.AccessManagement.Tests`:
* `GithubRepositorySecretsConfig_ToIndentedString_RedactsSecretValues`
* `AccessConfig_ToString_RedactsRenderedGithubRepositorySecretValues`
* `ReconcileGithubRepositorySecrets_DryRun_LogsSecretNameOnly`
* `ReconcileGithubRepositorySecrets_NormalMode_DoesNotLogSecretValue`
Contributor guide
Research direction
Start with GithubRepositorySecretsConfig.ToIndentedString() and AccessConfig.ToString(), then inspect Reconciler.cs and SyncAccessCommand.cs for the affected log paths. Run or add the focused tests under Azure.Sdk.Tools.AccessManagement.Tests, including the dry-run and normal-mode reconciliation cases. Done means repository and secret names remain visible while dummy secret values are absent from rendered output and captured logs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- security, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100