Skip to content

🔥 feat: add PEM-based TLS support for ListenConfig#4021

Closed
gaby wants to merge 5 commits intomainfrom
update-listen.go-for-pem-data-support
Closed

🔥 feat: add PEM-based TLS support for ListenConfig#4021
gaby wants to merge 5 commits intomainfrom
update-listen.go-for-pem-data-support

Conversation

@gaby
Copy link
Member

@gaby gaby commented Jan 20, 2026

Motivation

  • Allow configuring TLS/mTLS from in-memory PEM data (e.g. secrets or env vars) without writing files.
  • Provide deterministic validation and precedence to avoid ambiguous mixes of PEM and file-based TLS inputs.
  • Enable testing of PEM-based TLS flows and ensure helpers are placed for test readability.

Description

  • Added CertPEM, CertKeyPEM, and CertClientPEM fields to ListenConfig and documented them in docs/api/fiber.md and docs/whats_new.md.
  • Implemented validation and precedence in App.Listen to require matching cert/key pairs, forbid ambiguous mixes of PEM and file inputs, compare file contents with supplied PEM when both are provided, and return clear errors on mismatch.
  • Built server certificates from PEM via tls.X509KeyPair(cfg.CertPEM, cfg.CertKeyPEM) and configured client CA pools from PEM using x509.NewCertPool() + AppendCertsFromPEM to enable mTLS from in-memory data, and attached a TLSHandler to the TLS config.
  • Added unit tests for PEM flows (Test_Listen_TLS_PEM, Test_Listen_TLS_PEM_Validation) and moved the tlsPEM helper and readTLSPEM to the top of listen_test.go for reuse.

Related #4019

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds in-memory PEM-based TLS support to ListenConfig via new CertPEM, CertKeyPEM, and CertClientPEM fields; enforces mutual exclusivity with file-based TLS fields; extends TLS initialization and client-CA handling; and updates docs and tests for PEM usage.

Changes

Cohort / File(s) Summary
TLS PEM Support Implementation
listen.go
Added CertPEM, CertKeyPEM, and CertClientPEM to ListenConfig. Validates mutual exclusivity with file-based fields, rejects mixed/partial configs, loads key pairs from PEM, configures tls.Config/GetCertificate, and wires client CA handling for PEM or file sources.
Test Coverage for PEM Configuration
listen_test.go
Added tlsPEM helper and readTLSPEM(); new tests Test_Listen_TLS_PEM (server cert only, with client CA) and Test_Listen_TLS_PEM_Validation for mismatch/missing-file scenarios; adjusted test data paths to PEM files.
Documentation Updates
docs/api/fiber.md, docs/whats_new.md
Documented PEM-based TLS fields and added example demonstrating supplying CertPEM/CertKeyPEM (e.g., from env vars); referenced PEM-based configuration in ListenConfig usage.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Server as Fiber Listen
  participant TLS as tls.Config / TLSHandler
  participant CertSource as Cert Source (PEM/File/AutoCertManager)

  Client->>Server: Connect (TLS handshake)
  Server->>TLS: Use tls.Config / call GetCertificate
  TLS->>CertSource: Request certificate (PEM/File/Auto/CertManager)
  CertSource-->>TLS: Return certificate (from CertPEM/KeyPEM, CertFile/KeyFile, or AutoCertManager)
  TLS-->>Server: Complete handshake (apply ClientAuth if configured)
  Server-->>Client: Accept connection
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • sixcolors
  • ReneWerner87
  • efectn

Poem

🐰 In memory's burrow certificates sleep,
PEM bytes tucked safe, no paths to keep.
Handshakes hop quick through a secure glen,
Clients and servers curl close again. 🥕🔐

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description is comprehensive, covering motivation, implementation details, and validation approach. However, it does not follow the provided template structure with required sections like 'Changes introduced' checklist items and 'Type of change'. Consider restructuring the description to follow the repository template with explicit checklist items for benchmarks, documentation, changelog, migration guide, and type of change selection to improve clarity and consistency.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding PEM-based TLS support to ListenConfig, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gaby, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the ListenConfig functionality by introducing support for PEM-encoded TLS certificates and keys. This change allows developers to configure TLS and mTLS directly from in-memory data, such as environment variables or secrets, without needing to write certificate files to disk. It also includes robust validation to prevent misconfigurations and ensure secure and predictable behavior, making the TLS setup more flexible and secure for various deployment scenarios.

Highlights

  • PEM-based TLS Support: Introduced new CertPEM, CertKeyPEM, and CertClientPEM fields to ListenConfig, allowing TLS and mTLS to be configured using in-memory PEM-encoded certificate data instead of file paths. This is particularly useful for managing secrets via environment variables or secret management systems.
  • Robust TLS Configuration Validation: Implemented comprehensive validation logic within App.Listen to ensure correct TLS setup. This includes requiring matching certificate and key pairs, preventing ambiguous mixes of PEM and file-based inputs, and comparing file contents with supplied PEM data if both are provided, returning clear errors on mismatch.
  • Enhanced mTLS Capabilities: The system now supports mTLS configuration using CertClientPEM for client CA pools, enabling mutual TLS authentication from in-memory data. The TLS configuration logic has been updated to handle both PEM and file-based client certificates seamlessly.
  • Comprehensive Testing and Documentation: New unit tests (Test_Listen_TLS_PEM, Test_Listen_TLS_PEM_Validation) have been added to cover various PEM-based TLS scenarios and validation rules. The new fields and usage examples are also documented in docs/api/fiber.md and docs/whats_new.md.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ReneWerner87 ReneWerner87 added this to v3 Jan 20, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone Jan 20, 2026
@gaby gaby changed the title feat: add PEM-based TLS support for ListenConfig and tests feat: add PEM-based TLS support for ListenConfig Jan 20, 2026
@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

❌ Patch coverage is 95.16129% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.20%. Comparing base (1b2aa66) to head (5f900de).
⚠️ Report is 12 commits behind head on main.

Files with missing lines Patch % Lines
listen.go 95.16% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4021      +/-   ##
==========================================
- Coverage   91.22%   91.20%   -0.03%     
==========================================
  Files         119      119              
  Lines       11000    11057      +57     
==========================================
+ Hits        10035    10084      +49     
- Misses        610      617       +7     
- Partials      355      356       +1     
Flag Coverage Δ
unittests 91.20% <95.16%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable feature by adding support for PEM-based TLS configuration, allowing TLS setup from in-memory data. The implementation is robust, with thorough validation to handle various configuration scenarios and prevent ambiguity between PEM and file-based inputs. The documentation updates are clear, and the new unit tests provide good coverage for both happy paths and validation logic. I've included a few suggestions to simplify some of the validation logic and refactor a duplicated code block for better maintainability.

@gaby gaby changed the title feat: add PEM-based TLS support for ListenConfig 🔥 feat: add PEM-based TLS support for ListenConfig Jan 20, 2026
@gaby gaby marked this pull request as ready for review January 20, 2026 13:17
@gaby gaby requested a review from a team as a code owner January 20, 2026 13:17
@gaby
Copy link
Member Author

gaby commented Jan 20, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable feature by adding support for PEM-based TLS configuration, which enhances flexibility for secret management. The implementation is robust, featuring comprehensive validation logic and extensive test coverage that addresses numerous edge cases. The documentation has also been updated clearly to reflect these new capabilities.

My review focuses on improving the structure and readability of the new validation logic in listen.go. I've identified a couple of opportunities to refactor for better maintainability by reducing code duplication and simplifying complex conditional logic. My suggestions aim to make the code cleaner and more straightforward.

Copy link
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.

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
listen_test.go (1)

532-573: Add t.Parallel() at the start of each test function to follow guidelines.

Test data files are verified to exist at .github/testdata/. However, both Test_Listen_MutualTLS and Test_Listen_MutualTLS_Prefork are missing t.Parallel() calls at the beginning. Per coding guidelines for **/*_test.go files, each test must invoke t.Parallel() at the start to maximize concurrency.

♻️ Duplicate comments (2)
listen_test.go (1)

25-45: Unused variable declaration on line 33.

The var err error declaration on line 33 is unnecessary. The := on lines 35 and 38 will handle the assignment correctly since certPEM and keyPEM are new variables that require the short declaration form.

🔧 Suggested fix
 func readTLSPEM(t *testing.T, certPath, keyPath string) tlsPEM {
 	t.Helper()
 
-	var err error
-
 	certPEM, err := os.ReadFile(filepath.Clean(certPath))
 	require.NoError(t, err)
 
 	keyPEM, err := os.ReadFile(filepath.Clean(keyPath))
 	require.NoError(t, err)
listen.go (1)

207-229: Unreachable code block at lines 227-229.

After the validation at lines 199-205, either both hasCertPEM and hasCertKeyPEM are true (or both false), and similarly for hasCertFile/hasCertKeyFile. This means:

  • (hasCertPEM || hasCertKeyPEM)hasServerPEM
  • (hasCertFile || hasCertKeyFile)hasServerFile

The condition on line 227 becomes: hasServerPEM && hasServerFile && (!hasServerPEM || !hasServerFile), which is always false when both hasServerPEM and hasServerFile are true.

🔧 Suggested fix: remove unreachable code
 	if hasServerPEM && hasServerFile {
 		certFileBytes, err := os.ReadFile(filepath.Clean(cfg.CertFile))
 		if err != nil {
 			return fmt.Errorf("tls: cannot read certFile=%q to compare with CertPEM: %w", cfg.CertFile, err)
 		}
 
 		if !bytes.Equal(certFileBytes, cfg.CertPEM) {
 			return fmt.Errorf("tls: CertPEM does not match certFile=%q", cfg.CertFile)
 		}
 
 		certKeyFileBytes, err := os.ReadFile(filepath.Clean(cfg.CertKeyFile))
 		if err != nil {
 			return fmt.Errorf("tls: cannot read keyFile=%q to compare with CertKeyPEM: %w", cfg.CertKeyFile, err)
 		}
 
 		if !bytes.Equal(certKeyFileBytes, cfg.CertKeyPEM) {
 			return fmt.Errorf("tls: CertKeyPEM does not match keyFile=%q", cfg.CertKeyFile)
 		}
 	}
-
-	if (hasCertPEM || hasCertKeyPEM) && (hasCertFile || hasCertKeyFile) && (!hasServerPEM || !hasServerFile) {
-		return errors.New("tls: provide either CertPEM/CertKeyPEM or CertFile/CertKeyFile, not a mix")
-	}

@gaby gaby requested review from Copilot and removed request for Copilot January 20, 2026 14:47
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 pull request adds support for configuring TLS/mTLS from in-memory PEM data, allowing applications to use certificates from environment variables or secrets managers without writing files to disk.

Changes:

  • Added three new fields to ListenConfig: CertPEM, CertKeyPEM, and CertClientPEM for PEM-encoded certificate data
  • Implemented comprehensive validation logic to ensure cert/key pairs are complete and to detect/verify when both PEM and file-based inputs are provided
  • Updated TLS configuration logic to support PEM-based certificates with clear precedence (PEM takes priority over files when both are present and match)

Reviewed changes

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

Show a summary per file
File Description
listen.go Added new PEM fields to ListenConfig, implemented validation logic for PEM/file combinations, refactored TLS configuration to support PEM data with proper precedence
listen_test.go Added helper functions (tlsPEM struct, readTLSPEM) at top of file, comprehensive tests for PEM-based TLS flows and validation error paths, updated mTLS tests to use client.pem
docs/api/fiber.md Documented new CertPEM, CertKeyPEM, and CertClientPEM fields in config table, added example for TLS with PEM data
docs/whats_new.md Added example showing PEM-based TLS configuration using environment variables
.github/testdata/client.pem Added new client certificate file for mTLS testing (replaces ca-chain.cert.pem references)

@gaby gaby closed this Jan 21, 2026
@github-project-automation github-project-automation bot moved this to Done in v3 Jan 21, 2026
@ReneWerner87 ReneWerner87 deleted the update-listen.go-for-pem-data-support branch January 27, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants