Documentation
¶
Index ¶
- Constants
- Variables
- func Allows(entitlements Entitlements, feature Feature) bool
- func IsRecognizedFeature(key string) bool
- func KeysURLFromEnvironment() (string, error)
- func Require(entitlements Entitlements, feature Feature) error
- func RevocationsURL(keysURL string) string
- type DatabaseKeyListCache
- type DatabaseRevocationListCache
- type DatabaseSource
- type Edition
- type Entitlements
- type Feature
- type FileSource
- type KeyList
- type KeyListCache
- type KeySet
- type KeyStore
- type KeySync
- func (k *KeySync) Install(ctx context.Context, raw []byte) (*KeyList, error)
- func (k *KeySync) Reload(ctx context.Context) (bool, error)
- func (k *KeySync) Start(ctx context.Context, onChange func())
- func (k *KeySync) Status() KeySyncStatus
- func (k *KeySync) Sync(ctx context.Context) (bool, error)
- func (k *KeySync) SyncOnDemand(ctx context.Context) (bool, error)
- type KeySyncState
- type KeySyncStatus
- type License
- type PublicKeys
- type Reason
- type RevocationList
- type RevocationListCache
- type RevocationSync
- type Service
- func (s *Service) Install(ctx context.Context, raw []byte, installedBy uuid.UUID) (Status, error)
- func (s *Service) InstallKeyList(ctx context.Context, raw []byte) error
- func (s *Service) IsEntitled(feature Feature) bool
- func (s *Service) Refresh(ctx context.Context) error
- func (s *Service) Remove(ctx context.Context, removedBy uuid.UUID) (Status, error)
- func (s *Service) Start(ctx context.Context)
- func (s *Service) Status() Status
- func (s *Service) TrustedKeys() (KeySyncStatus, bool)
- type ServiceOption
- type Source
- type SourceKind
- type State
- type Status
- type Validity
- type VerificationError
- type Verifier
- type WritableSource
Constants ¶
const ( KeyListType = "superplane-license-keys+jwt" KeyListAudience = "superplane-license-keys" // MaxKeyListBytes bounds every key list input before any decoding. MaxKeyListBytes = 64 * 1024 )
const ( // KeysURLEnv overrides where SuperPlane downloads the license key list. // The value "none" turns downloads off, for example without network // access. KeysURLEnv = "SUPERPLANE_LICENSE_KEYS_URL" DefaultKeysURL = "https://licensing.superplane.com/.well-known/license-keys.jws" KeySyncInterval = 6 * time.Hour )
const ( RevocationListType = "superplane-license-revocations+jwt" RevocationListAudience = "superplane-license-revocations" // MaxRevocationListBytes bounds every revocation list before decoding. MaxRevocationListBytes = 256 * 1024 )
const ( ExpectedIssuer = "https://licensing.superplane.com" ExpectedAudience = "superplane-self-hosted" TokenType = "superplane-license+jwt" SigningAlgorithm = "ES256" // MaxLicenseBytes bounds every license input before any decoding. MaxLicenseBytes = 16 * 1024 ClockSkew = 5 * time.Minute )
const LicensePathEnv = "SUPERPLANE_LICENSE_PATH"
LicensePathEnv configures a license file, for example a mounted Kubernetes secret. When it is set, the file is the only license source.
const RefreshInterval = 30 * time.Second
RefreshInterval is how often every replica reloads the license, so that install, replace, and remove operations reach all replicas.
const RevocationSyncInterval = 5 * time.Minute
Variables ¶
var ErrInvalidKeyList = errors.New("invalid license key list")
ErrInvalidKeyList is returned for every key list that SuperPlane must not trust. It does not say why, so that callers cannot leak details.
var ErrInvalidRevocationList = errors.New("invalid license revocation list")
ErrInvalidRevocationList is returned for every revocation list that SuperPlane must not trust. It does not say why.
var ErrKeyListDowngrade = errors.New("license key list is older than the trusted list")
ErrKeyListDowngrade is returned for a key list that is older than the trusted one. Accepting it could restore a key that the issuer removed.
ErrKeySyncUnavailable is returned when the service does not manage keys.
var ErrManagedByFile = errors.New("the license is managed by the installation configuration")
ErrManagedByFile is returned when an administrator tries to change a license that comes from SUPERPLANE_LICENSE_PATH.
var ErrNotInstalled = errors.New("no license installed")
ErrNotInstalled tells the service that a source has no license. It is not a verification failure.
var ErrNotLicensed = errors.New("this action requires a SuperPlane Enterprise license")
ErrNotLicensed reports that the installation license does not grant an Enterprise feature.
var ErrRevocationListDowngrade = errors.New("license revocation list is older than the trusted list")
ErrRevocationListDowngrade is returned for a list older than the trusted one. Accepting it could drop a revocation the issuer already published.
Functions ¶
func Allows ¶
func Allows(entitlements Entitlements, feature Feature) bool
Allows reports whether entitlements grant a feature. A nil value grants nothing.
func IsRecognizedFeature ¶
IsRecognizedFeature reports whether this SuperPlane version knows the key. Unknown keys in a license never grant access.
func KeysURLFromEnvironment ¶
KeysURLFromEnvironment returns the key list URL, or an empty string when downloads are off.
func Require ¶
func Require(entitlements Entitlements, feature Feature) error
Require returns ErrNotLicensed unless the entitlements grant the feature.
func RevocationsURL ¶
RevocationsURL returns the revocation list URL for a key-list URL. An empty key-list URL, which disables key downloads, also disables this download.
Types ¶
type DatabaseKeyListCache ¶
type DatabaseKeyListCache struct{}
DatabaseKeyListCache shares the key list between replicas.
type DatabaseRevocationListCache ¶
type DatabaseRevocationListCache struct{}
DatabaseRevocationListCache shares the revocation list between replicas.
func (DatabaseRevocationListCache) Load ¶
func (DatabaseRevocationListCache) Load(ctx context.Context) (string, error)
func (DatabaseRevocationListCache) Save ¶
func (DatabaseRevocationListCache) Save(ctx context.Context, list *RevocationList) error
type DatabaseSource ¶
type DatabaseSource struct {
// contains filtered or unexported fields
}
DatabaseSource stores the license encrypted at rest with the installation encryptor.
func NewDatabaseSource ¶
func NewDatabaseSource(encryptor crypto.Encryptor) *DatabaseSource
func (*DatabaseSource) Kind ¶
func (d *DatabaseSource) Kind() SourceKind
type Entitlements ¶
Entitlements answers whether an Enterprise feature is available now.
var Community Entitlements = communityEntitlements{}
Community grants no Enterprise features. Use it when no license service is configured so that Enterprise checks fail closed.
type Feature ¶
type Feature string
Feature is an Enterprise capability key granted by a license. Keys are immutable and compared exactly.
func RecognizedFeatures ¶
func RecognizedFeatures() []Feature
RecognizedFeatures returns every Enterprise feature that this SuperPlane version knows.
type FileSource ¶
type FileSource struct {
// contains filtered or unexported fields
}
func NewFileSource ¶
func NewFileSource(path string) *FileSource
func (*FileSource) Kind ¶
func (f *FileSource) Kind() SourceKind
type KeyListCache ¶
type KeyListCache interface {
Load(ctx context.Context) (string, error)
Save(ctx context.Context, list *KeyList) error
}
KeyListCache stores the newest key list for every replica. Load returns an empty document when nothing is cached.
type KeySet ¶
type KeySet struct {
// contains filtered or unexported fields
}
KeySet holds public keys that verify signatures.
func ParseKeySet ¶
ParseKeySet parses a JWKS document and rejects any key that is not an ES256 P-256 signing key with a unique, well-formed key ID.
func ParseOptionalKeySet ¶
ParseOptionalKeySet is ParseKeySet, but it accepts a key set without keys.
func ProductionRootKeySet ¶
type KeyStore ¶
type KeyStore struct {
// contains filtered or unexported fields
}
KeyStore holds the license signing keys that SuperPlane trusts now. Only a key list signed by a root key can change them, and the version only grows.
func NewKeyStore ¶
NewKeyStore trusts the bootstrap key list when it is not empty. The extra keys are trusted in addition to every key list; only development builds pass them.
func TrustedKeyStore ¶
TrustedKeyStore returns the keys that verify licenses in this binary. Release builds trust only key lists signed by the embedded root keys.
type KeySync ¶
type KeySync struct {
// contains filtered or unexported fields
}
KeySync keeps the trusted license signing keys current. It downloads the key list, verifies it with the root keys, and shares it through the cache.
func NewKeySync ¶
func NewKeySync(store *KeyStore, cache KeyListCache, keysURL string) *KeySync
NewKeySync downloads from keysURL. An empty keysURL turns downloads off.
func (*KeySync) Install ¶
Install trusts a key list that an administrator supplies, for example without network access.
func (*KeySync) Reload ¶
Reload trusts the cached key list when it is newer. Another replica may have saved it. When the cache is older, Reload saves the trusted list, which repairs an earlier failed cache write. It reports whether the trusted keys changed.
func (*KeySync) Start ¶
Start syncs once and then every KeySyncInterval until the context ends. It calls onChange after the trusted keys change.
func (*KeySync) Status ¶
func (k *KeySync) Status() KeySyncStatus
type KeySyncState ¶
type KeySyncState string
const ( KeySyncDisabled KeySyncState = "disabled" KeySyncSyncing KeySyncState = "syncing" KeySyncSynced KeySyncState = "synced" KeySyncFailed KeySyncState = "failed" )
type KeySyncStatus ¶
type KeySyncStatus struct {
State KeySyncState
Version int64
SyncedAt *time.Time
}
KeySyncStatus describes the trusted key list. Version is zero when no key list is trusted.
type License ¶
type License struct {
ID uuid.UUID
CustomerID uuid.UUID
KeyID string
Issuer string
Edition Edition
// Features contains only keys that this SuperPlane version recognizes.
Features []Feature
IssuedAt time.Time
ValidFrom time.Time
ExpiresAt time.Time
}
License is the trusted result of a successful signature and claims verification. It never contains the raw artifact.
func (*License) HasFeature ¶
type PublicKeys ¶
PublicKeys finds the public key for a key ID.
type Reason ¶
type Reason string
Reason is a safe failure category. It never contains license content or cryptographic details.
const ( ReasonMalformed Reason = "malformed" ReasonUnsupportedAlgorithm Reason = "unsupported_algorithm" ReasonUnknownKey Reason = "unknown_key" ReasonInvalidSignature Reason = "invalid_signature" ReasonInvalidClaims Reason = "invalid_claims" ReasonExpired Reason = "expired" ReasonNotYetValid Reason = "not_yet_valid" ReasonRevoked Reason = "revoked" ReasonUnreadable Reason = "unreadable" )
type RevocationList ¶
type RevocationList struct {
Version int64
IssuedAt time.Time
Document string
// contains filtered or unexported fields
}
RevocationList is a verified, root-signed set of revoked license ids.
func VerifyRevocationList ¶
func VerifyRevocationList(raw []byte, roots *KeySet) (*RevocationList, error)
VerifyRevocationList verifies a revocation list signed by one of the root keys. It does not replace an older trusted list; callers compare versions.
type RevocationListCache ¶
type RevocationListCache interface {
Load(ctx context.Context) (string, error)
Save(ctx context.Context, list *RevocationList) error
}
RevocationListCache stores the newest revocation list for every replica. Load returns an empty document when nothing is cached.
type RevocationSync ¶
type RevocationSync struct {
// contains filtered or unexported fields
}
RevocationSync downloads the revocation list and keeps the last list that verified. A failed download does not change that list.
func NewRevocationSync ¶
func NewRevocationSync(roots *KeySet, cache RevocationListCache, revocationsURL string) *RevocationSync
NewRevocationSync downloads from revocationsURL. An empty URL turns downloads off.
func (*RevocationSync) Contains ¶
func (k *RevocationSync) Contains(id uuid.UUID) bool
Contains reports whether the last verified list names the license id. No verified list names nothing.
func (*RevocationSync) Reload ¶
func (k *RevocationSync) Reload(ctx context.Context) (bool, error)
Reload trusts the cached list when it is newer. Another replica may have saved it. When the cache is older, Reload saves the trusted list.
func (*RevocationSync) Start ¶
func (k *RevocationSync) Start(ctx context.Context)
Start syncs once and then every RevocationSyncInterval until the context ends.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func NewService(verifier *Verifier, source Source, options ...ServiceOption) *Service
func (*Service) Install ¶
Install verifies a license and stores it. It accepts only a license that is valid now, so an installation never replaces a working license with one that grants nothing.
func (*Service) InstallKeyList ¶
InstallKeyList trusts a key list that an administrator uploads and then reloads the license, which may use a key from the list.
func (*Service) IsEntitled ¶
func (*Service) Refresh ¶
Refresh reloads the trusted keys and the license. A temporary database error keeps the last known state instead of removing Enterprise access.
func (*Service) Start ¶
Start loads the license once and then refreshes it in the background until the context ends.
func (*Service) TrustedKeys ¶
func (s *Service) TrustedKeys() (KeySyncStatus, bool)
TrustedKeys reports the trusted key list. It returns false when the service does not sync keys.
type ServiceOption ¶
type ServiceOption func(*Service)
func WithKeySync ¶
func WithKeySync(keySync *KeySync) ServiceOption
WithKeySync keeps the trusted signing keys current while the service runs.
func WithRevocationSync ¶
func WithRevocationSync(revocations *RevocationSync) ServiceOption
WithRevocationSync keeps the revoked-license list current while the service runs.
type Source ¶
type Source interface {
Kind() SourceKind
Read(ctx context.Context) ([]byte, error)
}
Source supplies a raw license artifact.
func SourceFromEnvironment ¶
SourceFromEnvironment selects the single authoritative license source. A configured license file wins over the database. A configured but invalid file does not fall back to the database.
type SourceKind ¶
type SourceKind string
const ( SourceNone SourceKind = "none" SourceFile SourceKind = "file" SourceDatabase SourceKind = "database" )
type Status ¶
type Status struct {
Edition Edition
Source SourceKind
State State
Reason Reason
License *License
Writable bool
}
Status is the safe license state. It never contains the raw license.
func (Status) IsEntitled ¶
type VerificationError ¶
type VerificationError struct {
Reason Reason
}
func (*VerificationError) Error ¶
func (e *VerificationError) Error() string
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier checks license signatures and claims offline against trusted public keys. It does not check the validity window; callers use License.ValidityAt so an expired license can still be reported.
func NewVerifier ¶
func NewVerifier(keys PublicKeys) *Verifier
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package devlicense grants every Enterprise feature to the development server.
|
Package devlicense grants every Enterprise feature to the development server. |
|
Package licensingtest signs licenses with ephemeral keys for tests.
|
Package licensingtest signs licenses with ephemeral keys for tests. |