Skip to content

fix: use loaded public key in oidc service, fixes #860#874

Merged
steveiliop56 merged 1 commit into
mainfrom
fix/oidc-public-key
May 16, 2026
Merged

fix: use loaded public key in oidc service, fixes #860#874
steveiliop56 merged 1 commit into
mainfrom
fix/oidc-public-key

Conversation

@steveiliop56
Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 commented May 16, 2026

Summary by CodeRabbit

  • Refactor
    • Improved internal handling of public key storage and marshaling in OIDC service for token and JWK generation.
    • Minor cleanup of whitespace in authorization parameter validation.

Review Change Stack

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label May 16, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

The OIDCService refactors its public-key handling by storing a concrete *rsa.PublicKey instead of the generic crypto.PublicKey interface. During initialization, the service type-asserts the public key to RSA, and token/JWK generation now reads from this stored RSA key rather than deriving it from the private key.

Changes

RSA Public Key Storage and Usage

Layer / File(s) Summary
Field definition and initialization
internal/service/oidc_service.go
OIDCService.publicKey field type narrows from crypto.PublicKey to *rsa.PublicKey; NewOIDCService type-asserts and stores the loaded or generated public key as the concrete RSA type.
Token and JWK generation
internal/service/oidc_service.go
generateIDToken and GetJWK marshal the public key from service.publicKey instead of deriving it from service.privateKey.PublicKey, ensuring consistent key source.

🎯 2 (Simple) | ⏱️ ~10 minutes


🐰 A key made concrete, no more generic strife,
RSA stored, secure in the OIDC life,
Tokens and JWKs now share the same source bright,
Where once derived keys danced in cryptographic night!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: switching the OIDCService to use a loaded public key instead of deriving it, directly addressing issue #860.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/oidc-public-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/service/oidc_service.go 0.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/service/oidc_service.go (2)

226-239: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject non-RSA or mismatched public keys before constructing the service.

x509.ParsePKIXPublicKey accepts multiple key types (*rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey, *ecdh.PublicKey). The unchecked type assertion publicKey.(*rsa.PublicKey) at line 274 will panic at runtime if the parsed key is not RSA. Additionally, validate that the loaded public key matches the private key—if they differ, the service will advertise a key it cannot use for signing.

Suggested fix
 	} else {
 		block, _ := pem.Decode(fpublicKey)
 		if block == nil {
 			return nil, errors.New("failed to decode public key")
@@
 		default:
 			return nil, fmt.Errorf("unsupported public key type: %s", block.Type)
 		}
 	}
+
+	rsaPublicKey, ok := publicKey.(*rsa.PublicKey)
+	if !ok {
+		return nil, fmt.Errorf("unsupported public key type %T: RSA required", publicKey)
+	}
+	if rsaPublicKey.N.Cmp(privateKey.N) != 0 || rsaPublicKey.E != privateKey.E {
+		return nil, errors.New("public key does not match private key")
+	}
@@
-		publicKey:  publicKey.(*rsa.PublicKey),
+		publicKey:  rsaPublicKey,

Also applies to: 272-275

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/service/oidc_service.go` around lines 226 - 239, The parsed public
key from x509.ParsePKIXPublicKey may not be RSA and the code later does an
unchecked assertion publicKey.(*rsa.PublicKey), so update the parsing branch to
perform a safe type check (type switch or type assertion with ok) and return an
explicit error if the key is not an *rsa.PublicKey; additionally, verify the
loaded public key actually matches the service's private key by comparing the
RSA public components (e.g., compare rsaPub.N and rsaPub.E with
privateKey.PublicKey.N and .E) and return an error if they differ so the service
cannot be constructed with mismatched keys (refer to variables publicKey,
privateKey and the parsing branches that call x509.ParsePKCS1PublicKey /
x509.ParsePKIXPublicKey).

816-831: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Build the JWK from service.publicKey for consistency with the loaded key.

The KeyID is derived from the explicitly loaded service.publicKey, but the JWK is built from service.privateKey.Public(). Since the public key is loaded independently from its own file, these can diverge if keys are rotated or mismatched files are provided. The JWK should be built from the explicitly loaded service.publicKey to ensure the KeyID matches the actual served key.

Suggested fix
 	jwk := jose.JSONWebKey{
-		Key:       service.privateKey,
+		Key:       service.publicKey,
 		Algorithm: string(jose.RS256),
 		Use:       "sig",
 		KeyID:     base64.URLEncoding.EncodeToString(hasher.Sum(nil)),
 	}
 
-	return jwk.Public().MarshalJSON()
+	return jwk.MarshalJSON()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/service/oidc_service.go` around lines 816 - 831, The JWK is being
created from service.privateKey which can diverge from the separately loaded
service.publicKey used to compute KeyID; update the JSONWebKey construction in
the function that marshals the key (the block using x509.MarshalPKCS1PublicKey,
hasher.Write and creating jose.JSONWebKey) to use service.publicKey (the
explicit loaded public key) as the Key field so the JWK contents and the KeyID
derived from der remain consistent; keep Algorithm as RS256 and Use as "sig" and
continue returning jwk.Public().MarshalJSON().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/service/oidc_service.go`:
- Around line 226-239: The parsed public key from x509.ParsePKIXPublicKey may
not be RSA and the code later does an unchecked assertion
publicKey.(*rsa.PublicKey), so update the parsing branch to perform a safe type
check (type switch or type assertion with ok) and return an explicit error if
the key is not an *rsa.PublicKey; additionally, verify the loaded public key
actually matches the service's private key by comparing the RSA public
components (e.g., compare rsaPub.N and rsaPub.E with privateKey.PublicKey.N and
.E) and return an error if they differ so the service cannot be constructed with
mismatched keys (refer to variables publicKey, privateKey and the parsing
branches that call x509.ParsePKCS1PublicKey / x509.ParsePKIXPublicKey).
- Around line 816-831: The JWK is being created from service.privateKey which
can diverge from the separately loaded service.publicKey used to compute KeyID;
update the JSONWebKey construction in the function that marshals the key (the
block using x509.MarshalPKCS1PublicKey, hasher.Write and creating
jose.JSONWebKey) to use service.publicKey (the explicit loaded public key) as
the Key field so the JWK contents and the KeyID derived from der remain
consistent; keep Algorithm as RS256 and Use as "sig" and continue returning
jwk.Public().MarshalJSON().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ac789c9c-942c-4051-a015-a9aa1da80767

📥 Commits

Reviewing files that changed from the base of the PR and between e8071a9 and 5349f21.

📒 Files selected for processing (1)
  • internal/service/oidc_service.go

@steveiliop56 steveiliop56 merged commit 5349f21 into main May 16, 2026
5 checks passed
@steveiliop56 steveiliop56 deleted the fix/oidc-public-key branch May 16, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant