gatekeeper

package module
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: MIT Imports: 20 Imported by: 0

README

Gatekeeper

A credential-injecting TLS-intercepting proxy. Route HTTPS traffic through Gatekeeper and it transparently injects authentication headers based on hostname matching. Clients never see raw credentials.

# Start the proxy
gatekeeper --config gatekeeper.yaml

# In another terminal — credential injected automatically
curl --proxy http://127.0.0.1:9080 --cacert ca.crt https://api.github.com/user

No GITHUB_TOKEN in the command. No secrets in environment variables. The token is resolved from the configured source and injected at the network layer.

Installation

go install github.com/majorcontext/gatekeeper/cmd/gatekeeper@latest

Requires: Go 1.25+

How it works

  1. Client sends CONNECT host:443 through the proxy
  2. Proxy terminates TLS using a dynamically-generated certificate for that host
  3. Proxy reads the plaintext request, injects the matching credential as an HTTP header
  4. Request is forwarded to the real server over a separate TLS connection
  5. Response streams back to the client

The proxy needs a CA certificate to sign per-host certificates. Generate one with the included script:

cd examples && ./gen-ca.sh

Configuration

proxy:
  host: 127.0.0.1
  port: 9080

tls:
  ca_cert: ca.crt
  ca_key: ca.key

credentials:
  - host: api.github.com
    header: Authorization
    grant: github
    source:
      type: env
      var: GITHUB_TOKEN

network:
  policy: permissive

log:
  level: info
  format: text

Credential sources

Environment variable
source:
  type: env
  var: GITHUB_TOKEN
Static value
source:
  type: static
  value: "Bearer sk-..."
AWS Secrets Manager
source:
  type: aws-secretsmanager
  secret: prod/api-key
  region: us-east-1
GitHub App

Generates short-lived installation tokens from a GitHub App private key. Tokens refresh automatically in the background at 75% of TTL.

source:
  type: github-app
  app_id: "12345"
  installation_id: "67890"
  private_key_path: ./key.pem       # or use private_key_env

See examples/gatekeeper-github-app.yaml for a complete example.

Network policy

Control which hosts the proxy will forward traffic to:

network:
  policy: strict       # deny all except explicitly allowed
  allow:
    - "api.github.com"
    - "*.anthropic.com"

Policies: permissive (allow all), strict (deny all, allow listed).

Observability

Gatekeeper supports OpenTelemetry for traces, metrics, and logs. No YAML configuration needed — use standard OTEL_* environment variables:

export OTEL_EXPORTER_OTLP_ENDPOINT=https://your-collector:4318
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"
gatekeeper --config gatekeeper.yaml

Library usage

Gatekeeper is a Go module. Import the proxy engine directly for custom integrations:

import (
    "github.com/majorcontext/gatekeeper/proxy"
)

ca, _ := proxy.LoadCA(certPEM, keyPEM)

p := proxy.NewProxy()
p.SetCA(ca)
p.SetCredentialWithGrant("api.github.com", "Authorization", "Bearer xxx", "github")

Moat uses Gatekeeper this way — importing the proxy and adding per-run credential scoping via a daemon layer.

Development

go build ./...           # build
go test -race ./...      # test
go vet ./...             # lint

License

MIT — see LICENSE.

Documentation

Overview

Package gatekeeper provides a standalone credential-injecting TLS proxy.

Credentials are pre-configured in gatekeeper.yaml and injected for all proxied requests matching the host. Access control is via network policy (who can reach the proxy) and an optional static auth token.

For per-caller credential isolation (run registration, token-scoped credentials), use the daemon package, which provides a management API over a Unix socket.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ResolveCredentialSource added in v0.5.0

ResolveCredentialSource creates either a static CredentialSource or a dynamic CredentialResolver from a credential config. For static sources (env, static, aws-secretsmanager, github-app), the first return is non-nil. For dynamic sources (token-exchange), the second return is non-nil.

func ResolveSource

ResolveSource creates a CredentialSource from a SourceConfig. Returns an error if the config contains fields not relevant to the selected type.

Types

type Config

type Config struct {
	Proxy       ProxyConfig        `yaml:"proxy"`
	TLS         TLSConfig          `yaml:"tls"`
	Credentials []CredentialConfig `yaml:"credentials"`
	Network     NetworkConfig      `yaml:"network"`
	Log         LogConfig          `yaml:"log"`
}

Config represents a Gate Keeper configuration file.

func LoadConfig

func LoadConfig(path string) (*Config, error)

LoadConfig reads and parses a Gate Keeper config from a file path.

func ParseConfig

func ParseConfig(data []byte) (*Config, error)

ParseConfig parses a Gate Keeper config from YAML bytes.

type CredentialConfig

type CredentialConfig struct {
	Host   string       `yaml:"host"`             // Target host (e.g., "api.github.com")
	Header string       `yaml:"header,omitempty"` // Header name (default: "Authorization")
	Prefix string       `yaml:"prefix,omitempty"` // Auth scheme prefix (e.g., "Bearer", "token"); auto-detected if omitted
	Format string       `yaml:"format,omitempty"` // Auth format: "" (default scheme prefix) or "basic" (HTTP Basic)
	Source SourceConfig `yaml:"source"`
	Grant  string       `yaml:"grant,omitempty"` // Optional label for logging
}

CredentialConfig describes a credential to resolve and inject. Host specifies which requests receive the credential. Header names the HTTP header to set (defaults to "Authorization"). Grant is an optional label used for logging.

When the header is "Authorization", the proxy needs a full header value including the auth scheme (e.g., "Bearer token123"). If the source value is a bare token without a scheme prefix, the gatekeeper auto-detects the correct scheme from known token prefixes (GitHub ghp_/gho_/etc.) or defaults to "Bearer". Set Prefix to override the auto-detected scheme.

For hosts that require HTTP Basic authentication (e.g., github.com git smart HTTP), set Format to "basic" and Prefix to the Basic auth username. The credential value becomes the password: Authorization: Basic base64(prefix:value).

type LogConfig

type LogConfig struct {
	Level  string `yaml:"level"`  // Log level (e.g., "debug", "info", "warn", "error")
	Format string `yaml:"format"` // Output format ("json" or "text")
	Output string `yaml:"output"` // Destination ("stderr", "stdout", or a file path; default: stderr)
}

LogConfig configures logging.

type NetworkConfig

type NetworkConfig struct {
	Policy string   `yaml:"policy"`
	Allow  []string `yaml:"allow,omitempty"`
}

NetworkConfig configures network policy.

type ProxyConfig

type ProxyConfig struct {
	Port      int    `yaml:"port"`
	Host      string `yaml:"host"`
	AuthToken string `yaml:"auth_token,omitempty"` // Optional token clients must provide via Proxy-Authorization
}

ProxyConfig configures the proxy listener.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the Gate Keeper server. It manages a TLS-intercepting proxy with statically configured credentials.

func New

func New(ctx context.Context, cfg *Config) (*Server, error)

New creates a new Gate Keeper server from the given configuration. The context is used for credential fetching (e.g., AWS Secrets Manager) and can be used to cancel startup if the process receives a signal.

func (*Server) ProxyAddr

func (s *Server) ProxyAddr() string

ProxyAddr returns the proxy listener's actual address (host:port). Returns empty string if the proxy has not started.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start starts the proxy. It blocks until the context is canceled.

func (*Server) Stop

func (s *Server) Stop(ctx context.Context) error

Stop gracefully shuts down the proxy server and all background refresh goroutines.

type SourceConfig

type SourceConfig struct {
	Type   string `yaml:"type"`             // "env", "static", "aws-secretsmanager", "github-app"
	Var    string `yaml:"var,omitempty"`    // for env source
	Value  string `yaml:"value,omitempty"`  // for static source
	Secret string `yaml:"secret,omitempty"` // for aws-secretsmanager
	Region string `yaml:"region,omitempty"` // for aws-secretsmanager

	AppID          string `yaml:"app_id,omitempty"`           // for github-app source
	InstallationID string `yaml:"installation_id,omitempty"`  // for github-app source
	PrivateKeyPath string `yaml:"private_key_path,omitempty"` // for github-app source
	PrivateKeyEnv  string `yaml:"private_key_env,omitempty"`  // for github-app source

	// token-exchange (RFC 8693) fields
	Endpoint         string `yaml:"endpoint,omitempty"`
	ClientID         string `yaml:"client_id,omitempty"`
	ClientSecret     string `yaml:"client_secret,omitempty"`
	ClientSecretEnv  string `yaml:"client_secret_env,omitempty"`
	SubjectHeader    string `yaml:"subject_header,omitempty"`
	SubjectFrom      string `yaml:"subject_from,omitempty"`
	SubjectTokenType string `yaml:"subject_token_type,omitempty"`
	Resource         string `yaml:"resource,omitempty"`
}

SourceConfig describes where to read a credential value from.

type TLSConfig

type TLSConfig struct {
	CACert string `yaml:"ca_cert"`
	CAKey  string `yaml:"ca_key"`
}

TLSConfig configures the CA certificate used for TLS interception.

Directories

Path Synopsis
cmd
gatekeeper command
Package proxy provides a TLS-intercepting HTTP proxy for credential injection.
Package proxy provides a TLS-intercepting HTTP proxy for credential injection.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL