Skip to content

Add built-in key mapping options (SecretKeyMappingOptions)#123

Merged
Kralizek merged 4 commits into
masterfrom
copilot/add-key-mapping-options
May 8, 2026
Merged

Add built-in key mapping options (SecretKeyMappingOptions)#123
Kralizek merged 4 commits into
masterfrom
copilot/add-key-mapping-options

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 8, 2026

Adds SecretKeyMappingOptions — shared across all three provider modes — to handle common secret-name-to-config-key projection patterns without requiring a custom KeyGenerator.

Summary

New API

public sealed class SecretKeyMappingOptions
{
    public string? SecretNamePathSeparator { get; set; } = "/";  // replaces "/" with ":" in secret-name portion
    public bool PrefixJsonKeysWithSecretName { get; set; } = true;
    public string? TargetSection { get; set; }
}

Exposed on all three options types as options.KeyMapping.

Mapping pipeline

Applied in order before KeyGenerator is called; the result becomes SecretKeyGeneratorContext.DefaultKey:

  1. For JSON keys: extract the JSON property path from RawKey, then either combine it with the mapped secret name (when PrefixJsonKeysWithSecretName = true) or use the JSON path directly (when false)
  2. For scalar keys: apply SecretNamePathSeparator normalization to the secret name
  3. Optionally prepend TargetSection
  4. Pass the resulting key as DefaultKey to KeyGenerator

RawKey retains the pre-mapping key. JsonPath is always computed from RawKey.

Usage examples

// Load a JSON secret directly as app config
builder.Configuration.AddSecretsManagerKnownSecret("my-app/production", options =>
{
    options.KeyMapping.PrefixJsonKeysWithSecretName = false;
});

// Load a JSON secret into a target section
builder.Configuration.AddSecretsManagerKnownSecret("my-app/production/email", options =>
{
    options.KeyMapping.PrefixJsonKeysWithSecretName = false;
    options.KeyMapping.TargetSection = "Email";
});

// Merge shared + env secrets with last-wins override
builder.Configuration.AddSecretsManagerKnownSecrets(
    ["/my-app/shared", "/my-app/production"],
    options =>
    {
        options.KeyMapping.PrefixJsonKeysWithSecretName = false;
        options.DuplicateKeyHandling = DuplicateKeyHandling.LastWins;
    });

Breaking change

The default SecretNamePathSeparator = "/" changes key generation for secrets with /-style names: /my-app/production/database now produces my-app:production:database (not /my-app/production/database). Set SecretNamePathSeparator = null to restore the previous verbatim behavior. See MIGRATION.md for details. CHANGELOG.md is unchanged; entries for this feature are deferred to the final 2.0.0 release notes.

How it was tested

  • 31 new tests covering SecretKeyMapper unit behavior (all option combinations, validation) and provider integration tests for KnownSecret, KnownSecrets, and Discovery modes across JSON and scalar secret types
  • Two existing tests with /-style secret names updated to assert the new default-mapped keys
  • All 168 tests pass; build passes with --warnaserror

Checklist

  • Tests added or updated for changed behaviour
  • Documentation updated where relevant (README, XML docs, migration guide)
  • No unrelated changes included
  • CI is green
  • Build passes with --warnaserror (zero warnings)

Copilot AI linked an issue May 8, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add built-in key mapping options for configuration Add built-in key mapping options (SecretKeyMappingOptions) May 8, 2026
Copilot AI requested a review from Kralizek May 8, 2026 07:36
Copy link
Copy Markdown
Owner

@Kralizek Kralizek left a comment

Choose a reason for hiding this comment

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

This looks very close. The implementation matches the direction of #121: SecretKeyMappingOptions is shared across all provider modes, mapping is centralized in SecretKeyMapper, RawKey stays pre-mapping, and DefaultKey is correctly passed to KeyGenerator after built-in mapping.

A few cleanup items before merging:

  1. Please remove the CHANGELOG.md changes from this PR. We decided not to add changelog entries for beta-internal changes until the final 2.0.0 release notes. The README and MIGRATION.md updates are fine.

  2. Please fix the migration guide wording that says After (2.0.1+). This is still part of the 2.0.0 beta/final stabilization path, not a 2.0.1 change. Prefer wording like After this change or Current 2.0 beta / 2.0.0 final behavior.

  3. Please adjust the PR body’s mapping-pipeline description. The implementation does not simply “strip or normalize” first. For JSON keys, it extracts the JSON path from RawKey, then either combines it with the mapped secret name or uses the JSON path directly, then prepends TargetSection.

No need to introduce inheritance between option classes.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 8, 2026

This looks very close. The implementation matches the direction of #121: SecretKeyMappingOptions is shared across all provider modes, mapping is centralized in SecretKeyMapper, RawKey stays pre-...

Done in f8d4d31:

  1. CHANGELOG.md changes reverted — the file is back to its original empty [Unreleased] sections.
  2. MIGRATION.md heading changed from 2.0.x — ... (SecretNamePathSeparator default change) / After (2.0.1+): to 2.0.0 — ... / Current 2.0 beta / 2.0.0 final behavior:.
  3. The PR body description has been updated to reflect the actual JSON-key mapping pipeline (extract JSON path, combine or strip secret name, prepend TargetSection).

Copilot AI requested a review from Kralizek May 8, 2026 08:02
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 8, 2026

@Kralizek Kralizek marked this pull request as ready for review May 8, 2026 08:30
@Kralizek Kralizek merged commit 7f5ff37 into master May 8, 2026
2 checks passed
@Kralizek Kralizek deleted the copilot/add-key-mapping-options branch May 8, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add built-in key mapping options

2 participants