Gate is a multi-protocol, policy-driven privileged access gateway. It sits between users and upstream databases, APIs, and servers, evaluates OPA/Rego policies, masks sensitive data, and centralizes audit, webhook, and recording workflows in a control plane.
┌─────────────────────────────────┐
│ gate-control │
│ Admin UI + HTTP + gRPC + DB │
│ │
│ Resources Policies Audit │
│ Identities Groups Webhooks │
│ Organizations Recordings │
└──────────────┬──────────────────┘
│ gRPC / Protobuf
sync / audit / │ registration / heartbeat
│
┌──────────────▼──────────────────┐
┌──────────┐ │ gate-connector │ ┌──────────┐
│ Clients │────────▶│ Policy evaluation + proxying │────────▶│ Upstream │
│ psql/curl │◀────────│ PostgreSQL / MySQL / HTTP / SSH │◀────────│ services │
└──────────┘ │ Audit / masking / TLS / metrics │ └──────────┘
└─────────────────────────────────┘
- PostgreSQL, MySQL, HTTP, and SSH proxying.
- Rego v1 policy evaluation at
session,pre_request, andpost_requeststages. - Central management for resources, policies, identities, groups, organizations, scoped API keys, webhooks, access requests, audit logs, and recordings.
- gRPC/Protobuf control-plane contracts with generated Go stubs.
- Embedded admin UI plus HTTP
/api/v1/*compatibility endpoints over the same backend RPC logic. - Dedicated connector health, readiness, and Prometheus metrics endpoints.
- Durable dead-letter storage for async delivery paths and optional session recording storage.
gate-control exposes three surfaces on the same listener:
- Embedded admin UI at
/ - HTTP health and admin endpoints such as
/healthand/api/v1/* - gRPC services
gate.v1.ControlPlaneServiceandgate.v1.ConnectorService
The HTTP admin handlers are thin compatibility adapters over the gRPC services, so the web UI, HTTP clients, and Go RPC clients all share the same business logic and auth rules.
Connector-to-control-plane traffic now uses gRPC/Protobuf for:
- Policy sync
- Audit ingestion
- Connector registration
- Connector heartbeat
- Connector deregistration
Relevant sources:
- Protobuf contracts:
proto/gate/v1/*.proto - Generated Go stubs:
internal/gen/gate/v1 - Shared Go admin client:
internal/controlplaneclient
For the fastest local stack:
docker compose up --buildThis starts:
gate-controlonhttp://localhost:8080gate-connectorPostgreSQL listener onlocalhost:6432- connector health and metrics on
:8081inside the container (not published by default) - control-plane Postgres on
localhost:5433 - sample upstream Postgres on
localhost:5434
The checked-in docker-compose.yml is a local dev setup and currently runs the control plane without an API key. The sample connector config already points at the compose services and loads policies/example.rego for all three policy stages.
Example connection through the connector:
PGPASSWORD=app psql -h localhost -p 6432 -U app -d appdbBoth checked-in config files support environment-variable expansion:
configs/control.yamlconfigs/connector.yaml
Run the binaries directly:
go run ./cmd/gate-control -config configs/control.yaml
go run ./cmd/gate-connector -config configs/connector.yaml- HTTP and gRPC both use Bearer auth.
api_keyin the control-plane config is the system/root key.- Scoped organization API keys support roles such as
readonly,editor,admin, andconnector. - System callers can apply org scope with
X-Org-IDon HTTP requests orx-org-idgRPC metadata. - If
api_keyis empty, the control plane runs unauthenticated. That is useful for local development, not production.
The sample configs in configs/ are the best starting point. The fields below are the ones that matter most when wiring a real deployment.
listen_addr: ":8080"
api_key: "${GATE_API_KEY}"
database:
dsn: "postgres://${GATE_DB_USER}:${GATE_DB_PASSWORD}@${GATE_DB_HOST}:${GATE_DB_PORT}/${GATE_DB_NAME}?sslmode=disable"
max_open_conns: 25
min_conns: 5
migrations_path: "internal/store/migrations"
recording:
dir: ".data/recordings" # optional
delivery:
dead_letter_dir: ".data/control-deadletters" # optional
logging:
level: "info"
format: "json"listen_addr: ":6432"
health_addr: ":8081"
control_plane:
url: "http://localhost:8080"
token: "${GATE_CONTROL_TOKEN}"
sync_interval: "30s"
resources:
- name: "primary-db"
protocol: "postgres"
host: "localhost"
port: 5432
database: "appdb"
policies:
- path: "policies/example.rego"
stage: "session"
- path: "policies/example.rego"
stage: "pre_request"
- path: "policies/example.rego"
stage: "post_request"
tls:
enabled: false # optional
recording:
dir: ".data/recordings" # optional
delivery:
dead_letter_dir: ".data/connector-deadletters" # optional
logging:
level: "info"
format: "json"Gate evaluates Rego policies in three stages:
session: allow or block a connection/session before it is establishedpre_request: allow, block, or rewrite a request/query before forwarding upstreampost_request: allow or transform the upstream response, including masking
Managed policies in the control plane move through draft, dry_run, and active states.
Minimal example:
package formal.v2
import rego.v1
default pre_request := {"action": "allow"}
pre_request := {"action": "block", "reason": "destructive queries are not allowed"} if {
input.query.type == "drop"
}
post_request := {
"action": "mask",
"masks": [
{"column": "email", "strategy": "partial"},
{"column": "ssn", "strategy": "redact"},
],
}Masking strategies include redact, partial, hash, and encrypt.
See policies/example.rego for the sample policy used by the local connector config.
Top-level HTTP admin areas under /api/v1/ include:
resourcespoliciesorganizationsidentitiesgroupsconnectorswebhooksaccess-requestsauditrecordings
The gRPC contracts are defined in:
proto/gate/v1/controlplane.protoproto/gate/v1/connector.proto
Domain messages are split across:
proto/gate/v1/resource_policy.protoproto/gate/v1/identity_group.protoproto/gate/v1/tenant.protoproto/gate/v1/webhook_access.protoproto/gate/v1/audit.protoproto/gate/v1/recording.proto
Prerequisites:
- Go 1.25+
- Docker for local compose and integration tests
golangci-lintv2 formake lint
Common commands:
make build
make test
make test-race
make lint
make generate-proto
make verify-generated
make docker
make test-e2eNotes:
make generate-protoregenerates all Go stubs fromproto/gate/v1/*.proto.make verify-generatedis what CI uses to ensure generated files are up to date.make test-e2ebrings updocker-compose.test.yml, runs integration tests with theintegrationbuild tag, then tears the stack down.
gate/
├── cmd/
│ ├── gate-connector/ # Connector binary entrypoint
│ ├── gate-control/ # Control-plane binary entrypoint
│ └── gate-policy/ # Policy tooling
├── configs/ # Sample runtime configs
├── internal/
│ ├── connector/ # Proxy runtime, routing, TLS, health, metrics
│ ├── controlplane/ # HTTP server, gRPC services, embedded UI bridge
│ ├── controlplaneclient/ # Shared Go admin client for ControlPlaneService
│ ├── enforcement/ # Masking, filtering, rewrite helpers
│ ├── gen/gate/v1/ # Generated protobuf and gRPC stubs
│ ├── policy/ # OPA/Rego policy engine
│ ├── protocol/ # Postgres, MySQL, HTTP, SSH protocol handlers
│ ├── recording/ # Session recording storage/replay primitives
│ ├── store/ # Postgres and in-memory stores + migrations
│ ├── sync/ # Connector policy sync and audit shipping
│ └── webhooks/ # Webhook dispatch and retry/dead-letter handling
├── policies/ # Example local policies
├── proto/gate/v1/ # Protobuf contracts
├── scripts/ # Helper scripts, including protobuf generation
├── Dockerfile # Multi-stage connector/control image build
├── docker-compose.yml # Local dev stack
└── docker-compose.test.yml # Integration test dependencies
Business Source License 1.1. See LICENSE for the current terms.