Documentation
¶
Overview ¶
Package config loads and validates the proxy YAML configuration. Use Load to parse from an io.Reader or LoadFile to read from disk. Both expand ${VAR} references using the process environment before unmarshalling.
Index ¶
- Variables
- type AuthConfig
- type Config
- type ConfigParams
- type CredentialConfig
- type Encryption
- type ExtensionServer
- type ExtensionServerList
- type ExternalAuthConfig
- type JWKSConfig
- type KeyPolicy
- type ListenConfig
- type NamespaceConfig
- type NamespaceMapping
- type NamespaceRules
- type Routing
- type RoutingMatch
- type RoutingRule
- type StaticCredentialConfig
- type StaticTokenConfig
- type TLSConfig
- type Upstream
- type UpstreamList
Constants ¶
This section is empty.
Variables ¶
var ConfigFileTag = fx.ResultTags(`name:"configFile"`)
var Module = fx.Option(fx.Provide(func(p ConfigParams) (*Config, error) { return LoadFile(p.File) }))
Module is an fx module that provides *Config by loading the file path supplied as the named value "configFile".
Functions ¶
This section is empty.
Types ¶
type AuthConfig ¶
type AuthConfig struct {
External *ExternalAuthConfig `yaml:"external"`
StaticToken *StaticTokenConfig `yaml:"staticToken"`
JWKS *JWKSConfig `yaml:"jwks"`
}
AuthConfig configures inbound authentication for the proxy listener. Exactly one authenticator must be selected: one of the built-in ones, or an external extension server that decides on the proxy's behalf.
func (*AuthConfig) Validate ¶
func (a *AuthConfig) Validate() error
Validate requires exactly one authenticator and checks the selected one.
type Config ¶
type Config struct {
Listen ListenConfig `yaml:",inline"`
Encryption Encryption `yaml:"encryption"`
ExtensionServers ExtensionServerList `yaml:"extensionServers"`
Routing Routing `yaml:"routing"`
Upstreams UpstreamList `yaml:"upstreams"`
Auth *AuthConfig `yaml:"auth"`
}
Config is the top-level proxy configuration.
func Load ¶
Load reads and parses the YAML config specified in the Reader. Values of the form ${VAR} are replaced with the corresponding environment variable.
func LoadFile ¶
LoadFile reads and parses the YAML config file at path. Values of the form ${VAR} are replaced with the corresponding environment variable.
func (*Config) Validate ¶
Validate requires at least one upstream, checks the listen configuration and every upstream, requires upstream names to be unique, and checks that every cross-reference names something configured: routing references an upstream, while encryption key URIs and external authentication reference an extension server. A missing upstream surfaces on the "upstreams" field. Failures are stamped with the failing node's YAML path as the subject (e.g. "upstreams[0].namespaces.rules.overrides[1]"). A duplicate name surfaces on the "upstreams[name]" field, an unknown routing reference on the "routing"/"routing.rules[i]" subject, and an unknown extension server on the referring "encryption.*" or "auth.external" subject.
type ConfigParams ¶
ConfigParams holds the fx-injected dependencies for loading the config file.
type CredentialConfig ¶
type CredentialConfig struct {
Static *StaticCredentialConfig `yaml:"static"`
}
CredentialConfig configures the credential the proxy presents to an upstream. Static is the only variant today.
func (*CredentialConfig) Validate ¶
func (c *CredentialConfig) Validate() error
Validate requires the static credential and checks it.
type Encryption ¶
type Encryption struct {
Enabled bool `yaml:"enabled"`
CacheSize int `yaml:"cacheSize"`
Default *KeyPolicy `yaml:"default"`
Overrides map[string]KeyPolicy `yaml:"overrides"`
}
Encryption configures envelope encryption of payloads. When Enabled, a Default key policy is required and governs how DEKs are provisioned and rotated. CacheSize bounds the in-memory DEK cache. Overrides maps a namespace to a key policy that supersedes Default for that namespace; the keys are pre-translation (local) namespace names, matching the namespace the vault seals under at request time.
func (*Encryption) Validate ¶
func (e *Encryption) Validate() error
Validate requires a non-negative cache size, a Default policy whenever encryption is Enabled, and (when a Default is present at all) that the policy itself is valid.
type ExtensionServer ¶ added in v0.3.0
type ExtensionServer struct {
Name string `yaml:"name"`
Listen ListenConfig `yaml:",inline"`
Credentials *CredentialConfig `yaml:"credentials"`
}
ExtensionServer addresses an operator-run gRPC server implementing the extension APIs under api/, currently api.kms.v1.EncryptionService, the pluggable Key Encryption Key provider. The proxy has built-in KMS providers (awskms, azurekeyvault, gcpkms); an extension server is how an operator plugs in a backend the proxy does not support natively, such as an on-prem HSM or an internal key service.
Name identifies the server within the configuration so other blocks can reference it, and must be unique across the list. Credentials, when set, attach per-request credentials to the outbound calls and require TLS, since sending them over a plaintext connection would expose them on the wire.
Unlike Upstream, an extension server is dialed at a fixed address rather than resolved per request, so a templated hostPort is rejected outright instead of being deferred to request time.
func (*ExtensionServer) Validate ¶ added in v0.3.0
func (s *ExtensionServer) Validate() error
Validate checks a single extension server: a name is required, hostPort must be a literal host:port with no template action, and any TLS block must be valid for dialing out. Credentials without TLS are rejected. Failures are unattributed, leaving the caller to stamp the path - ExtensionServerList supplies the index.
type ExtensionServerList ¶ added in v0.3.0
type ExtensionServerList []ExtensionServer
ExtensionServerList is the configured set of extension servers. It exists as a named type so the checks that span the whole collection - name and address uniqueness - live alongside the per-entry checks instead of in the parent Config.
func (ExtensionServerList) Validate ¶ added in v0.3.0
func (sl ExtensionServerList) Validate() error
Validate checks every entry and enforces that names and addresses are unique across the list: two servers sharing a name would make a reference ambiguous, and two sharing an address is a copy-paste error rather than a useful configuration. Uniqueness failures are reported on a "[name]"/"[hostPort]" field because they belong to the collection rather than to any one entry, while per-entry failures are stamped with a "[i]" subject. Both compose onto the parent's path, so Config surfaces them as "extensionServers[name]" and "extensionServers[0]". An empty or nil list is valid.
type ExternalAuthConfig ¶ added in v0.4.0
type ExternalAuthConfig struct {
Name string `yaml:"name"`
CredentialHeaders []string `yaml:"credentialHeaders"`
}
ExternalAuthConfig delegates the inbound decision to an extension server implementing api.auth.v1.AuthService, for identity systems the built-in authenticators do not cover.
Name selects which configured extension server to ask. CredentialHeaders names the metadata headers carrying the caller's credentials, which the proxy lifts into the request it sends that server and removes from the stream it forwards upstream. It has to be declared because a verdict reports only admit-or-deny, so nothing in the exchange reveals which headers mattered.
Leaving it empty does not hide the caller's credentials from the server. The proxy forwards the caller's metadata on the call either way, so the server still sees whatever headers the caller sent; what it loses is the request field naming them, so it has to know which metadata to read and cannot tell a header this proxy vouches for from any other. Nothing is stripped before proxying upstream either, so the caller's credential continues to the upstream alongside any credential configured for it.
func (*ExternalAuthConfig) Validate ¶ added in v0.4.0
func (c *ExternalAuthConfig) Validate() error
Validate requires the extension server name; the credential header list may be empty. Whether a server by that name is actually configured is checked by [AuthConfig.referentialRules], which runs where the server list is known.
type JWKSConfig ¶
type JWKSConfig struct {
URL string `yaml:"url"`
Audiences []string `yaml:"audiences"`
Issuer string `yaml:"issuer"`
Header string `yaml:"header"`
Scheme string `yaml:"scheme"`
}
JWKSConfig verifies an inbound JWT's signature and claims against a JWKS.
func (*JWKSConfig) Validate ¶
func (c *JWKSConfig) Validate() error
Validate requires a syntactically valid absolute JWKS URL.
type KeyPolicy ¶
type KeyPolicy struct {
URI url.URL `yaml:"uri"`
DecryptURIs []url.URL `yaml:"decryptURIs"`
Duration time.Duration `yaml:"duration"`
RenewBefore time.Duration `yaml:"renewBefore"`
}
KeyPolicy describes the KMS key backing a DEK and its rotation schedule. URI is the primary key used to wrap new DEKs; DecryptURIs are additional keys accepted when unwrapping existing DEKs (for example, during key migration). Duration is a DEK's lifetime and RenewBefore is the lead time before that lifetime elapses at which rotation begins.
type ListenConfig ¶
ListenConfig defines properties for an inbound listener.
func (*ListenConfig) Validate ¶
func (l *ListenConfig) Validate() error
Validate checks the host:port and, when present, the TLS configuration.
type NamespaceConfig ¶
type NamespaceConfig struct {
Rules NamespaceRules `yaml:"rules"`
}
NamespaceConfig groups the namespace translation rules for an upstream.
func (*NamespaceConfig) Validate ¶
func (c *NamespaceConfig) Validate() error
Validate checks the namespace translation rules.
type NamespaceMapping ¶
NamespaceMapping is one explicit local/remote namespace pair, used to short-circuit the prefix/suffix rule for namespaces whose names do not follow the convention.
func (*NamespaceMapping) Validate ¶
func (m *NamespaceMapping) Validate() error
Validate requires both the local and remote namespace names.
type NamespaceRules ¶
type NamespaceRules struct {
Prefix string `yaml:"prefix"`
Suffix string `yaml:"suffix"`
Overrides []NamespaceMapping `yaml:"overrides"`
// contains filtered or unexported fields
}
NamespaceRules translates namespace names between the local view that workers use and the remote names registered on the upstream cluster.
The default translation is to wrap or unwrap a Prefix and Suffix: Remote("payments") returns Prefix+"payments"+Suffix, and Local of that returns "payments". When an explicit Overrides entry matches, the override takes precedence over the prefix/suffix rule.
func (*NamespaceRules) Configured ¶
func (r *NamespaceRules) Configured() bool
Configured reports whether the rules translate anything. When false the prefix, suffix, and overrides are all empty and Remote and Local are identity, so callers can skip installing translation entirely.
func (*NamespaceRules) Local ¶
func (r *NamespaceRules) Local(remoteNS string) string
Local returns the local namespace name that corresponds to remoteNS. If an override matches it wins; otherwise the configured Prefix and Suffix are stripped from remoteNS.
func (*NamespaceRules) Remote ¶
func (r *NamespaceRules) Remote(localNS string) string
Remote returns the remote namespace name that corresponds to localNS. If an override matches it wins; otherwise localNS is wrapped with the configured Prefix and Suffix.
func (*NamespaceRules) UnmarshalYAML ¶
func (r *NamespaceRules) UnmarshalYAML(unmarshal func(any) error) error
func (*NamespaceRules) Validate ¶
func (r *NamespaceRules) Validate() error
Validate checks that override entries are complete and that no local or remote name is mapped more than once.
type Routing ¶
type Routing struct {
DefaultUpstream string `yaml:"default"`
SystemUpstream string `yaml:"system"`
Rules []RoutingRule `yaml:"rules"`
}
Routing selects which upstream serves a request. DefaultUpstream is the fallback when no rule matches and SystemUpstream serves system-namespace traffic; both name an upstream and are optional. Rules are evaluated in order against the incoming request.
type RoutingMatch ¶
type RoutingMatch struct {
Namespace string `yaml:"namespace"`
Metadata map[string]string `yaml:"metadata"`
}
RoutingMatch describes the request attributes a rule matches on. A match requires at least one of Namespace or Metadata: an empty match would apply to every request, which is what DefaultUpstream is for.
func (*RoutingMatch) Validate ¶
func (m *RoutingMatch) Validate() error
Validate requires at least one of Namespace or Metadata to be set.
type RoutingRule ¶
type RoutingRule struct {
Upstream string `yaml:"upstream"`
Match RoutingMatch `yaml:"match"`
}
RoutingRule sends every request matched by Match to the named Upstream.
func (*RoutingRule) Validate ¶
func (r *RoutingRule) Validate() error
Validate requires the referenced upstream and checks the match.
type StaticCredentialConfig ¶
type StaticCredentialConfig struct {
APIKey string `yaml:"apiKey"`
Header string `yaml:"header"`
Scheme string `yaml:"scheme"`
}
StaticCredentialConfig injects a fixed API key as a bearer header on every outbound request to the upstream.
func (*StaticCredentialConfig) Validate ¶
func (c *StaticCredentialConfig) Validate() error
Validate requires the API key.
type StaticTokenConfig ¶
type StaticTokenConfig struct {
Token string `yaml:"token"`
Header string `yaml:"header"`
Scheme string `yaml:"scheme"`
}
StaticTokenConfig compares an inbound bearer token against a fixed value.
func (*StaticTokenConfig) Validate ¶
func (c *StaticTokenConfig) Validate() error
Validate requires the token value.
type TLSConfig ¶
type TLSConfig struct {
CA string `yaml:"ca"` // PEM-encoded CA certificate (mTLS only)
Cert string `yaml:"cert"` // PEM-encoded server certificate
Key string `yaml:"key"` // PEM-encoded private key
ServerName string `yaml:"serverName"` // Optional SNI override
}
TLSConfig specifies TLS material for an inbound HTTPS listener. When CAFile is non-empty the listener enforces mutual TLS: connecting clients must present a certificate signed by that CA.
NB: Be sure to set ServerName when the host name you dial doesn't match the CN or SAN on the server's certificate.
func (*TLSConfig) Dialer ¶
Dialer resolves the outbound (client) credential for this TLS block. A nil receiver yields an insecure dialer.
type Upstream ¶
type Upstream struct {
Name string `yaml:"name"`
Listen ListenConfig `yaml:",inline"`
Namespaces NamespaceConfig `yaml:"namespaces"`
Credentials *CredentialConfig `yaml:"credentials"`
}
Upstream describes a single upstream Temporal cluster the proxy connects workers to along with configuration for that remote cluster. Name identifies the upstream so routing rules can refer to it; it must be unique within the config.
func (*Upstream) IsTemplated ¶
IsTemplated reports whether the upstream must be resolved per request because its hostPort, or its TLS server name when one is configured, contains a text/template action.
type UpstreamList ¶ added in v0.3.0
type UpstreamList []Upstream
func (UpstreamList) Validate ¶ added in v0.3.0
func (ul UpstreamList) Validate() error