Skip to content

[WIP][forge-iterating] [CIAM Cred Mgmt] PR2 — Public API Surface (Passkey/FIDO Only) - #3008

Draft
Sergei Demchenko (antrix1989) wants to merge 6 commits into
sedemche/ciam-cred-managment-releasefrom
sedemche/ciam-cred-managment-pr2-public-api
Draft

[WIP][forge-iterating] [CIAM Cred Mgmt] PR2 — Public API Surface (Passkey/FIDO Only)#3008
Sergei Demchenko (antrix1989) wants to merge 6 commits into
sedemche/ciam-cred-managment-releasefrom
sedemche/ciam-cred-managment-pr2-public-api

Conversation

@antrix1989

@antrix1989 Sergei Demchenko (antrix1989) commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

[CIAM Cred Mgmt] PR2 — Public API Surface (Passkey/FIDO Only)

Summary

This PR adds the complete public API surface for the Credential Management SDK, scoped to passkey (FIDO2/WebAuthn) credential type only.

All implementations are stubs (fatalError("Not implemented")) — this PR is purely for API shape review.

Work Item

AB#3654791

Files Added (14 total)

  • MSALNativeCredentialMethodsClient — Main client
  • MSALNativeCredentialManagementConfig — Config class
  • MSALNativeCredentialManagementError — Error types
  • MSALCredentialMethodProtocol — Protocol
  • MSALCredentialType — Type identifier
  • MSALCredentialMethod — Internal base class
  • MSALPasskeyCredentialMethod — Passkey type
  • MSALRegisterMethods + MSALRegisterMethods+Passkey
  • MSALRegisterParams / MSALRegisterPasskeyParams
  • MSALCredentialMethodRegistrationResult + ChallengeState
  • Token provider protocol + stub

Build Verification

swift build passes cleanly.

Not Included (Future PRs)

  • Password/Phone credential types
  • Network layer implementation
  • Unit tests (PR3+)

This commit adds the complete public API surface for the Credential Management
SDK, limited to passkey (FIDO2/WebAuthn) credential type only.

All implementations are stubs (fatalError) — this PR is purely for API shape review.

New files:
- MSALNativeCredentialMethodsClient — Main client (list/register/delete)
- MSALNativeCredentialManagementConfig — Configuration class
- MSALNativeCredentialManagementError — Error types
- MSALCredentialMethodProtocol — Protocol for credential methods
- MSALCredentialType — Extensible type identifier
- MSALCredentialMethod — Internal base class
- MSALPasskeyCredentialMethod — Passkey concrete type
- MSALRegisterMethods — Registration namespace
- MSALRegisterMethods+Passkey — Passkey registration extension
- MSALRegisterParams/MSALRegisterPasskeyParams — Params classes
- MSALCredentialMethodRegistrationResult — Result enum + ChallengeState
- MSALNativeCredentialManagementTokenProvider — Token provider protocol
- MSALNativeAuthTokenProvider — Built-in MSAL token provider (stub)

Work item: AB#3654791

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@antrix1989
Sergei Demchenko (antrix1989) requested a review from a team as a code owner June 9, 2026 00:27
@antrix1989
Sergei Demchenko (antrix1989) requested review from Ameya Patil (ameyapat) and Kai (kaisong1990) and removed request for a team June 9, 2026 00:27
@antrix1989 Sergei Demchenko (antrix1989) changed the title [forge-iterating] [CIAM Cred Mgmt] PR2 — Public API Surface (Passkey/FIDO Only) [WIP][forge-iterating] [CIAM Cred Mgmt] PR2 — Public API Surface (Passkey/FIDO Only) Jun 9, 2026
@antrix1989
Sergei Demchenko (antrix1989) marked this pull request as draft June 9, 2026 00:54
The error contract is not finalized yet. Keep only the base
MSALNativeCredentialManagementError class with a single generalError
case. All detailed error types (networkError, unauthorized, forbidden,
notFound, conflict, challengeFailed, sessionExpired,
invalidConfiguration, invalidInput) will be added in a future PR once
the contract is finalized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Base automatically changed from sedemche/ciam-cred-managment-pr1-scaffold to sedemche/ciam-cred-managment-release June 9, 2026 19:36
@swasti29

Copy link
Copy Markdown
Contributor

This PR has had no activity for 1–2 months. Sergei Demchenko (@antrix1989) — if it's no longer relevant, please close it; otherwise please continue working toward getting it merged/closed. Thank you!

import Foundation

/// Error domain for credential management operations.
public let MSALNativeCredentialManagementErrorDomain = "MSALNativeCredentialManagementErrorDomain"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This constant is never used. MSALNativeCredentialManagementError is a plain NSObject conforming to Error, so bridging to NSError yields domain MSALNativeCredManagment.MSALNativeCredentialManagementError, not this string. Either conform to CustomNSError and return this as errorDomain, or drop it so we don't ship a public symbol that doesn't match runtime behavior.

self.credentialID = credentialID
self.aaguid = aaguid
super.init(
id: "",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The public init hardcodes id to an empty string, but MSALCredentialMethodProtocol documents id as the unique identifier. Anything built through this init and passed to deleteCredentialMethod would target an empty id. Take id as a parameter, or make this init internal so only server-hydrated instances exist.

public init(clientId: String) throws
{
super.init()
fatalError("Not implemented — stub only")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This init is declared throws but traps instead. Throw MSALNativeCredentialManagementError(type: .generalError, message: "Not implemented") here so the declared contract holds and the stub can't crash a host app.

correlationId: UUID? = nil
) async -> Result<[any MSALCredentialMethodProtocol], MSALNativeCredentialManagementError>
{
fatalError("Not implemented — stub only")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The Result-returning stubs (here, deleteCredentialMethod, register.passkey, submitChallenge, resendChallenge) already have a failure channel, so fatalError is avoidable. Return .failure(MSALNativeCredentialManagementError(type: .generalError, message: "Not implemented")) instead - anyone integrating against this branch gets an error rather than a crash.

///
/// let result = await client.listCredentialMethods()
/// ```
@objcMembers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@objcMembers doesn't buy anything on this surface: listCredentialMethods, deleteCredentialMethod and register are all non-representable in Objective-C (async, Result, any protocol), and MSALCredentialType is a Swift struct. Only init gets exposed. Either drop the @objc annotations across this module or add explicit completion-block overloads - as written it implies Objective-C support we don't have.

/// - Parameter config: Configuration including token provider and tenant subdomain.
/// - Throws: `MSALNativeCredentialManagementError` if the configuration is invalid
/// (e.g., no token provider or tenant subdomain set).
public init(config: MSALNativeCredentialManagementConfig) throws

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This validation is the only real logic in the PR and it has no coverage - MSALNativeCredManagmentTests only asserts the version string. Please add tests for both throw paths (missing tokenProvider, missing tenantSubdomain) and for the success path.


import Foundation

/// Internal abstract base class for all credential methods.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Doc says Internal abstract base class but the type is public and MSALPasskeyCredentialMethod inherits from it, so it ships as public API. Please fix the wording - the internal-only initializer already prevents external subclassing, but the comment says the opposite of what the declaration does.

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.

3 participants