Skip to content

Commit a9a46fb

Browse files
brunoborgesCopilot
andauthored
docs: document self-signed certificate / internal CA handling for GitHub Enterprise (#1050)
Adds an advanced-usage section explaining the 'self signed certificate in certificate chain' error seen on GitHub Enterprise Server and behind TLS-inspecting proxies. Recommends the secure fix of trusting the internal CA via NODE_EXTRA_CA_CERTS (or the OS trust store on self-hosted runners), with a GitHub Enterprise callout, and warns against disabling TLS verification since the JDK download has no checksum fallback. Refs #640 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5431e71 commit a9a46fb

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

docs/advanced-usage.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- [Hosted Tool Cache](#Hosted-Tool-Cache)
2323
- [Modifying Maven Toolchains](#Modifying-Maven-Toolchains)
2424
- [Java-version file](#Java-version-file)
25+
- [Self-signed certificates and internal CAs (GitHub Enterprise)](#Self-signed-certificates-and-internal-CAs-GitHub-Enterprise)
2526

2627
See [action.yml](../action.yml) for more details on task inputs.
2728

@@ -660,3 +661,56 @@ If the file contains multiple versions, only the first one will be recognized.
660661
661662
***NOTE***:
662663
For the tool-version file, ensure that you use standard semantic versioning (semver) formats, as non-standard formats (such as jetbrains-21b212.1) may not be parsed correctly. Additionally, for complex version strings containing multiple version-like segments (for example, java semeru-openj9-11.0.15+10_openj9-0.32.0), the extraction logic may incorrectly capture the last segment (0.32.0) instead of the main version (11.0.15+10).
664+
665+
## Self-signed certificates and internal CAs (GitHub Enterprise)
666+
667+
When `setup-java` dynamically downloads a JDK, it makes HTTPS requests both to fetch the available version metadata and to download the JDK archive. If your runners sit behind a **TLS-inspecting corporate proxy**, or you are on **GitHub Enterprise Server (GHES)** with an internal certificate authority, those requests can fail with an error such as:
668+
669+
```
670+
Error: self signed certificate in certificate chain
671+
```
672+
673+
This happens because the certificate presented to the runner is signed by an **internal or self-signed CA** that is not part of the runner's default trust store. The download itself is fine — the runner simply cannot verify the certificate chain.
674+
675+
### Recommended fix: trust your internal CA
676+
677+
The secure way to resolve this is to make the runner trust your organization's CA, which keeps TLS verification fully enabled. `setup-java` runs on Node.js, which honors the [`NODE_EXTRA_CA_CERTS`](https://nodejs.org/api/cli.html#node_extra_ca_certsfile) environment variable. Point it at your CA bundle (in PEM format) **before** the `actions/setup-java` step:
678+
679+
```yaml
680+
steps:
681+
# The CA bundle is already present on the runner image in this example.
682+
# Alternatively, write it from a secret in a previous step.
683+
- name: Trust the internal CA
684+
run: echo "NODE_EXTRA_CA_CERTS=/etc/ssl/certs/internal-ca.pem" >> "$GITHUB_ENV"
685+
686+
- uses: actions/setup-java@v5
687+
with:
688+
distribution: 'temurin'
689+
java-version: '21'
690+
```
691+
692+
If you keep the certificate in a secret rather than on the runner image, write it to disk first:
693+
694+
```yaml
695+
steps:
696+
- name: Write and trust the internal CA
697+
run: |
698+
echo "${{ secrets.INTERNAL_CA_PEM }}" > "${RUNNER_TEMP}/internal-ca.pem"
699+
echo "NODE_EXTRA_CA_CERTS=${RUNNER_TEMP}/internal-ca.pem" >> "$GITHUB_ENV"
700+
701+
- uses: actions/setup-java@v5
702+
with:
703+
distribution: 'temurin'
704+
java-version: '21'
705+
```
706+
707+
For **self-hosted runners**, you can instead install your CA into the operating system's trust store (for example, `update-ca-certificates` on Debian/Ubuntu or `update-ca-trust` on RHEL). This makes the certificate trusted for all tooling on the runner, not just `setup-java`.
708+
709+
### GitHub Enterprise customers
710+
711+
On **GitHub Enterprise Server**, traffic from your runners frequently passes through an organization-managed proxy or terminates TLS at an appliance using a certificate from an internal CA. If your workflows hit the error above, set `NODE_EXTRA_CA_CERTS` to your enterprise CA bundle (or bake the CA into your self-hosted runner image) as shown above. Coordinate with your platform team to obtain the correct PEM bundle for your appliance and proxy chain.
712+
713+
### Security warning: do not disable certificate verification
714+
715+
Do **not** work around this error by disabling TLS verification (for example, by setting `NODE_TLS_REJECT_UNAUTHORIZED=0`). `setup-java` does not verify a pinned checksum or signature of the downloaded archive, so **TLS is effectively the only integrity guarantee** on the JDK download. Disabling verification would expose your workflow to a man-in-the-middle attacker who could serve a tampered JDK — which then becomes the `java` used by the rest of your pipeline, with access to your secrets and credentials. Always extend trust to your CA instead of turning verification off.
716+

0 commit comments

Comments
 (0)