Documentation
¶
Overview ¶
Package parsec is a scalable realtime messaging engine built on the github.com/centrifugal/centrifuge OSS Go library.
Parsec ships as a CLI binary and as an embeddable Go library. The library is the primary deliverable; the CLI in cmd/parsec is a thin adapter over it, and the Twirp surface is a sibling to the CLI.
Concepts:
- Channel — a named pub/sub topic. Names follow the public/private namespace grammar in package channels.
- Broker — the centrifuge Node wrapper that holds connections and ships publications.
- Manager — channel lifecycle (open, create-private, touch, sweep, delete). TTL enforcement.
- Sink — out-of-band delivery (email, slack, webhook) when a session is no longer listening.
- KeyRing — N HMAC keys with one active signer; rotated without downtime.
- Issuer — mints access / refresh / mgmt tokens using the active key.
Index ¶
- Constants
- func ClaimsFromContext(ctx context.Context) *auth.Claims
- func RemoteIPFromContext(ctx context.Context) string
- func SubjectFromContext(ctx context.Context) string
- func WithClaims(ctx context.Context, c *auth.Claims) context.Context
- func WithRemoteIP(ctx context.Context, ip string) context.Context
- func WithSubject(ctx context.Context, sub string) context.Context
- type AdminUIOptions
- type Channel
- type ChannelName
- type Credentials
- type Message
- type Options
- type Parsec
- func (p *Parsec) AccessLogger() *slog.Logger
- func (p *Parsec) AdminUIOptions() AdminUIOptions
- func (p *Parsec) Broker() *broker.Broker
- func (p *Parsec) Cache() cache.Cache
- func (p *Parsec) CacheBackend() string
- func (p *Parsec) CheckPublishLimit(ctx context.Context, subject string, channel channels.Name, ...) (ratelimit.Decision, error)
- func (p *Parsec) CheckRateLimit(ctx context.Context, bucket, subject string, override *ratelimit.Limit) (ratelimit.Decision, error)
- func (p *Parsec) CheckSubscribeLimit(ctx context.Context, subject string, channel channels.Name, ...) (ratelimit.Decision, error)
- func (p *Parsec) CompositeVerifier() *auth.CompositeVerifier
- func (p *Parsec) ConfigSource() string
- func (p *Parsec) CreatePrivate(subjectID, name string, ttl time.Duration, scopes []auth.Scope) (Credentials, error)
- func (p *Parsec) DLQ() sinks.DLQ
- func (p *Parsec) DLQBackend() string
- func (p *Parsec) GenerateKey() (auth.Key, error)
- func (p *Parsec) GenerateKeyAlg(alg auth.Alg) (auth.Key, error)
- func (p *Parsec) Issuer() *auth.Issuer
- func (p *Parsec) JWKSHandler() http.Handler
- func (p *Parsec) KeyRing() *auth.KeyRing
- func (p *Parsec) KeyringPath() string
- func (p *Parsec) KeyringStore() auth.KeyRingStore
- func (p *Parsec) Limiter() ratelimit.Limiter
- func (p *Parsec) Manager() *channels.Manager
- func (p *Parsec) Metrics() *metrics.Metrics
- func (p *Parsec) MetricsBearerToken() string
- func (p *Parsec) OIDCEnabled() bool
- func (p *Parsec) OIDCIssuer() string
- func (p *Parsec) OIDCVerifier() *auth.OIDCVerifier
- func (p *Parsec) OTLPEndpoint() string
- func (p *Parsec) OpenPublic(name string, ttl time.Duration) (*channels.Channel, error)
- func (p *Parsec) Peers() []string
- func (p *Parsec) Persistence() string
- func (p *Parsec) PromoteKey(id string) error
- func (p *Parsec) Publish(ctx context.Context, name string, data []byte) (broker.PublishResult, error)
- func (p *Parsec) PublishOrSink(ctx context.Context, name string, data []byte, sinkName string, ...) (bool, error)
- func (p *Parsec) RateLimits() ratelimit.RateLimits
- func (p *Parsec) RefreshAccess(refreshToken string) (RefreshResult, error)
- func (p *Parsec) RefreshAccessCtx(ctx context.Context, refreshToken string) (RefreshResult, error)
- func (p *Parsec) Region() string
- func (p *Parsec) ReloadKeys() error
- func (p *Parsec) RetireKey(id string) error
- func (p *Parsec) RevocationStore() tokenbroker.RevocationStore
- func (p *Parsec) Run(ctx context.Context) error
- func (p *Parsec) SchemaHandler() http.Handler
- func (p *Parsec) SinkRetryConfig() sinks.RetryConfig
- func (p *Parsec) Sinks() *sinks.Registry
- func (p *Parsec) TelemetryHandler() http.Handler
- func (p *Parsec) TokenBrokerHandler() http.Handler
- func (p *Parsec) Tracer() trace.Tracer
- func (p *Parsec) TracerShutdown(ctx context.Context) error
- func (p *Parsec) TrustedProxies() []net.IPNet
- func (p *Parsec) Verifier() *auth.Verifier
- func (p *Parsec) WebTransportOptions() WebTransportOptions
- type RefreshResult
- type Sink
- type WebTransportOptions
Constants ¶
const MetricsPath = "/metrics"
MetricsPath is the canonical mount point for the Prometheus endpoint. Surfaced in the manifest so clients can discover it.
Variables ¶
This section is empty.
Functions ¶
func ClaimsFromContext ¶
ClaimsFromContext returns the claims planted by WithClaims, or nil.
func RemoteIPFromContext ¶
RemoteIPFromContext returns the IP planted by WithRemoteIP, or "".
func SubjectFromContext ¶
SubjectFromContext returns the bearer subject planted by WithSubject, or "" when no bearer was presented (e.g. RefreshToken's body authentication, or tests with bearer enforcement disabled).
func WithClaims ¶
WithClaims returns a new context that carries the validated claims. Surface code calls this so downstream rate-limit gates can read the optional rl override.
func WithRemoteIP ¶
WithRemoteIP returns a new context that carries the request's remote IP (host portion of r.RemoteAddr). Used by gates that key off IP instead of subject — typically RefreshToken which has no mgmt bearer.
Types ¶
type AdminUIOptions ¶
type AdminUIOptions struct {
// Enabled mounts /admin/* with the SPA when true. Operators opt in
// per deployment; production deployments that don't want the UI
// leave it off so the asset bundle never enters the response graph.
Enabled bool
}
AdminUIOptions controls the embedded operator admin SPA. Off by default — when disabled the entire /admin/* tree returns 404 and no bytes from the embedded asset bundle reach the response.
type Credentials ¶
type Credentials struct {
Name channels.Name
AccessToken string
RefreshToken string
AccessExpires time.Time
RefreshExpires time.Time
}
Credentials returned from CreatePrivate.
type Options ¶
type Options struct {
// FS is the filesystem used for any persistence. Defaults to OsFs.
FS afero.Fs
// Sinks is the registry of out-of-band delivery sinks.
Sinks *sinks.Registry
// KeyRing holds the HMAC signing keys. If nil, parsec.New chooses
// between StateDir-backed bootstrap and an ephemeral in-memory ring
// (logged loudly so the operator knows tokens won't survive restart).
KeyRing *auth.KeyRing
// StateDir, when set, makes parsec.New load (or bootstrap) the
// keyring from <StateDir>/keyring.json. Ignored if KeyRing is
// non-nil. The directory is created with 0700; the file with 0600.
StateDir string
// KeyringPollInterval enables the mtime-poll watcher when > 0 and a
// StateDir is set. Default 5s.
KeyringPollInterval time.Duration
// RedisClient enables multi-node mode. When set, channel registry,
// keyring, DLQ, and rate limiter all share this client by default.
// The zero value (nil) means single-node in-memory.
RedisClient redis.UniversalClient
// RedisAddr is a convenience: when set and RedisClient is nil,
// parsec.New constructs a default go-redis client. Address syntax
// accepts the same forms as centrifuge.RedisShardConfig.Address
// (host:port, redis://..., redis+sentinel://..., etc.).
RedisAddr string
// RedisShards configures the centrifuge Redis broker. When set, the
// broker switches from in-memory to Redis-backed. If empty and
// RedisAddr is set, parsec.New builds a single shard from RedisAddr.
RedisShards []*centrifuge.RedisShard
// RedisKeyPrefix namespaces every Parsec key in Redis. Default
// "parsec". Override when multiple Parsec deployments share an
// instance.
RedisKeyPrefix string
// NodeID identifies this Parsec process across the cluster. Used to
// dedupe cross-node pub/sub events. Empty means auto-generate.
NodeID string
// AccessTokenTTL overrides the default access-token lifetime (5m).
AccessTokenTTL time.Duration
// MaxRefreshTokenTTL overrides the default refresh-token cap (1h).
MaxRefreshTokenTTL time.Duration
// RefreshStore tracks redeemed refresh JTIs and revoked rotation
// families. When nil and a RedisClient is configured parsec.New
// builds a RedisRefreshStore; otherwise a MemoryRefreshStore. The
// store gates RefreshAccess so a leaked refresh token cannot be
// redeemed twice without revoking the entire family.
RefreshStore auth.RefreshStore
// MemoryRefreshPruneInterval is the cleanup interval used when
// parsec.New constructs the default MemoryRefreshStore. Default
// 5 minutes. Ignored when RefreshStore is explicit.
MemoryRefreshPruneInterval time.Duration
// BrokerOptions are forwarded to broker.New. The SubscribeAuthorizer
// is overridden by parsec.New to use the Verifier.
BrokerOptions broker.Options
// SweepInterval is how often the channel manager runs Sweep. Default 30s.
SweepInterval time.Duration
// SinkRetry configures the sink-side retry loop used by PublishOrSink.
// Defaults are filled by sinks.RetryConfig.Normalize: 5 attempts,
// 1s..30s exponential backoff, 0.2 jitter. Set MaxAttempts=1 to
// disable retries.
SinkRetry sinks.RetryConfig
// PerSinkRetry holds per-sink-name overrides of SinkRetry. Useful
// when email needs longer backoffs than slack, for instance.
PerSinkRetry map[string]sinks.RetryConfig
// DLQ overrides the default DLQ. When nil, parsec.New constructs a
// sinks.RedisDLQ if RedisClient is set, otherwise a MemoryDLQ.
DLQ sinks.DLQ
// Logger receives boot warnings and reload events. Optional.
Logger *slog.Logger
// MetricsRegistry, when non-nil, is used as the Prometheus registry
// the /metrics endpoint scrapes. When nil, parsec.New constructs a
// dedicated registry (Go + process collectors included) — set this
// when the embedder already runs prometheus.DefaultRegisterer and
// wants Parsec metrics to share that universe.
MetricsRegistry *prometheus.Registry
// MetricsBearerToken gates the /metrics endpoint. When set, requests
// must present Authorization: Bearer <token> matching this value
// exactly. When empty, /metrics is unguarded — appropriate only when
// the route is blocked at the network layer.
MetricsBearerToken string
// OTLPEndpoint enables OpenTelemetry tracing when non-empty. The
// value is passed to otlptracehttp.WithEndpoint (host:port form, no
// scheme). Empty means "tracing disabled" and the hot path performs
// zero allocations.
OTLPEndpoint string
// AccessLogger receives the per-request INFO line from the HTTP
// access-log middleware. Defaults to Logger when nil.
AccessLogger *slog.Logger
// TrustedProxies is the CIDR list of upstream proxies whose
// X-Forwarded-For headers Parsec will honor. Anything else is
// ignored to prevent client-IP spoofing.
TrustedProxies []net.IPNet
// WebTransport, when populated with a UDP listen address + TLS cert
// pair, enables the HTTP/3 WebTransport handler. Default: disabled.
WebTransport WebTransportOptions
// AdminUI controls the embedded operator SPA. Default: disabled —
// the bytes are kept out of the response graph entirely (every
// /admin/* path returns 404 when off).
AdminUI AdminUIOptions
// ConfigSource is the path the TOML config was loaded from. The CLI
// stamps this from `parsec serve --config <path>`; the library
// facade carries it through to the manifest for operator visibility.
// Embedders typically leave it empty.
ConfigSource string
// Limiter, when non-nil, is the rate-limit backend used by every
// gated surface (publish / subscribe / token-issue). When nil and
// RateLimits has any non-zero bucket, parsec.New builds one:
// RedisLimiter when RedisClient is set, MemoryLimiter otherwise.
Limiter ratelimit.Limiter
// RateLimits configures the default per-subject budgets for each
// gated bucket. The zero value (every Limit.Rate == 0) means
// "unlimited" — no gating, no Redis traffic.
RateLimits ratelimit.RateLimits
// PerChannelPublishLimits, when non-empty, overrides RateLimits.Publish
// for channels whose name matches a configured pattern. Keys are
// channel-name patterns (see channels.ParsePattern grammar); values
// are the Limit applied to publishes to channels matching that
// pattern. parsec.New compiles each pattern at boot — an invalid
// pattern aborts startup so misconfigurations fail loud. Per-rule
// keys are namespaced separately from the default bucket, so a
// hot channel cannot drain the global publish budget.
PerChannelPublishLimits map[string]ratelimit.Limit
// PerChannelSubscribeLimits mirrors PerChannelPublishLimits for the
// subscribe bucket. The subscribe authorizer resolves the most-
// specific rule on every subscribe attempt; the per-rule key is
// namespaced (`subscribe-channel:<rule-raw>:<subject>`) so a hot
// channel cannot drain the global subscribe budget. An invalid
// pattern aborts startup with PARSEC_INVALID_ARGUMENT.
PerChannelSubscribeLimits map[string]ratelimit.Limit
// OIDCConfig, when non-nil, enables the OIDC bridge: management
// RPC requests carrying an IdP-issued ID token bearer are
// translated into a synthetic mgmt Claims and accepted alongside
// HMAC-signed parsec mgmt tokens. nil = OIDC disabled (default).
//
// See auth.OIDCConfig for the full shape. parsec.New discovers
// the issuer at boot — discovery failures abort startup so
// misconfigured deployments fail loud.
OIDCConfig *auth.OIDCConfig
// Region labels metrics and access logs with the operator's region
// name (e.g. "us-east"). When empty no label is attached, so
// single-region deployments stay label-free. The value is also
// surfaced in the manifest so peers can discover topology.
Region string
// Peers is the informational list of peer region URLs. Surfaced in
// the manifest so operators (and tooling like parsec-keys-sync) can
// discover the multi-region topology. Parsec itself does no peer
// validation or active replication against this list — it is purely
// declarative.
Peers []string
// SchemaHandler, when non-nil, is mounted at /parsec/schemas. The
// HTTP surface delegates to the supplied handler so the embedder
// can plug a schema.MemoryRegistry (or any other Registry impl)
// without parsec.go importing the schema package itself.
SchemaHandler http.Handler
// JWKSHandler, when non-nil, is mounted at /parsec/jwks.json. The
// handler is expected to serve the active KeyRing's asymmetric
// public keys as an RFC 7517 JWKS document. Embedders that only
// use HMAC signing should leave this nil — there is nothing to
// publish, and the 404 prevents probing.
JWKSHandler http.Handler
// TokenBrokerHandler, when non-nil, is mounted under /parsec
// (/parsec/token, /parsec/token/delegate, /parsec/revoke). The
// embedder constructs a tokenbroker.Broker, configures its
// Authenticator / Authorizer, and passes Broker.Handler() here.
TokenBrokerHandler http.Handler
// RevocationStore, when non-nil, is consulted on every private
// channel subscribe attempt. The subscribe authorizer checks the
// access token's JTI and the user's blanket revoke timestamp; a
// match denies the subscribe with PARSEC_AUTH_DENIED. Pair this
// with a tokenbroker.Broker so revoke RPCs from operators land
// somewhere both the broker and the subscribe path can read.
RevocationStore tokenbroker.RevocationStore
// TelemetryHandler, when non-nil, is mounted at /parsec/metrics
// and serves the aggregated JSON snapshot. The native /metrics
// Prometheus endpoint is unaffected.
TelemetryHandler http.Handler
// Cache, when non-nil, is the request-hash cache exposed to
// embedder code via Parsec.Cache(). Parsec itself does NOT
// consult this cache on the hot path — the field exists so
// embedders share one cache instance across the library, the
// telemetry source, and any sinks/handlers they wire. Leave
// nil to disable; pass cache.NewMemoryCache or cache.NewRedisCache
// to enable.
//
// When nil and RedisClient is set, parsec.New auto-builds a
// cache.RedisCache against the same client (sharing the
// connection pool). Pass an explicit cache.NoopCache instance
// to opt out of the auto-build.
Cache cache.Cache
}
Options configures a Parsec instance. All fields are optional.
func (Options) OIDCEnabled ¶
OIDCEnabled reports whether the OIDC bridge is configured. Convenience shorthand for the manifest layer.
type Parsec ¶
type Parsec struct {
// contains filtered or unexported fields
}
Parsec is the library facade. Construct with New, drive with Run, publish with Publish.
func New ¶
New constructs a Parsec instance. The broker is created but not started; call Run on the returned instance to boot the centrifuge Node and the sweeper goroutine.
func (*Parsec) AccessLogger ¶
AccessLogger returns the slog logger the HTTP surface should use for access logs. Falls back to Logger when nothing explicit was set.
func (*Parsec) AdminUIOptions ¶
func (p *Parsec) AdminUIOptions() AdminUIOptions
AdminUIOptions returns the embedded admin SPA configuration. Used by the HTTP surface to decide whether to mount the /admin/* routes.
func (*Parsec) Cache ¶ added in v0.3.0
Cache returns the configured request-hash cache, or nil when no cache was wired (the default). Embedders share this instance so the library, the telemetry source, and any sinks/handlers consult one view of cached state. See docs/src/ops/cache.md.
func (*Parsec) CacheBackend ¶ added in v0.3.0
CacheBackend reports the cache implementation in use: "" when no cache is wired, "memory" / "redis" / "noop" for the bundled impls, and "custom" for an embedder-supplied Cache. Surfaced in the manifest.
func (*Parsec) CheckPublishLimit ¶ added in v0.3.0
func (p *Parsec) CheckPublishLimit(ctx context.Context, subject string, channel channels.Name, override *ratelimit.Limit) (ratelimit.Decision, error)
CheckPublishLimit is CheckRateLimit specialised for the publish bucket with per-channel rule resolution: the channel's name is matched against the operator's PerChannelPublish rules and the most-specific match wins. When no rule matches, the global publish default applies. Per-rule and per-token-override are honored in that order — override beats the rule.
The bucket key namespaces channels: rule-matched calls use `publish-channel:<rule-raw>:<subject>`, default calls use `publish:<subject>` (unchanged). That keeps a hot channel from eating the global budget.
func (*Parsec) CheckRateLimit ¶
func (p *Parsec) CheckRateLimit(ctx context.Context, bucket, subject string, override *ratelimit.Limit) (ratelimit.Decision, error)
CheckRateLimit charges one event against bucket:subject and reports the decision. When no limiter is configured the call returns AllowDecisionUnlimited without touching state. When override is non-nil and tighter than the configured default, the override applies — surfacing per-token rate-limit claims.
func (*Parsec) CheckSubscribeLimit ¶ added in v0.3.0
func (p *Parsec) CheckSubscribeLimit(ctx context.Context, subject string, channel channels.Name, override *ratelimit.Limit) (ratelimit.Decision, error)
CheckSubscribeLimit is CheckRateLimit specialised for the subscribe bucket with per-channel rule resolution. The channel's name is matched against the operator's PerChannelSubscribe rules and the most-specific match wins; when no rule matches, the global subscribe default applies. override is honored when tighter (or when the default + matched rule are both unlimited).
Bucket keys mirror CheckPublishLimit: rule-matched calls use `subscribe-channel:<rule-raw>:<subject>`, default calls use `subscribe:<subject>`. Per-rule namespacing prevents a hot channel's subscribers from eating the global subscribe budget.
func (*Parsec) CompositeVerifier ¶
func (p *Parsec) CompositeVerifier() *auth.CompositeVerifier
CompositeVerifier returns the composed HMAC+OIDC verifier, or nil when OIDC is disabled. Surface code that wraps mgmt bearer validation should check for non-nil first and fall back to Verifier() when nil.
func (*Parsec) ConfigSource ¶
ConfigSource returns the path the TOML config was loaded from, or "" when no file was used (flag/env or embedded configuration).
func (*Parsec) CreatePrivate ¶
func (p *Parsec) CreatePrivate(subjectID, name string, ttl time.Duration, scopes []auth.Scope) (Credentials, error)
CreatePrivate mints a private channel and returns the access + refresh token pair. Pattern grants in scopes are stamped into both tokens; pass nil for "exact-match channel only".
func (*Parsec) DLQ ¶
DLQ returns the dead-letter queue. Never nil — when no DLQ is configured (and no Redis client is present) parsec.New constructs an in-memory MemoryDLQ.
func (*Parsec) DLQBackend ¶
DLQBackend reports "memory", "redis", or "custom" depending on which backend is wired. Exposed in the manifest.
func (*Parsec) GenerateKey ¶
GenerateKey mints a new HS256 key (joins the ring as verify-only) and persists if StateDir is configured.
func (*Parsec) GenerateKeyAlg ¶ added in v0.3.0
GenerateKeyAlg mints a new key of the requested algorithm. After generation: if the freshly-added key is asymmetric and the embedder did not wire an explicit JWKSHandler, parsec auto-installs one so the next /parsec/jwks.json hit picks the new public material up.
func (*Parsec) JWKSHandler ¶ added in v0.3.0
JWKSHandler returns the optional JWKS handler mounted at /parsec/jwks.json. Convenience: when Options.JWKSHandler is nil and the live ring carries at least one asymmetric key, parsec.New auto-wires auth.JWKSHandler against the ring — operators who add an Ed25519 key get a JWKS endpoint for free.
func (*Parsec) KeyRing ¶
KeyRing returns the live ring. Mutations go through the dedicated methods (GenerateKey / PromoteKey / RetireKey) so persistence stays in sync — surface code should not call ring.Promote directly.
func (*Parsec) KeyringPath ¶
KeyringPath returns the on-disk path of the keyring file, or "" if the instance runs with an ephemeral / programmatic ring.
func (*Parsec) KeyringStore ¶
func (p *Parsec) KeyringStore() auth.KeyRingStore
KeyringStore returns the configured KeyRingStore, or nil when the instance runs with an explicit/ephemeral ring. Surface code (the CLI `keys import` adapter) calls this to push an externally produced snapshot through the store so the watch event fires on every node.
func (*Parsec) Limiter ¶
Limiter returns the resolved rate-limit backend, or nil when no limiting is configured. Surface code calls this at request time.
func (*Parsec) Metrics ¶
Metrics returns the Prometheus collector bundle. Surface code (HTTP middleware, sink wrappers, broker hooks) reaches for this rather than constructing its own registry.
func (*Parsec) MetricsBearerToken ¶
MetricsBearerToken returns the configured bearer for the /metrics route. Empty means /metrics is unguarded.
func (*Parsec) OIDCEnabled ¶
OIDCEnabled reports whether an OIDC issuer is wired. Used by the manifest layer.
func (*Parsec) OIDCIssuer ¶
OIDCIssuer returns the configured OIDC issuer URL, or "" when OIDC is disabled. Used by the manifest layer.
func (*Parsec) OIDCVerifier ¶
func (p *Parsec) OIDCVerifier() *auth.OIDCVerifier
OIDCVerifier returns the OIDC verifier, or nil when OIDC is disabled. Exposed primarily for tests + the manifest.
func (*Parsec) OTLPEndpoint ¶
OTLPEndpoint returns the configured OTLP endpoint or "" if tracing is off.
func (*Parsec) OpenPublic ¶
OpenPublic creates or re-opens a public channel by parsed name. TTL of 0 uses the manager default. Fossil-delta encoding is off by default; enable it after the open call with Manager().SetDelta(name, true).
func (*Parsec) Peers ¶
Peers returns a defensive copy of the configured peer region URLs. Always non-nil-safe: returns nil when no peers were configured. The list is purely informational — parsec.New does no validation.
func (*Parsec) Persistence ¶
Persistence returns "redis" when the channel registry is Redis-backed, or "in-memory" otherwise. Exposed to manifests.
func (*Parsec) PromoteKey ¶
PromoteKey makes id the active signing key.
func (*Parsec) Publish ¶
func (p *Parsec) Publish(ctx context.Context, name string, data []byte) (broker.PublishResult, error)
Publish ships data to a managed channel.
func (*Parsec) PublishOrSink ¶
func (p *Parsec) PublishOrSink(ctx context.Context, name string, data []byte, sinkName string, to sinks.Recipient, msg sinks.Message) (bool, error)
PublishOrSink publishes to ch if there is at least one live subscriber, otherwise falls back to the named sink.
func (*Parsec) RateLimits ¶
func (p *Parsec) RateLimits() ratelimit.RateLimits
RateLimits returns the normalized default budgets. Exposed to manifest + service code so /manifest can advertise the configured ceilings.
func (*Parsec) RefreshAccess ¶
func (p *Parsec) RefreshAccess(refreshToken string) (RefreshResult, error)
RefreshAccess verifies refreshToken, enforces rotation policy via the RefreshStore, and mints a fresh access (and, when the token carries a JTI, a fresh refresh in the same family).
Rotation rules:
- Tokens without JTI are legacy: mint a new access only. The store is untouched.
- Tokens with JTI consult the store. A revoked family or an already-redeemed JTI returns PARSEC_AUTH_DENIED. A reused JTI additionally revokes the family so subsequent siblings fail even before the JTI check.
- On success, both tokens are reissued: the new refresh shares the old FID, a fresh JTI, and refresh TTL bounded by the channel TTL and MaxRefreshTTL.
func (*Parsec) RefreshAccessCtx ¶ added in v0.3.0
RefreshAccessCtx is RefreshAccess with an explicit context. The context is forwarded to the RefreshStore so Redis-backed stores pick up the caller's cancellation + deadline. Most callers should use RefreshAccess; this overload exists for the RPC adapter.
func (*Parsec) Region ¶
Region returns the configured region label, or "" when single-region (no label) mode is active. Surfaced in the manifest and used as a constant metric label by parsec.New.
func (*Parsec) ReloadKeys ¶
ReloadKeys re-reads the keyring from its backing store. Returns an error if no store is configured (i.e. explicit ring or ephemeral).
func (*Parsec) RevocationStore ¶ added in v0.3.0
func (p *Parsec) RevocationStore() tokenbroker.RevocationStore
RevocationStore returns the optional revocation store the subscribe authorizer consults on every private channel subscribe. Used by the manifest layer to surface the on/off state to operators.
func (*Parsec) Run ¶
Run starts the broker, the sweeper, the manager↔broker event bridge, and (when StateDir is set) the keyring file watcher. Blocks until ctx is done.
func (*Parsec) SchemaHandler ¶
SchemaHandler returns the optional handler mounted at /parsec/schemas, or nil when no schema registry was wired.
func (*Parsec) SinkRetryConfig ¶
func (p *Parsec) SinkRetryConfig() sinks.RetryConfig
SinkRetryConfig returns the normalized retry config used by PublishOrSink. Per-sink overrides are not reflected here — call Options().PerSinkRetry directly for that.
func (*Parsec) TelemetryHandler ¶
TelemetryHandler returns the optional aggregated /parsec/metrics handler, or nil when telemetry aggregation is not wired.
func (*Parsec) TokenBrokerHandler ¶
TokenBrokerHandler returns the optional handler mounted under /parsec (token, token/delegate, revoke), or nil when no broker was wired.
func (*Parsec) Tracer ¶
Tracer returns the active tracer. The default-off path returns a no-op tracer that never allocates.
func (*Parsec) TracerShutdown ¶
TracerShutdown flushes any buffered spans and stops the exporter. Safe to call when tracing is off (returns nil).
func (*Parsec) TrustedProxies ¶
TrustedProxies returns the proxy CIDR list as configured. Empty means X-Forwarded-For is ignored.
func (*Parsec) Verifier ¶
Verifier returns the HMAC token verifier. Surface code that needs to accept either HMAC or OIDC tokens should prefer CompositeVerifier when it is non-nil.
func (*Parsec) WebTransportOptions ¶
func (p *Parsec) WebTransportOptions() WebTransportOptions
WebTransportOptions returns the WT listener configuration. Used by the HTTP surface to decide whether to mount the h3 endpoint.
type RefreshResult ¶
type RefreshResult struct {
AccessToken string
AccessExpires time.Time
RefreshToken string
RefreshExpires time.Time
Rotated bool
}
RefreshResult is what RefreshAccess returns. The RefreshToken / RefreshExpires fields are populated on rotation — a token carrying a JTI yields a fresh refresh in the same family. Legacy tokens (no JTI) leave them zero-valued so older clients keep working.
type WebTransportOptions ¶
type WebTransportOptions struct {
// Addr is the UDP listen address for the QUIC/HTTP3 listener.
Addr string
// TLSCertFile + TLSKeyFile are the TLS cert pair. Required.
TLSCertFile string
TLSKeyFile string
// AllowedOrigins gates incoming WT requests by Origin header.
// Empty slice = allow all (dev mode).
AllowedOrigins []string
}
WebTransportOptions is re-exported from internal/server so embedders don't need to import the internal package for the WT config shape.
func (WebTransportOptions) Enabled ¶
func (o WebTransportOptions) Enabled() bool
Enabled reports whether the WT options describe an active listener.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package auth issues and verifies the HMAC-SHA256 JWTs that gate access to Parsec.
|
Package auth issues and verifies the HMAC-SHA256 JWTs that gate access to Parsec. |
|
Package broker wraps the github.com/centrifugal/centrifuge OSS library in the small surface Parsec actually needs: boot a Node, publish to a named channel, authorize subscribes against the Parsec channel grammar, and expose presence + history for the management surface.
|
Package broker wraps the github.com/centrifugal/centrifuge OSS library in the small surface Parsec actually needs: boot a Node, publish to a named channel, authorize subscribes against the Parsec channel grammar, and expose presence + history for the management surface. |
|
Package cache provides request-hash caching primitives for Parsec.
|
Package cache provides request-hash caching primitives for Parsec. |
|
Package channels owns the channel naming contract and the channel manager (public / private namespaces, TTL bookkeeping, expiry).
|
Package channels owns the channel naming contract and the channel manager (public / private namespaces, TTL bookkeeping, expiry). |
|
Package client is the envelope-aware Go client for Parsec.
|
Package client is the envelope-aware Go client for Parsec. |
|
cmd
|
|
|
parsec
command
Package main is the entry point for the parsec CLI binary.
|
Package main is the entry point for the parsec CLI binary. |
|
parsec-gen
command
Package main is the parsec-gen command: it reads a Parsec schema registry snapshot (either from a running registry over HTTP or from a JSON file on disk) and emits typed Go and TypeScript bindings for every registered channel pattern.
|
Package main is the parsec-gen command: it reads a Parsec schema registry snapshot (either from a running registry over HTTP or from a JSON file on disk) and emits typed Go and TypeScript bindings for every registered channel pattern. |
|
parsec-keys-sync
command
Package main is the parsec-keys-sync daemon: a tiny pub/sub bridge that mirrors Parsec keyring rotation events from one Redis (the source region) to N target Redis instances (the peer regions).
|
Package main is the parsec-keys-sync daemon: a tiny pub/sub bridge that mirrors Parsec keyring rotation events from one Redis (the source region) to N target Redis instances (the peer regions). |
|
Package descriptor provides the self-describing manifest envelope used by every surface (CLI --json, Twirp Manifest RPC).
|
Package descriptor provides the self-describing manifest envelope used by every surface (CLI --json, Twirp Manifest RPC). |
|
Package envelope is the wire-format contract every Parsec subscriber and publisher uses.
|
Package envelope is the wire-format contract every Parsec subscriber and publisher uses. |
|
Package errors holds the typed Code system used across Parsec.
|
Package errors holds the typed Code system used across Parsec. |
|
examples
|
|
|
browser
command
Browser end-to-end demo.
|
Browser end-to-end demo. |
|
embedded
command
Embedded shows how a Go service uses parsec as a library.
|
Embedded shows how a Go service uses parsec as a library. |
|
notify-or-email
command
notify-or-email demonstrates PublishOrSink: if the user's browser session is still subscribed, ship to the channel; otherwise fall back to email.
|
notify-or-email demonstrates PublishOrSink: if the user's browser session is still subscribed, ship to the channel; otherwise fall back to email. |
|
playground
command
Command playground boots an in-memory parsec instance and serves an interactive browser UI that exercises publish, subscribe, token issuance, sinks, DLQ, rate limits, and manifest inspection.
|
Command playground boots an in-memory parsec instance and serves an interactive browser UI that exercises publish, subscribe, token issuance, sinks, DLQ, rate limits, and manifest inspection. |
|
scenarios/agent-analysis
command
Scenario 2 from the parsec brief:
|
Scenario 2 from the parsec brief: |
|
scenarios/download-notify
command
Scenario 1 from the parsec brief:
|
Scenario 1 from the parsec brief: |
|
scenarios/feedback-flag
command
Scenario 3 from the parsec brief:
|
Scenario 3 from the parsec brief: |
|
scenarios/heartbeat
command
Scenario 4 from the parsec brief:
|
Scenario 4 from the parsec brief: |
|
scenarios/nightly-report
command
Scenario 5 from the parsec brief:
|
Scenario 5 from the parsec brief: |
|
scenarios/scoreboard
command
Scenario 7 from the parsec brief:
|
Scenario 7 from the parsec brief: |
|
internal
|
|
|
admin
Package admin embeds the parsec administrative single-page application.
|
Package admin embeds the parsec administrative single-page application. |
|
cli
Package cli holds the urfave/cli/v3 command definitions for the parsec binary.
|
Package cli holds the urfave/cli/v3 command definitions for the parsec binary. |
|
codegen
Package codegen reads a schema-registry snapshot and emits typed Go and TypeScript bindings for each registered ChannelPattern.
|
Package codegen reads a schema-registry snapshot and emits typed Go and TypeScript bindings for each registered ChannelPattern. |
|
config
Package config defines the on-disk configuration schema for `parsec serve`.
|
Package config defines the on-disk configuration schema for `parsec serve`. |
|
metrics
Package metrics centralizes the Prometheus collectors Parsec exposes.
|
Package metrics centralizes the Prometheus collectors Parsec exposes. |
|
rpcclient
Package rpcclient is the CLI's adapter onto the generated Twirp JSON client.
|
Package rpcclient is the CLI's adapter onto the generated Twirp JSON client. |
|
server
Package server mounts the parsec HTTP surface: the centrifuge websocket transport, the rpc Twirp-JSON handler, an SSE fallback for the CLI `subscribe` probe, and /healthz.
|
Package server mounts the parsec HTTP surface: the centrifuge websocket transport, the rpc Twirp-JSON handler, an SSE fallback for the CLI `subscribe` probe, and /healthz. |
|
testutil
Package testutil contains shared scaffolding for Parsec test packages: boot a real Parsec instance with an ephemeral key, wrap it in a Service, and (optionally) expose the composed HTTP surface via httptest.Server.
|
Package testutil contains shared scaffolding for Parsec test packages: boot a real Parsec instance with an ephemeral key, wrap it in a Service, and (optionally) expose the composed HTTP surface via httptest.Server. |
|
tracing
Package tracing wraps the OpenTelemetry SDK into a small surface Parsec actually uses: a tracer + a shutdown hook.
|
Package tracing wraps the OpenTelemetry SDK into a small surface Parsec actually uses: a tracer + a shutdown hook. |
|
Package parsectest provides test helpers for code that embeds or integrates against the parsec library.
|
Package parsectest provides test helpers for code that embeds or integrates against the parsec library. |
|
Package ratelimit gates Parsec's publish/subscribe/refresh-token paths behind configurable per-key budgets.
|
Package ratelimit gates Parsec's publish/subscribe/refresh-token paths behind configurable per-key budgets. |
|
Package rpc is the parsec management RPC surface.
|
Package rpc is the parsec management RPC surface. |
|
Package schema is the Parsec schema registry.
|
Package schema is the Parsec schema registry. |
|
Package service implements the surface-agnostic business logic that the CLI and Twirp layers all call into.
|
Package service implements the surface-agnostic business logic that the CLI and Twirp layers all call into. |
|
Classification helpers for the sink retry loop.
|
Classification helpers for the sink retry loop. |
|
email
Package email is a thin SMTP sink.
|
Package email is a thin SMTP sink. |
|
slack
Package slack is a Slack incoming-webhook sink.
|
Package slack is a Slack incoming-webhook sink. |
|
webhook
Package webhook posts an arbitrary JSON envelope to a configured URL.
|
Package webhook posts an arbitrary JSON envelope to a configured URL. |
|
Package telemetry exposes the aggregated /parsec/metrics view that the upgrade spec calls for.
|
Package telemetry exposes the aggregated /parsec/metrics view that the upgrade spec calls for. |
|
Package tokenbroker is the policy point for issuing Parsec / Centrifugo connection tokens.
|
Package tokenbroker is the policy point for issuing Parsec / Centrifugo connection tokens. |