Skip to content

fix: honor kid and other credential fields on private_key_jwt/mTLS credential creation - #1489

Draft
harshithRai wants to merge 3 commits into
masterfrom
ghIssue1466
Draft

fix: honor kid and other credential fields on private_key_jwt/mTLS credential creation#1489
harshithRai wants to merge 3 commits into
masterfrom
ghIssue1466

Conversation

@harshithRai

@harshithRai harshithRai commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

🔧 Changes

When deploying a Private Key JWT client credential from a tenant config, the clientAuthCredentials handler only forwarded name, pem, and credential_type to the POST /clients/{id}/credentials API. Any other field the user set in the config, most notably kid, was silently dropped, so Auth0 auto-generated a kid instead of using the one specified. This resolves #1466.

The handler now forwards the full set of API-accepted optional fields on public_key credential creation: kid, alg, expires_at, and parse_expiry_from_cert. Fields left unset are omitted from the payload (filtered on != null, which drops null and undefined but preserves an explicit false such as parse_expiry_from_cert: false) to avoid sending nulls the API rejects. The forwarded set matches the public_key (PublicKeyCredential) create model in the SDK.

Scope is deliberately narrow: only the create path changed. Credential matching remains keyed on name, export shape is unchanged (Auth0 returns only name and credential_type on read, so kid/pem are never exported), and the "no pem means skip" safeguard that makes export then deploy non-destructive is untouched.

Shape

The credentials block accepts additional optional fields on creation. No existing field is renamed or removed.

YAML, before:

clients:
  - name: My API Client
    client_authentication_methods:
      private_key_jwt:
        credentials:
          - name: my-key-v2
            credential_type: public_key
            pem: |
              -----BEGIN PUBLIC KEY-----
              ...
              -----END PUBLIC KEY-----

YAML, after:

clients:
  - name: My API Client
    client_authentication_methods:
      private_key_jwt:
        credentials:
          - name: my-key-v2
            credential_type: public_key
            kid: my-custom-kid          # optional, honored on create; auto-generated if omitted
            alg: RS256                   # optional
            expires_at: '2027-01-01T00:00:00.000Z'  # optional
            pem: |
              -----BEGIN PUBLIC KEY-----
              ...
              -----END PUBLIC KEY-----

Directory mode (client JSON), before:

{
  "name": "My API Client",
  "client_authentication_methods": {
    "private_key_jwt": {
      "credentials": [
        { "name": "my-key-v2", "credential_type": "public_key", "pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n" }
      ]
    }
  }
}

Directory mode (client JSON), after:

{
  "name": "My API Client",
  "client_authentication_methods": {
    "private_key_jwt": {
      "credentials": [
        { "name": "my-key-v2", "credential_type": "public_key", "kid": "my-custom-kid", "alg": "RS256", "pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n" }
      ]
    }
  }
}

📚 References

🔬 Testing

Unit: added a handler test asserting kid and alg are forwarded, that an explicit parse_expiry_from_cert: false is sent, and that null/undefined optional fields are omitted from the create payload. Full suite passes (1481 passing, 0 failing).

Manual, against a live dev tenant, in both YAML and directory formats:

  1. Add a private_key_jwt credential with a custom kid and a public-key pem to a client config.
  2. Run a dry run and confirm the client CREATE is previewed with no handler crash.
  3. Import, then GET /clients/{id}/credentials and confirm the credential's kid equals the configured value (previously it was a random auto-generated value).
  4. Re-import to confirm idempotency (no re-create), and export then re-import to confirm the credential is not deleted (no pem in an export means skip).

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@codecov-commenter

codecov-commenter commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.54%. Comparing base (5968f81) to head (d892f73).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1489   +/-   ##
=======================================
  Coverage   80.54%   80.54%           
=======================================
  Files         166      166           
  Lines        7920     7922    +2     
  Branches     1771     1771           
=======================================
+ Hits         6379     6381    +2     
  Misses        829      829           
  Partials      712      712           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@harshithRai harshithRai changed the title fix(clients): honor kid and other credential fields on private_key_jwt/mTLS credential creation fix: honor kid and other credential fields on private_key_jwt/mTLS credential creation Sep 10, 2026
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.

kid field ignored in tenant YAML credentials for private_key_jwt client authentication

2 participants