Skip to content

Fix PEM line ending normalization for JWT OAuth2 private key, TLS certs and keys#1673

Open
Copilot wants to merge 7 commits into
mainfrom
copilot/fix-jwt-oauth2-private-key
Open

Fix PEM line ending normalization for JWT OAuth2 private key, TLS certs and keys#1673
Copilot wants to merge 7 commits into
mainfrom
copilot/fix-jwt-oauth2-private-key

Conversation

Copilot AI commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

JWT OAuth2 authentication fails when the private key contains escaped CRLF sequences (\r\n literal chars), common in Google Service Account JSON files and Windows-generated keys. The previous code only replaced escaped \n with actual newlines, leaving literal \r characters that corrupt the PEM header, causing pem.Decode() to return nil and subsequent parsing to fail.

The same issue applies to TLS client certificates, TLS client keys, and TLS CA certificates, which are also PEM-encoded and may be stored with the same line-ending variants.

Changes

  • pkg/models/pem.go: Added normalizePEMContent() to the models package. It handles all common line-ending formats in priority order:

    1. Escaped CRLF (\r\n literal) → LF
    2. Escaped LF (\n literal) → LF
    3. Escaped standalone CR (\r literal) → strip
    4. Actual CRLF → LF
    5. Actual standalone CR → strip
  • pkg/models/settings.go: Applied normalizePEMContent() in LoadSettings at the point each PEM field is read from DecryptedSecureJSONDataoauth2JWTPrivateKey, tlsCACert, tlsClientCert, and tlsClientKey. Normalization now happens once at config-parse time rather than in each runtime consumer.

  • pkg/models/pem_test.go: Unit tests covering all line-ending variants, plus PEM-parseability tests that verify the normalized output is accepted by pem.Decode() and x509.ParsePKCS1PrivateKey() for each input format.

Copilot AI changed the title [WIP] Fix JWT Oauth2 setup issue with private key format Fix JWT OAuth2: normalize private key line endings before PEM parsing Apr 29, 2026
Copilot AI requested a review from yesoreyeram April 29, 2026 08:34
@github-actions

github-actions Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

TruffleHog Scan Results

Summary: Found 1 potential secrets (0 verified, 1 unverified)

  • Possible secret (PrivateKey) at pkg/httpclient/normalize_test.go:13----***---

Review: Check if unverified secrets are false positives.


Ignoring False Positives:
To mark a false positive, add # trufflehog:ignore as an inline comment on the same line as the detected secret:

my_fake_secret = "AKIAIOSFODNN7EXAMPLE"  # trufflehog:ignore

This works for files that support line numbers (most source files). After adding the comment, push your changes and the scan will re-run.

@yesoreyeram

Copy link
Copy Markdown
Contributor

@copilot - Address the review comment. Also add required changeset files.

Copilot AI commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot - Address the review comment. Also add required changeset files.

Added the changeset file in commit aab8ac6. The previous code review feedback about replacement ordering was already addressed in commit 488b977 (combined sequences like \r\n are now processed before standalone \r).

@yesoreyeram

Copy link
Copy Markdown
Contributor

@copilot - Identify and apply the fix in other places if applicable. (example: TLS certs and keys)

Copilot AI commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot - Identify and apply the fix in other places if applicable. (example: TLS certs and keys)

Done in commit fdd224b. Renamed normalizePrivateKeynormalizePEMContent and applied it to all three TLS PEM fields in tls.go: TLSClientCert, TLSClientKey, and TLSCACert.

Copilot AI changed the title Fix JWT OAuth2: normalize private key line endings before PEM parsing Fix PEM line ending normalization for JWT OAuth2 private key, TLS certs and keys Apr 29, 2026
@yesoreyeram

Copy link
Copy Markdown
Contributor

@copilot - sanitise these while parsing the settings/config rather at runtime / consumers.

Copilot AI commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot - sanitise these while parsing the settings/config rather at runtime / consumers.

Done in commit 74df464. Moved normalizePEMContent to pkg/models/pem.go and applied it directly in LoadSettings when each PEM field is read from DecryptedSecureJSONData (oauth2JWTPrivateKey, tlsCACert, tlsClientCert, tlsClientKey). The consumers (httpclient.go, tls.go) now receive already-normalized values and no longer call the function themselves.

@yesoreyeram yesoreyeram marked this pull request as ready for review June 17, 2026 04:56
@yesoreyeram yesoreyeram requested a review from a team as a code owner June 17, 2026 04:56
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.

[Bug] Unable to set up JWT Oauth2 as Private Key format not recognised

2 participants