feat: add mTLS client certificate support #232
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/OpenSpec
Kind/Security
Kind/Testing
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
RFC - Request For Comments
Reviewed/Confirmed
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Status/Abandoned
Status/Blocked
Status/Need More Info
hermes-attempted
hermes-needs-clarification
hermes-ready
hermes-review
hermes-wip
human-required
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
agentic-forges/forgejo-mcp!232
Loading…
Reference in a new issue
No description provided.
Delete branch "berzdev/feat/mtls-client-cert-support"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Add -tls-cert / -tls-key flags and FORGEJO_TLS_CERT / FORGEJO_TLS_KEY
env vars to configure a TLS client certificate for Forgejo instances
that require mutual TLS authentication at the network level.
When both cert and key are provided, a custom http.Client with the
client certificate is injected into the Forgejo SDK via SetHTTPClient.
If not set, behaviour is unchanged.
Example:
forgejo-mcp -t stdio -url https://git.example.com
-tls-cert ~/.config/mtls/client.crt.pem
-tls-key ~/.config/mtls/client.key.pem
Or via env vars:
FORGEJO_TLS_CERT=
/.config/mtls/client.crt.pem/.config/mtls/client.key.pemFORGEJO_TLS_KEY=
forgejo-mcp -t stdio -url https://git.example.com
op1st Pipelines as Code is skipping this commit.
User berzdev is not allowed to trigger CI via pull_request in this repo.
/ok-to-test
op1st Pipelines as Code/forgejo-mcp-on-pull-request-6ntwt is running.
Starting Pipelinerun forgejo-mcp-on-pull-request-6ntwt in namespace op1st-pipelines
You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:
tkn pr logs -n op1st-pipelines forgejo-mcp-on-pull-request-6ntwt -fop1st Pipelines as Code/forgejo-mcp-code-scans- has failed.
There was an error creating the PipelineRun: forgejo-mcp-code-scans-
cannot use the API on the provider platform to create a in_progress status:
op1st Pipelines as Code/forgejo-mcp-on-pull-request-6ntwt has successfully validated your commit.
Task Statuses:
fetch-source
build-and-test
commit-title-check
@berzdev — thanks for the contribution! Could you have a look at the inline review comments left above? Three issues were flagged in
pkg/forgejo/forgejo.go:--tls-cert/--tls-keyis set,mtlsClient()returnsnilwithout logging anything, so mTLS is silently skipped.LoadX509KeyPairfailure logs an error but returnsnil, causing the client to connect without mTLS. Should be a hard failure.http.Transport(line 26): constructing a fresh transport instead of cloninghttp.DefaultTransportdrops proxy support (HTTP_PROXY/HTTPS_PROXY), connection-pool timeouts, andhttp.Client.Timeout.Happy to discuss the suggested fixes in the review thread!
Thanks for the contribution, @berzdev! While reviewing the PR, we wanted to bring up a few architectural design points for discussion to see if they might be relevant for your use case or if we should consider adding them to future-proof the implementation:
Custom Root CA Support (e.g.,
-tls-ca/FORGEJO_TLS_CA):In many private or enterprise environments where mTLS is used, the Forgejo instance might run on a private/internal Certificate Authority (CA) rather than a public one. If the system running
forgejo-mcpdoes not trust that private CA, the TLS handshake will fail. Would it be useful to add an optional way to specify a custom server CA certificate to trust? This would avoid having users bypass server verification entirely (e.g. via insecure flags).Zero-Downtime Certificate Rotation:
Since
forgejo-mcpcan run as a long-lived process (like in SSE mode), certificates loaded at startup might eventually expire. In environments where certs are rotated dynamically on disk (like Kubernetes secrets or Vault volume mounts), we could use Go'sGetClientCertificatecallback intls.Configinstead of a one-timetls.LoadX509KeyPair. This allows reloading rotated certs on the fly without restarting the process. Is this something your deployment environment would benefit from?Cloud-Native PEM Input (Inline Certificate Data):
In containerized/serverless environments (like AWS Fargate or Google Cloud Run), mounting files to disk can be tricky. It is often easier to pass the PEM-encoded certificate/key contents directly in environment variables (e.g.,
FORGEJO_TLS_CERT_DATA). We could potentially support both file paths and raw PEM strings for greater flexibility.Let us know what you think and what your deployment target looks like!
op1st Pipelines as Code/forgejo-mcp-code-scans-rnghp is running.
Starting Pipelinerun forgejo-mcp-code-scans-rnghp in namespace op1st-pipelines
You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:
tkn pr logs -n op1st-pipelines forgejo-mcp-code-scans-rnghp -fop1st Pipelines as Code/forgejo-mcp-on-pull-request-gnhhs is running.
Starting Pipelinerun forgejo-mcp-on-pull-request-gnhhs in namespace op1st-pipelines
You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:
tkn pr logs -n op1st-pipelines forgejo-mcp-on-pull-request-gnhhs -fop1st Pipelines as Code/forgejo-mcp-code-scans-rnghp has successfully validated your commit.
Task Statuses:
fetch-source
gitleaks-version
gitleaks
op1st Pipelines as Code/forgejo-mcp-on-pull-request-gnhhs has successfully validated your commit.
Task Statuses:
fetch-source
build-and-test
commit-title-check
op1st Pipelines as Code/forgejo-mcp-code-scans-pcknq is running.
Starting Pipelinerun forgejo-mcp-code-scans-pcknq in namespace op1st-pipelines
You can monitor the execution using the op1st Pipelines as Code PipelineRun viewer or through the command line by
using the tkn CLI with the following command:
tkn pr logs -n op1st-pipelines forgejo-mcp-code-scans-pcknq -fop1st Pipelines as Code/forgejo-mcp-on-pull-request- has failed.
There was an error creating the PipelineRun: forgejo-mcp-on-pull-request-
cannot use the API on the provider platform to create a in_progress status:
op1st Pipelines as Code/forgejo-mcp-code-scans-pcknq has successfully validated your commit.
Task Statuses:
fetch-source
gitleaks-version
gitleaks
Thanks for the thorough review! I've pushed two follow-up commits addressing all three bugs and adding the custom CA support:
Bug fixes (commit
25fa43a):Custom Root CA (commit
952d866, addressing @byteflavour's point 1):Added -tls-ca / FORGEJO_TLS_CA for specifying a custom CA certificate bundle. Works standalone (server cert verification only) or combined with -tls-cert/-tls-key for full mutual TLS:
mTLS + private CA
forgejo-mcp -t stdio -url https://git.example.com
-tls-cert ~/.config/mtls/client.crt.pem
-tls-key ~/.config/mtls/client.key.pem
-tls-ca ~/.config/mtls/internal-ca.crt.pem
private CA only (no client cert)
FORGEJO_TLS_CA=/etc/ssl/internstdio -urlhttps://git.example.com
On @byteflavour's remaining po
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.