Documentation
¶
Overview ¶
Package license is the OSS base of the Versus license shim.
It reads a signed license token from the LICENSE_KEY environment variable and validates it OFFLINE against an embedded Ed25519 public key. There is no phone-home and no outbound network call — validation is pure local crypto, so an air-gapped deployment validates exactly like a connected one.
Two modes:
- community — LICENSE_KEY is absent or empty. IsEnterpriseEnabled() returns false and Features() is empty. This is the default for every OSS deployment and changes no behaviour.
- enterprise — LICENSE_KEY holds a valid, unexpired token signed by the Versus license private key. IsEnterpriseEnabled() returns true and Features() lists the entitlements baked into the token.
The token format is a compact EdDSA JWT (header.payload.signature, all base64url). The private signing key is held OUTSIDE this repository by the Versus license service; only the public verification key is embedded below, so the OSS tree can verify but never mint licenses.
Index ¶
Constants ¶
const CacheEnvVar = "LICENSE_CACHE_PATH"
CacheEnvVar is the environment variable holding the path to the on-disk lease cache. When set, Load() prefers a valid cached token over the LICENSE_KEY seed, and a long-running process that renews its lease can persist the fresh token here so it survives a restart. The cache is pure local file IO — no network, no enterprise coupling — so the OSS tree stays offline-only. An empty value disables the cache entirely.
const EnvVar = "LICENSE_KEY"
EnvVar is the environment variable the license token is read from.
Variables ¶
var ( // ErrNoLicense indicates LICENSE_KEY was absent/empty — community mode. ErrNoLicense = errors.New("license: no LICENSE_KEY set (community mode)") // ErrMalformed indicates the token is not a well-formed EdDSA JWT. ErrMalformed = errors.New("license: malformed token") // ErrBadSignature indicates the signature did not verify against the // embedded public key. ErrBadSignature = errors.New("license: signature verification failed") // ErrExpired indicates the token's exp claim is in the past. ErrExpired = errors.New("license: token expired") )
Functions ¶
func WriteCache ¶
WriteCache atomically persists token to path with 0600 permissions so a renewed lease survives a restart (Load prefers it over the LICENSE_KEY seed). It is pure local file IO — no network — keeping the OSS tree offline-only. An empty path is a no-op (caching disabled). The write goes through a temp file + rename so a crash mid-write can never leave a truncated lease on disk.
Types ¶
type Claims ¶
type Claims struct {
// Org is the organization the license was issued to.
Org string `json:"org,omitempty"`
// Subject mirrors the JWT "sub" claim (customer / account id).
Subject string `json:"sub,omitempty"`
// FeatureList is the set of enabled enterprise entitlements.
FeatureList []string `json:"features,omitempty"`
// IssuedAt is the JWT "iat" claim (unix seconds).
IssuedAt int64 `json:"iat,omitempty"`
// ExpiresAt is the JWT "exp" claim (unix seconds). 0 means no expiry.
ExpiresAt int64 `json:"exp,omitempty"`
}
Claims is the validated payload of a license token. Only the fields Versus understands are decoded; unknown fields are ignored.
type License ¶
type License struct {
// contains filtered or unexported fields
}
License is the result of evaluating LICENSE_KEY. The zero value is a valid community license (no enterprise features).
A License is safe for concurrent use: every read goes through an RWMutex and Reload swaps the validated claims atomically under the write lock, so a long-running process can adopt a renewed lease without a restart while other goroutines keep calling HasFeature/IsEnterpriseEnabled. Because it carries a mutex a License must never be copied after first use — always pass *License.
func Load ¶
Load reads the license token and validates it OFFLINE. A cached token at LICENSE_CACHE_PATH (if set and valid) takes precedence over the LICENSE_KEY environment seed, so a lease renewed by a long-running process survives a restart; otherwise the LICENSE_KEY seed is used. A missing/empty token returns a community License with ErrNoLicense (callers usually ignore the error and run in community mode). A present-but-invalid token returns a community License together with the validation error so the caller can log/refuse, never silently granting enterprise on a bad token.
func Parse ¶
Parse validates an explicit token string against the embedded public key. Useful for tooling and tests that do not want to touch the environment.
func (*License) Claims ¶
Claims returns a copy of the validated license claims. Zero value in community mode or once the lease has expired.
func (*License) ExpiresAt ¶
ExpiresAt returns the current lease's expiry as a time.Time, or the zero time when there is no expiry (community mode, or a never-expiring token). The renewer reads it to decide how much lease time remains before it must refresh.
func (*License) Features ¶
Features returns the entitlements granted by the license. Empty in community mode or once the lease has expired. The returned slice is a copy callers may mutate freely.
func (*License) HasFeature ¶
HasFeature reports whether a specific entitlement is granted by an in-force lease. False in community mode and once the lease has expired.
func (*License) IsEnterpriseEnabled ¶
IsEnterpriseEnabled reports whether a valid, unexpired enterprise license is in force. Always false in community mode, and false once the current lease's exp has passed without a renewal.
func (*License) Raw ¶
Raw returns the original compact token this license currently holds, or "" in community mode. The enterprise renewer presents it as the Bearer credential when asking the platform for a fresh lease.
func (*License) Reload ¶
Reload verifies newToken OFFLINE against the embedded public key and, on success, atomically swaps the in-memory claims so a long-running process adopts a renewed lease without a restart. On any verification error the existing claims are retained unchanged and the error is returned — a bad or foreign-signed token can never downgrade or hijack a live license. It is pure local crypto: it verifies and swaps, it never fetches anything.