policyserver

package
v0.17.0 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: Apache-2.0, Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnauthorized indicates token is invalid or expired (401).
	ErrUnauthorized = &PolicyError{StatusCode: http.StatusUnauthorized, Message: "Unauthorized"}

	// ErrForbidden indicates token valid but access denied by policy (403).
	ErrForbidden = &PolicyError{StatusCode: http.StatusForbidden, Message: "Forbidden"}

	// ErrNotHandled indicates this policy server does not handle the connection (422).
	ErrNotHandled = &PolicyError{StatusCode: http.StatusUnprocessableEntity, Message: "connection not handled"}
)

Standard errors for policy evaluation.

Functions

func DefaultExpiration added in v0.1.8

func DefaultExpiration() string

DefaultExpiration returns the default certificate expiration duration

func DefaultExtensions added in v0.1.8

func DefaultExtensions() map[string]string

DefaultExtensions returns the default SSH certificate extensions

func DefaultScopes added in v0.5.1

func DefaultScopes() []string

DefaultScopes returns the default OIDC scopes

func Forbidden

func Forbidden(message string) error

Forbidden returns a 403 error with the given message.

func InternalError

func InternalError(message string) error

InternalError returns a 500 error with the given message.

func NewHandler

func NewHandler(config Config) http.Handler

NewHandler creates an HTTP handler for the policy server. The handler supports:

GET /  — returns discovery data (auth, match patterns, default expiration)
POST / — evaluates a cert request (token + connection)

All requests are verified using RFC 9421 HTTP Message Signatures if CAPublicKey is configured.

func NotHandled added in v0.3.0

func NotHandled(message string) error

NotHandled returns a 422 error indicating this policy server does not handle the requested connection. The CA will return 422 to the client.

func Unauthorized

func Unauthorized(message string) error

Unauthorized returns a 401 error with the given message.

func ValidateDuration added in v0.1.8

func ValidateDuration(d string) error

ValidateDuration checks if a duration string is valid

Types

type BootstrapAuth added in v0.5.1

type BootstrapAuth struct {
	// Type identifies the auth method: "oidc" or "command"
	Type string `json:"type"`

	// OIDC fields (when type="oidc")
	Issuer       string   `json:"issuer,omitempty"`
	ClientID     string   `json:"client_id,omitempty"`
	ClientSecret string   `json:"client_secret,omitempty"`
	Scopes       []string `json:"scopes,omitempty"`

	// Command field (when type="command") - opaque string
	Command string `json:"command,omitempty"`
}

BootstrapAuth represents the auth configuration returned by the bootstrap endpoint. The Type field discriminates between auth methods.

type Config

type Config struct {
	// CAPublicKey is the CA's SSH public key for verifying RFC 9421 request signatures.
	// If empty, signature verification is skipped (not recommended for production).
	CAPublicKey sshcert.RawPublicKey

	// Validator validates tokens and extracts identity (authentication).
	Validator TokenValidator

	// Evaluator makes authorization decisions based on identity.
	Evaluator PolicyEvaluator

	// MaxRequestSize limits the request body size (default: 8192 bytes).
	MaxRequestSize int64

	// Discovery is the configuration returned on GET / requests.
	// The CA fetches this to serve discovery data to clients.
	Discovery *DiscoveryResponse
}

Config configures the policy server HTTP handler.

type DefaultPolicy added in v0.1.8

type DefaultPolicy struct {
	Allow      map[string][]string `yaml:"allow,omitempty" json:"allow,omitempty"`           // principal → allowed tags
	Expiration string              `yaml:"expiration,omitempty" json:"expiration,omitempty"` // Default cert expiration (e.g., "5m")
	Extensions map[string]string   `yaml:"extensions,omitempty" json:"extensions,omitempty"` // Default cert extensions
}

DefaultPolicy defines default policy settings

type DiscoveryResponse added in v0.14.0

type DiscoveryResponse struct {
	Auth              *BootstrapAuth `json:"auth"`
	MatchPatterns     []string       `json:"matchPatterns,omitempty"`
	DefaultExpiration string         `json:"defaultExpiration,omitempty"`
}

DiscoveryResponse is returned by GET / on the policy server. The CA fetches this and serves it to clients on /discovery.

type HostPolicy added in v0.1.8

type HostPolicy struct {
	Allow      map[string][]string `yaml:"allow,omitempty" json:"allow,omitempty"`           // principal → allowed tags
	Expiration string              `yaml:"expiration,omitempty" json:"expiration,omitempty"` // Override expiration
	Extensions map[string]string   `yaml:"extensions,omitempty" json:"extensions,omitempty"` // Override extensions
}

HostPolicy defines per-host policy overrides

type LoaderProvider added in v0.8.0

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

LoaderProvider wraps a PolicyLoader to implement PolicyProvider.

func NewLoaderProvider added in v0.8.0

func NewLoaderProvider(loader *PolicyLoader) *LoaderProvider

NewLoaderProvider creates a PolicyProvider that uses a PolicyLoader.

func (*LoaderProvider) GetPolicy added in v0.8.0

func (p *LoaderProvider) GetPolicy(ctx context.Context) (*PolicyConfig, error)

GetPolicy loads the current policy from the configured URL.

type OIDCConfig added in v0.1.8

type OIDCConfig struct {
	Issuer       string   `yaml:"issuer" json:"issuer"`
	ClientID     string   `yaml:"client_id" json:"client_id"`
	ClientSecret string   `yaml:"client_secret,omitempty" json:"client_secret,omitempty"` // Optional, for confidential clients
	Scopes       []string `yaml:"scopes,omitempty" json:"scopes,omitempty"`               // Optional, defaults to ["openid", "profile", "email"]
}

OIDCConfig represents OIDC configuration for token validation

type PolicyConfig added in v0.8.0

type PolicyConfig struct {
	Users    map[string][]string    `yaml:"users" json:"users"` // user identity → tags
	Defaults *DefaultPolicy         `yaml:"defaults,omitempty" json:"defaults,omitempty"`
	Hosts    map[string]*HostPolicy `yaml:"hosts,omitempty" json:"hosts,omitempty"` // hostname → host policy
}

PolicyConfig contains the dynamic policy data that can be loaded from a URL. This includes users, defaults, and hosts that can change without restarting the server.

func (*PolicyConfig) HostPatterns added in v0.8.0

func (c *PolicyConfig) HostPatterns() []string

HostPatterns returns the list of host patterns defined in the policy.

func (*PolicyConfig) Validate added in v0.8.0

func (c *PolicyConfig) Validate() error

Validate checks that the PolicyConfig is valid.

type PolicyError

type PolicyError struct {
	StatusCode int
	Message    string
}

PolicyError represents a policy evaluation error with HTTP status code.

func (*PolicyError) Error

func (e *PolicyError) Error() string

type PolicyEvaluator

type PolicyEvaluator interface {
	// Evaluate makes an authorization decision for the given identity and connection.
	// The identity has already been extracted from a validated token.
	// The context is used for loading dynamic policy if configured.
	// Returns:
	// - *Response: Certificate parameters and policy if authorized
	// - error: If authorization denied
	//
	// Error handling:
	// - Return ErrForbidden (403) if access denied by policy
	// - Return other errors (500) for internal errors
	Evaluate(ctx context.Context, identity string, conn policy.Connection) (*Response, error)
}

PolicyEvaluator makes authorization decisions based on identity and connection details. The token has already been validated and identity extracted by the handler. Implementations must: - Make authorization decision (allow/deny) based on identity - Return certificate parameters (principals, expiration, extensions) and policy (hostPattern) - Return appropriate errors for different failure modes

type PolicyLoader added in v0.8.0

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

PolicyLoader loads policy configuration from a URL (file or HTTP). It handles caching for both HTTP (via Cache-Control headers) and file sources (via mtime).

func NewPolicyLoader added in v0.8.0

func NewPolicyLoader(url string) *PolicyLoader

NewPolicyLoader creates a new policy loader for the given URL. Supports:

  • http:// or https:// - HTTP fetch with automatic caching based on response headers
  • file:///path - explicit file path
  • /path or ./path - bare file path

func (*PolicyLoader) Load added in v0.8.0

func (l *PolicyLoader) Load(ctx context.Context) (*PolicyConfig, error)

Load loads the policy configuration from the configured URL. For HTTP sources, caching is handled by httpcache respecting Cache-Control headers. For file sources, the policy is reloaded if the file's mtime has changed.

type PolicyProvider added in v0.8.0

type PolicyProvider interface {
	// GetPolicy returns the current policy configuration.
	// Implementations should handle caching internally.
	GetPolicy(ctx context.Context) (*PolicyConfig, error)
}

PolicyProvider is the interface for getting the current policy. This allows the evaluator to get fresh policy on each request.

type PolicyRulesConfig added in v0.1.8

type PolicyRulesConfig struct {
	CAPublicKey string                 `yaml:"ca_pubkey" json:"ca_pubkey"`
	OIDC        OIDCConfig             `yaml:"oidc" json:"oidc"`
	Users       map[string][]string    `yaml:"users" json:"users"` // user identity → tags
	Defaults    *DefaultPolicy         `yaml:"defaults,omitempty" json:"defaults,omitempty"`
	Hosts       map[string]*HostPolicy `yaml:"hosts,omitempty" json:"hosts,omitempty"` // hostname → host policy
}

PolicyRulesConfig represents the policy server rules configuration. This defines users, hosts, and access policies - not CLI flags. For new deployments, consider using ServerConfig + PolicyConfig separately to enable dynamic policy loading via policy_url.

func (*PolicyRulesConfig) BootstrapAuth added in v0.5.1

func (c *PolicyRulesConfig) BootstrapAuth() BootstrapAuth

BootstrapAuth returns the auth configuration for the bootstrap endpoint. Currently only supports OIDC auth type.

func (*PolicyRulesConfig) ExtractPolicyConfig added in v0.8.0

func (c *PolicyRulesConfig) ExtractPolicyConfig() *PolicyConfig

ExtractPolicyConfig extracts the dynamic policy portion from PolicyRulesConfig. Used for backwards compatibility when policy is defined inline.

func (*PolicyRulesConfig) ExtractServerConfig added in v0.8.0

func (c *PolicyRulesConfig) ExtractServerConfig() *ServerConfig

ExtractServerConfig extracts the static server portion from PolicyRulesConfig. Used for backwards compatibility when all config is in one file.

func (*PolicyRulesConfig) Validate added in v0.1.8

func (c *PolicyRulesConfig) Validate() error

Validate checks that the PolicyRulesConfig is valid

type Request

type Request struct {
	Token      string            `json:"token"`
	Connection policy.Connection `json:"connection"`
}

Request from CA to policy server.

type Response

type Response struct {
	CertParams ca.CertParams `json:"certParams"`
	Policy     policy.Policy `json:"policy"`
}

Response from policy server to CA.

type ServerConfig added in v0.8.0

type ServerConfig struct {
	CAPublicKey string     `yaml:"ca_pubkey" json:"ca_pubkey"`
	OIDC        OIDCConfig `yaml:"oidc" json:"oidc"`
	PolicyURL   string     `yaml:"policy_url,omitempty" json:"policy_url,omitempty"` // URL to load dynamic policy from
}

ServerConfig contains static server configuration loaded at startup. These settings cannot be changed without restarting the server.

func (*ServerConfig) BootstrapAuth added in v0.8.0

func (c *ServerConfig) BootstrapAuth() BootstrapAuth

BootstrapAuth returns the auth configuration for the bootstrap endpoint. Currently only supports OIDC auth type.

func (*ServerConfig) Validate added in v0.8.0

func (c *ServerConfig) Validate() error

Validate checks that the ServerConfig is valid.

type StaticProvider added in v0.8.0

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

StaticProvider provides a fixed policy configuration. Used for backwards compatibility when policy is defined inline in config.

func NewStaticProvider added in v0.8.0

func NewStaticProvider(policy *PolicyConfig) *StaticProvider

NewStaticProvider creates a PolicyProvider that always returns the same policy.

func (*StaticProvider) GetPolicy added in v0.8.0

func (p *StaticProvider) GetPolicy(ctx context.Context) (*PolicyConfig, error)

GetPolicy returns the static policy configuration.

type TokenValidator added in v0.3.0

type TokenValidator interface {
	// ValidateAndExtractIdentity validates the token and returns the identity.
	// Returns an error if the token is invalid or expired.
	ValidateAndExtractIdentity(token string) (identity string, err error)
}

TokenValidator validates authentication tokens and extracts identity. Used by handlers to authenticate requests before policy evaluation.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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