Skip to content

azure_core/azure_identity: introduce SecretBytes for ClientCertificateCredential#3807

Merged
heaths merged 6 commits intomainfrom
copilot/update-clientcertificatecredential
Feb 26, 2026
Merged

azure_core/azure_identity: introduce SecretBytes for ClientCertificateCredential#3807
heaths merged 6 commits intomainfrom
copilot/update-clientcertificatecredential

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

ClientCertificateCredential::new() previously required callers to base64-encode their certificate bytes and pass them as a Secret, only for the credential to immediately decode them. This replaces that with a purpose-built SecretBytes type that accepts raw bytes directly.

New SecretBytes type (in azure_core::credentials):

  • Wraps Vec<u8>; Debug and Display emit "SecretBytes" — no data leakage
  • PartialEq/Eq use constant-time comparison (same approach as Secret)
  • From<azure_core::Bytes>, From<&[u8]>, From<Vec<u8>>
  • Public bytes() accessor returns &[u8]

ClientCertificateCredential::new()certificate parameter changed from Secret to SecretBytes; the base64 decode step is removed.

Migration

Before:

let cert_bytes = std::fs::read("cert.pfx")?;
ClientCertificateCredential::new(tenant, client, Secret::new(base64::encode(cert_bytes)), None)?;

After:

let cert_bytes = std::fs::read("cert.pfx")?;
ClientCertificateCredential::new(tenant, client, SecretBytes::from(cert_bytes.as_slice()), None)?;

Breaking Change: ClientCertificateCredential::new()certificate is now SecretBytes instead of Secret. See CHANGELOG.md.

Original prompt

This section details on the original issue you should resolve

<issue_title>ClientCertificateCredential should take bytes instead of base64-encoded string for certificate</issue_title>
<issue_description>Current, the ClientCertificateCredential in azure_identity requires that the caller base64-encode the certificate bytes and pass them as a azure_core::credentialsSecret. We just turn around and base64-decode those. Not only is this wasteful, but taking what is otherwise a String doesn't make it plain what the dev should pass anyway.

Instead, define a SecretBytes struct that implements Display and Debug exactly as azure_core::credentials::Secret does so that no data is printed. Define it in a new module in azure_identity but import that module privately and re-export the SecretBytes publicly from the root of the crate. Update ClientCertificateCredential::new to take a SecretBytes instead of Secret and update all examples that show base64-encoding a file or some other bytes to just wrap those bytes in a SecretBytes instead.

SecretBytes should also implement PartialEq in constant time similar to Secret, and should implement From<Bytes> (specifically, azure_core::Bytes) as well as From<&[u8]>. Add tests appropriately.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: heaths <1532486+heaths@users.noreply.github.com>
Copilot AI changed the title [WIP] Update ClientCertificateCredential to accept bytes for certificate azure_identity: introduce SecretBytes for ClientCertificateCredential Feb 25, 2026
@heaths heaths marked this pull request as ready for review February 25, 2026 21:13
@heaths heaths self-requested a review as a code owner February 25, 2026 21:13
Copilot AI review requested due to automatic review settings February 25, 2026 21:13
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 improves azure_identity’s certificate credential ergonomics by letting callers pass raw PKCS#12 bytes directly, avoiding the previous base64 encode/decode roundtrip and making the API intent clearer.

Changes:

  • Added a new public SecretBytes type for securely holding secret byte buffers (no leakage via Debug/Display, constant-time Eq).
  • Updated ClientCertificateCredential::new() to accept SecretBytes and removed the base64 decode step.
  • Updated azure_identity’s changelog to document the new type and the breaking constructor signature change.

Reviewed changes

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

File Description
sdk/identity/azure_identity/src/secret_bytes.rs Introduces SecretBytes with safe formatting, constant-time equality, conversions, and unit tests.
sdk/identity/azure_identity/src/lib.rs Adds the module and re-exports SecretBytes from the crate root.
sdk/identity/azure_identity/src/client_certificate_credential.rs Switches ClientCertificateCredential::new() from Secret (base64 string) to SecretBytes (raw bytes) and updates tests accordingly.
sdk/identity/azure_identity/CHANGELOG.md Documents the new SecretBytes and the breaking API change in the unreleased section.

Copy link
Member

@heaths heaths left a comment

Choose a reason for hiding this comment

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

Rename the function and make sure tests pass - specifically, spell check and mitigation issues appropriately.

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

Copilot AI commented Feb 25, 2026

Rename the function and make sure tests pass - specifically, spell check and mitigation issues appropriately.

Renamed secret() to bytes() and ran cargo fmt in 70321e7. All 79 tests pass and clippy is clean.

heaths
heaths previously approved these changes Feb 25, 2026
Copy link
Member

@heaths heaths left a comment

Choose a reason for hiding this comment

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

@copilot commit/pull request instructions make clear to summarize the changes in the PR description - not retain your task list. Do that, and please suggest improvements to make sure you always do that because you most often don't after feedback for changes is provided.

@heaths
Copy link
Member

heaths commented Feb 25, 2026

@copilot summarize the changes in the PR description. Do not retain your task list.

Copy link
Contributor Author

Copilot AI commented Feb 25, 2026

@copilot summarize the changes in the PR description. Do not retain your task list.

Updated the PR description to a prose summary. I've also stored a memory to always replace task checklists with a summary before finalizing future PRs.

@heaths heaths enabled auto-merge (squash) February 25, 2026 21:40
LarryOsterman
LarryOsterman previously approved these changes Feb 25, 2026
@heaths
Copy link
Member

heaths commented Feb 25, 2026

@copilot move SecretBytes into the azure_core crate next to Secret and make sure its exported similarly. Update azure_core's and azure_identity's CHANGELOGS accordingly. The tests should also be moved.

For context, @chlowell and I talked about this offline. I initially wrestled with this myself and ended up echoing @JeffreyRichter in these matters about how we can almost move things up the dependency stack; however, leaving behind something somewhat intrinsic and is likely to be needed elsehwere in the root of azure_identity does feel a little dirty.

Moves `SecretBytes` from `azure_identity/src/secret_bytes.rs` into
`azure_core/src/credentials.rs`, placing it alongside `Secret`.

- `azure_identity` now re-exports it via
  `pub use azure_core::credentials::SecretBytes`
- Updated `ClientCertificateCredential` and its tests to import
  `SecretBytes` from `azure_core::credentials`
- Updated both `azure_core` and `azure_identity` CHANGELOGs

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

Copilot AI commented Feb 25, 2026

@copilot move SecretBytes into the azure_core crate next to Secret and make sure its exported similarly. Update azure_core's and azure_identity's CHANGELOGS accordingly. Th...

Done in 31374f3. SecretBytes is now defined in azure_core::credentials alongside Secret, with the tests moved there too. azure_identity re-exports it via pub use azure_core::credentials::SecretBytes. Both changelogs updated accordingly.

Copilot AI changed the title azure_identity: introduce SecretBytes for ClientCertificateCredential azure_core/azure_identity: introduce SecretBytes for ClientCertificateCredential Feb 25, 2026
- Remove bare `Debug` import; use `fmt::Debug` throughout
- Update SecretBytes doc comment to use linked references
- Fix azure_identity CHANGELOG to just say "Added SecretBytes"

Co-authored-by: heaths <1532486+heaths@users.noreply.github.com>
@github-actions
Copy link

Hi @copilot. We've noticed that new changes have been pushed to this pull request. Because it is set to automatically merge, we've reset the approvals to allow the opportunity to review the updates.

@github-actions github-actions bot dismissed stale reviews from heaths and LarryOsterman February 25, 2026 23:08

Hi @heaths. We've noticed that new changes have been pushed to this pull request. Because it is set to automatically merge, we've reset the approvals to allow the opportunity to review the updates.

SecretBytes is defined in azure_core::credentials and should be
imported from there directly. azure_identity uses it internally in
client_certificate_credential.rs but does not re-export it.

Co-authored-by: heaths <1532486+heaths@users.noreply.github.com>
heaths
heaths previously approved these changes Feb 25, 2026
chlowell
chlowell previously approved these changes Feb 25, 2026
@github-actions
Copy link

Hi @copilot. We've noticed that new changes have been pushed to this pull request. Because it is set to automatically merge, we've reset the approvals to allow the opportunity to review the updates.

@github-actions github-actions bot dismissed stale reviews from heaths and chlowell February 25, 2026 23:27

Hi @heaths. We've noticed that new changes have been pushed to this pull request. Because it is set to automatically merge, we've reset the approvals to allow the opportunity to review the updates.

@heaths
Copy link
Member

heaths commented Feb 26, 2026

/check-enforcer evaluate

@heaths heaths merged commit 0fabdb7 into main Feb 26, 2026
18 checks passed
@heaths heaths deleted the copilot/update-clientcertificatecredential branch February 26, 2026 01:32
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.

ClientCertificateCredential should take bytes instead of base64-encoded string for certificate

5 participants