Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions content/docs/deploy/k8s/ingress.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ The remaining annotations are specific to or behave differently than they do whe

| Annotation | Description |
| --- | --- |
| `ingress.pomerium.io/h2c_upstream` | When set to `"true"`, use cleartext HTTP/2 (`h2c`) when connecting to the upstream endpoint. See the [example below](#http2-cleartext-upstreams) for more information. Cannot be combined with `secure_upstream`. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Incomplete incompatibility list

The annotation reference says h2c_upstream cannot be combined only with secure_upstream, while the detailed section also lists ssh_upstream, tcp_upstream, and udp_upstream. Someone relying on the table can therefore configure a combination that the documented controller behavior rejects instead of creating the route.

This red test demonstrates the incomplete table entry:

import assert from 'node:assert/strict';
import fs from 'node:fs';
import test from 'node:test';

test('h2c annotation row lists every incompatible upstream mode', () => {
  const markdown = fs.readFileSync('content/docs/deploy/k8s/ingress.md', 'utf8');
  const row = markdown
    .split('\n')
    .find((line) => line.startsWith('| `ingress.pomerium.io/h2c_upstream`'));

  for (const annotation of [
    'secure_upstream',
    'ssh_upstream',
    'tcp_upstream',
    'udp_upstream',
  ]) {
    assert.match(row, new RegExp(`\\`${annotation}\\``));
  }
});

It fails on the current row at the ssh_upstream assertion, while the detailed section establishes that all four annotations are incompatible.

Suggested change
| `ingress.pomerium.io/h2c_upstream` | When set to `"true"`, use cleartext HTTP/2 (`h2c`) when connecting to the upstream endpoint. See the [example below](#http2-cleartext-upstreams) for more information. Cannot be combined with `secure_upstream`. |
| `ingress.pomerium.io/h2c_upstream` | When set to `"true"`, use cleartext HTTP/2 (`h2c`) when connecting to the upstream endpoint. See the [example below](#http2-cleartext-upstreams) for more information. Cannot be combined with `secure_upstream`, `ssh_upstream`, `tcp_upstream`, or `udp_upstream`. |

Fix in Claude Code Fix in Codex

| `ingress.pomerium.io/kubernetes_service_account_token_secret` | Name of a Kubernetes Secret containing a [Kubernetes Service Account Token](/docs/reference/routes/kubernetes-service-account-token) in a `token` key. |
| `ingress.pomerium.io/name` | Sets a human-readable name for the route. See [Route Naming](#route-naming) below. |
| `ingress.pomerium.io/mcp_client` | When set to `"true"`, configures the route as an MCP (Model Context Protocol) client. The URL is defined by the service backend. |
Expand Down Expand Up @@ -517,6 +518,18 @@ Additional TLS certificates may be supplied by creating a Kubernetes secret(s) i

Please note that the referenced `tls_client_secret` must be a [TLS Kubernetes secret](https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets). `tls_custom_ca_secret` and `tls_downstream_client_ca_secret` referenced Secrets must contain `ca.crt` key containing a .PEM encoded (base64-encoded DER format) public certificate.

### HTTP/2 Cleartext Upstreams

By default, Pomerium connects to upstream endpoints using HTTP/1.1. Some upstream services, such as insecure gRPC servers, require HTTP/2 without TLS (known as [HTTP/2 cleartext](/docs/reference/routes/to#http2-cleartext), or `h2c`).

Annotate your Ingress with

```yaml
ingress.pomerium.io/h2c_upstream: 'true'
```

The `h2c_upstream` annotation cannot be combined with `secure_upstream`, `ssh_upstream`, `tcp_upstream`, or `udp_upstream`. Setting more than one of these results in an error reported in the Ingress events.

### External Services

You may refer to external services by defining a [Service](https://kubernetes.io/docs/concepts/services-networking/service/) with `externalName`.
Expand Down
Loading