Skip to content

Conversation

@demolaf
Copy link
Member

@demolaf demolaf commented Nov 28, 2025

Adds a sign() extension method to AuthClient that enables cryptographic signing of data, matching the Node.js Firebase Admin SDK's GoogleAuth.sign() behavior. The implementation automatically uses local signing when service account credentials with private keys are available, falling back to IAM API signing otherwise.

New sign() Extension Method

final credential = GoogleCredential.fromServiceAccount(file);
final client = await createAuthClient(credential, scopes);

// Sign data - automatically uses local signing if available
final signature = await client.sign('data to sign');

// Sign with custom IAM endpoint (e.g., for different universe domains)
final signature = await client.sign('data', endpoint:
'https://iamcredentials.example.com');

Signing behavior:

  • Service account credentials with private key: Signs locally using RSA-SHA256 (fast, no API calls)
  • Impersonated credentials: Uses IAM signBlob API with target principal
  • Other credentials: Uses IAM signBlob API with default service account
  • Custom endpoints: Supports different IAM Credentials API endpoints for universe domain support

Implementation

Expando-based credential association:

  • Uses Expando to associate credentials with AuthClient instances
  • No wrapper classes needed - returns standard AuthClient
  • Credential association is maintained throughout the client lifecycle

Integration with Firebase Admin SDK:

  • firebase_app.dart now uses createAuthClient()
  • Auth clients automatically support sign() operations
  • Local signing enabled by default when service account keys available

Testing

  • ✅ Local signing with service account credentials
  • ✅ IAM API signing fallback
  • ✅ Impersonated credentials support
  • ✅ Custom endpoint support

…nt/projectId handling

Add `_run` helper method to MessagingHttpClient, SecurityRulesHttpClient, and AppCheckHttpClient that accepts both client and projectId as callback parameters. This eliminates redundant `await app.client` calls and centralizes client/projectId retrieval logic.
…PI, local RSA signing, and service account impersonation
@demolaf demolaf marked this pull request as draft November 28, 2025 08:20
@github-actions
Copy link

github-actions bot commented Nov 28, 2025

Coverage Report

✅ Coverage 57.12% meets 40% threshold

Coverage: 57.12%
Lines Covered: 2563/4487

Minimum threshold: 40%

@demolaf demolaf changed the title Feat/sign auth client feat: sign() on AuthClient Nov 28, 2025
@demolaf demolaf marked this pull request as ready for review November 28, 2025 13:41
Base automatically changed from feat/api-tests to next December 2, 2025 14:53
String endpoint,
String email,
) async {
final url = Uri.parse(
Copy link
Member

Choose a reason for hiding this comment

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

Can this technically not use the googleapis identidy provider api?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes and now that you mention it, seems the IAMCredentialsApi supports a different rootUrl, https://pub.dev/documentation/googleapis/latest/iamcredentials_v1/IAMCredentialsApi-class.html which I would refactor _signBlobWithEndpoint to use instead.

Copy link
Member Author

@demolaf demolaf Dec 5, 2025

Choose a reason for hiding this comment

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

so the nullable endpoint here allows projects to specify a different domain other than the default googleapis.com but I can't seem to find comprehensive docs on this except from here and then used like this to override service endpoints e.g. https://iamcredentials.googleapis.com -> https://iamcredentials.custom-universe-domain-here.com.

Also see how it's used in googleauth.ts

@demolaf demolaf merged commit cf734d5 into next Dec 5, 2025
7 checks passed
@demolaf demolaf deleted the feat/sign-auth-client branch December 5, 2025 13:52
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