diff --git a/cmd/ate-setup/commands.md b/cmd/ate-setup/commands.md index 62ddeb12f1..fdc2eeff6d 100644 --- a/cmd/ate-setup/commands.md +++ b/cmd/ate-setup/commands.md @@ -29,7 +29,7 @@ every setting with its environment variable. | `--ingress-allowed-spiffe-ids IDS` | Comma-separated SPIFFE IDs (exact match) of the clients the ingress router lets reach actors; any listed client may reach any actor. Unset, no client may reach actors through the router. Both dataplanes require a Pod Identity CA client certificate on HTTPS and TLS CONNECT. The SPIFFE URI SAN allowlist may be checked during or after TLS, including after CONNECT acceptance, but unlisted clients must be denied before actor routing. The podidentity signer issues `spiffe://cluster.local/ns//sa/`. `ATE_INGRESS_ALLOWED_SPIFFE_IDS` when the flag is absent | | `--egress-gateway-extra-spiffe-ids IDS` | Comma-separated SPIFFE IDs that hold ate-api-server's `egress_gateway` role next to atenet-egress, such as a credential provider that mints actor JWTs. ate-setup passes atenet-egress's ID and then each listed ID as repeated `--egress-gateway-spiffe-id` flags; unset passes none, leaving ate-api-server's default. `ATE_EGRESS_GATEWAY_EXTRA_SPIFFE_IDS` when the flag is absent | | `--experimental-additional-egress-extproc-service NS/SVC:PORT` | External processor authorization filter | -| `--credential-provider JSON` | Required by `deploy ate-system` and `deploy atenet`. A JSON object: `{"name":"k8s.io"}` deploys and uses the bundled Kubernetes Secrets provider, with a NetworkPolicy that admits only the egress gateway; `{"enabled":false}` turns egress credential injection off; `{"name":"","address":":"}` uses a provider you deploy yourself. See [`docs/guides/egress-credential-injection.md`](../../docs/guides/egress-credential-injection.md). `ATE_CREDENTIAL_PROVIDER` when the flag is absent | +| `--credential-provider JSON` | Required by `deploy ate-system` and `deploy atenet`. A JSON object: `{"name":"k8s.io"}` deploys and uses the bundled Kubernetes Secrets provider, with a NetworkPolicy that admits only the egress gateway; `{"enabled":false}` turns egress credential injection off; `{"name":"","address":":"}` uses a provider you deploy yourself. A JSON array of provider objects selects several, each serving the `ate-secret://` URIs its name is the host of. See [`docs/guides/egress-credential-injection.md`](../../docs/guides/egress-credential-injection.md). `ATE_CREDENTIAL_PROVIDER` when the flag is absent | | `--ateapi-log-level LEVEL` | ate-api-server log level: `debug`, `info`, `warn`, or `error`. Written to the `ate-api-config` ConfigMap on every deploy when set; unset keeps the installed level (`info` on a new install). The server picks up a change without restarting. `ATE_API_LOG_LEVEL` when the flag is absent | | `--otlp-endpoint URL` | Send control plane telemetry to `URL` instead of the cluster default (see [`benchmarking/telemetry/README.md`](../../benchmarking/telemetry/README.md)). `ATE_OTLP_ENDPOINT` when the flag is absent | | `--preview GATES` | Preview gates passed as `--preview` to every substrate component: comma-separated gate names, or `ALL` for all. `ATE_PREVIEW` or `config.preview` when the flag is absent. An explicit `--preview=''` turns them all off, even when `ATE_PREVIEW` is set | diff --git a/cmd/atenet/internal/router/egress/provider.go b/cmd/atenet/internal/router/egress/provider.go index 252e3ec237..b44dfff1b2 100644 --- a/cmd/atenet/internal/router/egress/provider.go +++ b/cmd/atenet/internal/router/egress/provider.go @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file connects the egress gateway to the credential provider it resolves -// egress credential injections through: dialing it, reducing the configured -// provider prefix to the provider name the handler enforces, and the small +// This file connects the egress gateway to the credential providers it resolves +// egress credential injections through: dialing them, validating the configured +// provider names the handler routes on, and the small // validators the injection path shares. The gateway's atenet router wires // DialProvider and ProviderName in when it builds the egress handler (see // cmd/atenet/internal/router). @@ -97,7 +97,7 @@ func ProviderName(name string) (string, error) { // providerNameFromURI returns the provider name of a ate-secret:// URI — // the URI host, e.g. "k8s.io" in // ate-secret://k8s.io/default///. The gateway reads only the host, -// to confirm a URI targets the provider it is configured to serve. +// to pick the provider a URI targets. func providerNameFromURI(raw string) (string, error) { u, err := url.Parse(raw) if err != nil { diff --git a/docs/guides/egress-credential-injection.md b/docs/guides/egress-credential-injection.md index 610cc58171..0cf8e40397 100644 --- a/docs/guides/egress-credential-injection.md +++ b/docs/guides/egress-credential-injection.md @@ -197,12 +197,13 @@ go run ./cmd/ate-setup deploy atenet --credential-provider='{"name":"k8s.io"}' ``` `--credential-provider` (or `ATE_CREDENTIAL_PROVIDER` when the flag is -absent) is a JSON object with these keys; any other key is an error: +absent) is a JSON object with these keys, or a JSON array of such objects to +select several providers; any other key is an error: | Key | Value | |---|---| -| `enabled` | Defaults to `true`. `false` turns injection off, and then no other key is allowed | -| `name` | Required unless `enabled` is `false`. A DNS name: `k8s.io` for the bundled Kubernetes Secrets provider, or the name of a provider you deploy, which is the host of the `ate-secret://` URIs it serves, e.g. `vault.example.com` for `ate-secret://vault.example.com/...`. A policy URI naming any other provider fails closed | +| `enabled` | Defaults to `true`. `false` turns injection off, and then no other key is allowed. An array entry can't be `false` | +| `name` | Required unless `enabled` is `false`. A DNS name: `k8s.io` for the bundled Kubernetes Secrets provider, or the name of a provider you deploy, which is the host of the `ate-secret://` URIs it serves, e.g. `vault.example.com` for `ate-secret://vault.example.com/...`. Names in an array must differ. A policy URI naming no configured provider fails closed | | `address` | The `host:port` the gateway dials the provider at. Required for a provider you deploy; optional with `k8s.io`, where it defaults to the bundled provider's Service, `k8s-credential-provider.ate-system.svc:50051` | For example: @@ -211,9 +212,10 @@ For example: --credential-provider='{"name":"k8s.io"}' --credential-provider='{"enabled":false}' --credential-provider='{"name":"vault.example.com","address":"vault-provider.ate-system.svc:50051"}' +--credential-provider='[{"name":"k8s.io"},{"name":"vault.example.com","address":"vault-provider.ate-system.svc:50051"}]' ``` -**2. The provider.** With `k8s.io` the install deploys the Kubernetes Secrets +**2. The provider.** With `k8s.io` among the providers, the install deploys the Kubernetes Secrets provider itself, from `manifests/egress-credential-injection/`, and waits for it alongside the gateway. The install applies: @@ -230,7 +232,7 @@ it alongside the gateway. The install applies: V2, which `tools/setup-gcp` turns on by default. Elsewhere the provider's check of the gateway's client certificate is the only restriction. -Selecting any other provider, or `{"enabled":false}`, removes a bundled +A selection without `k8s.io`, including `{"enabled":false}`, removes a bundled provider an earlier install left behind, NetworkPolicy included. A provider of your own is yours to deploy, and until something serves the configured address every matching injection rule fails closed with 503. @@ -320,12 +322,12 @@ Manager, or any other secret store — implement the API under your own provider class (the URI host, e.g. `ate-secret://vault.example.com/...`), then have a cluster admin point the gateway at it with `--credential-provider='{"name":"vault.example.com","address":":"}'`. -A gateway currently fronts **one** provider: -a policy URI naming any other class fails closed rather than being sent to the -wrong provider. +A gateway can front several providers, one per class. It sends each URI to the +provider its host names, and a policy URI naming no configured class fails +closed rather than being sent to the wrong provider. -The gateway reads only the URI host, to confirm the URI targets the provider it -serves. Everything after the host is the provider's to interpret. +The gateway reads only the URI host, to pick the provider the URI targets. +Everything after the host is the provider's to interpret. [credprovider-gcp-secret-manager](https://github.com/agent-substrate-plugins/credprovider-gcp-secret-manager) is such a provider for Google Cloud Secret Manager. diff --git a/manifests/ate-install/atenet-egress.yaml b/manifests/ate-install/atenet-egress.yaml index 88a0945fd6..af19b0890c 100644 --- a/manifests/ate-install/atenet-egress.yaml +++ b/manifests/ate-install/atenet-egress.yaml @@ -1393,7 +1393,7 @@ spec: # "Envoy already exited", and reports a drain it never performed. - --envoy-admin-address=127.0.0.1:15000 # Egress credential-injection flags. The installer replaces this marker - # with the --credential-provider-* flags for the provider that the + # with the --credential-provider-* flags for the providers that the # installer's --credential-provider selects, or removes it when that is # {"enabled":false}. Without a provider, a request matching a rule that # requires an injection is denied (see egress.applyEffects).