Skip to content
Docs / dflux EdgeGuard
ContactGet started

Securing the admin API

The admin API is the EdgeControl gRPC control surface for the proxy (admin.grpc_listen). Anything that touches policy, transformation rules, routing, or producers goes through it. This guide covers locking it down with TLS, username/password login, API keys, JWT bearer auth, and mTLS, plus the v1 default-action semantics you should understand before deploying.

Threat model

The admin API can:

  • Mutate any policy rule, rate-limit rule, transformation rule, or routing rule.
  • Drain or restore producers.
  • Change the log level (including trace, which leaks request bodies).

An attacker with admin API access can bypass every gate the proxy enforces. Treat the admin port the same way you'd treat a root shell on the host.

Defaults to understand

default_action: deny

The v1 default for admin.default_action is deny (fail-closed). This value seeds the policy store that gates proxied SBI traffic, so a fresh install with no policy rules denies every request on the SBI listener. Flip to allow only when you understand the implications — typically a lab or bring-up environment. The live value is mutable without a restart:

Bash

Admin listener is off until you set grpc_listen

admin.grpc_listen has no implicit default — empty leaves the admin surface down. The shipped examples set 127.0.0.1:9091 so a loopback install matches the d3x-edgectl -addr default (the SBI listener is separate, on :8090). To expose the admin port off-host, change the listen address and turn on TLS + auth at the same time. examples/edge-full.yaml uses 127.0.0.1:8091 — pass -addr 127.0.0.1:8091 if you follow that file.

allow_insecure

The admin listener requires TLS by default. Setting admin.allow_insecure: true opts into cleartext gRPC — fine for local development on loopback, but exposes bearer tokens and API keys on the wire over any shared network. Production should configure admin.tls and remove this flag.

The example configs ship allow_insecure: true
examples/edge-minimal.yaml and examples/edge-full.yaml set allow_insecure: true so the shipped example config runs out of the box. Flip it and configure admin.tls before deploying anywhere outside loopback.

allow_anonymous

The proxy refuses to start unless admin.auth is populated or admin.allow_anonymous: true is set. This catches the misconfiguration where someone forgets to configure auth on a publicly-exposed admin port. examples/edge-minimal.yaml satisfies the gate by populating admin.auth.users (see username/password login below); examples/edge-full.yaml ships no credentials and sets allow_anonymous: true so it runs out of the box — turn that off and populate admin.auth for any real deployment.

Username/password login

The default mechanism the shipped configs use: an operator roster under admin.auth.users, each entry pairing a username, a bcrypt password_hash, and an RBAC role (admin, operator, or viewer). The EdgeControl Login RPC exchanges those credentials for a short-lived HMAC JWT. d3x-edgectl has no login subcommand — pass the token with -token, or prefer an API key for the CLI.

YAML

The shipped examples/edge-minimal.yaml uses admin / admin. Replace the hash before deploying. Login issues an HMAC JWT signed with jwt_secret carrying the role claim, which EdgeControl then validates on each authenticated RPC.

Bash
login_token_ttl requires jwt_secret
An empty users list disables the Login RPC; the API-key and bearer-token paths are unaffected. Issuing login tokens requires admin.auth.jwt_secret to be set. When login_token_ttl is unset, the TTL is 1 hour.

API keys

The simplest gate for d3x-edgectl: a static API key, sent as gRPC metadata (-key / D3X_EDGE_ADMIN_KEY). It always maps to the admin role.

YAML

Use the _file: variant in production so the key doesn't appear in your config repo. Set strong random keys (32+ bytes), rotate periodically, and gate file access on a small operator group.

d3x-edgectl picks the key up from the D3X_EDGE_ADMIN_KEY environment variable or the -key flag.

Bash

JWT bearer auth

For environments where the admin client is itself authenticated (CI, SSO, an operator portal), accept JWT bearer tokens minted by your issuer. The proxy validates either against an HMAC secret or an asymmetric public key.

YAML

The proxy enforces the signature and expiry, then reads the role claim (admin, operator, or viewer) and rejects any unknown role. Map your SSO identities to that claim in the issuer that mints these tokens.

TLS on the admin listener

Configure server-side TLS:

YAML

The proxy serves the EdgeControl gRPC API over TLS. ca_file is required only when require_client_cert: true.

mTLS

For the strongest gate, require client certificates. Combined with TLS, mTLS makes the admin listener reachable only from clients that hold a cert signed by your CA.

YAML

Pair mTLS with one of the auth modes above so the listener both verifies the client's certificate and resolves an RBAC role for each request.

Pre-prod checklist

  • admin.default_action is deny unless you've consciously chosen otherwise.
  • admin.allow_insecure is false.
  • admin.allow_anonymous is false.
  • One of admin.auth.users, admin.auth.api_key_file, or admin.auth.jwt_* is configured.
  • The dev admin / admin password hash has been replaced.
  • admin.tls is configured.
  • Admin listen address is reachable only by operators — firewall, ACLs, or service-mesh policy.