You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Update kotskinds dependency to support v1beta2 License API
Updates kotskinds from v0.0.0-20230724164735-f83482cc9cfe to
v0.0.0-20251023161058-b6489d3d51c5 to gain access to the new
v1beta2 License API. This version includes both v1beta1 and v1beta2
license types, allowing the SDK to support both API versions during
a gradual migration period.
This is the first step toward supporting the new v1beta2 License API
while maintaining backward compatibility with existing v1beta1 licenses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Add LicenseWrapper type to abstract v1beta1/v1beta2 differences
Introduces a new LicenseWrapper type that can hold either a v1beta1 or
v1beta2 License object, providing a unified interface to access common
license fields regardless of the API version.
The wrapper includes:
- Version detection methods (IsV1, IsV2)
- Accessor methods for all common license fields (AppSlug, LicenseID,
CustomerName, etc.)
- Support for all boolean feature flags (IsAirgapSupported,
IsGitOpsSupported, etc.)
This abstraction allows the SDK to work with both license versions
transparently, eliminating the need for version checks throughout
the codebase. The wrapper always has exactly one field populated
(either V1 or V2), never both.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Update license loading and storage to use LicenseWrapper
Modifies LoadLicenseFromBytes to detect and parse both v1beta1 and
v1beta2 license formats, returning a LicenseWrapper that encapsulates
the appropriate version. The loader now accepts both API versions and
creates the correct wrapper type based on the detected GVK.
Updates the Store interface and InMemoryStore implementation to use
LicenseWrapper instead of the concrete v1beta1.License type. This
enables the SDK to store and retrieve licenses of either version
transparently.
Key changes:
- LoadLicenseFromBytes returns LicenseWrapper instead of *v1beta1.License
- Store interface methods accept/return LicenseWrapper
- InMemoryStore properly deep copies the correct license version
- Uses wrapper accessor methods (GetAppSlug, GetLicenseType) instead
of direct field access
This completes the core infrastructure needed to support both license
API versions throughout the SDK while maintaining a clean, version-
agnostic API surface.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Adds SHA-256 signature verification for v1beta2 licenses
Refactors signature verification to support both v1beta1 (MD5) and v1beta2 (SHA-256) licenses:
- Refactors VerifySignature() to accept LicenseWrapper and dispatch to version-specific verification
- Adds verifyV1Signature() for backward-compatible MD5 verification of v1beta1 licenses
- Adds verifyV2Signature() for SHA-256 verification of v1beta2 licenses
- Implements VerifySHA256() helper function using RSA-PSS with SHA-256 hashing
This enables the SDK to verify v1beta2 licenses using the more secure SHA-256 algorithm instead of MD5, while maintaining full backward compatibility for existing v1beta1 licenses.
[Phase 3 of v1beta2 license support]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Refactor codebase to use LicenseWrapper throughout
Updates all code to use the LicenseWrapper type instead of direct kotsv1beta1.License references. This completes the integration of the abstraction layer that supports both v1beta1 and v1beta2 license APIs.
Changes include:
- Update function signatures in pkg/license/, pkg/report/, pkg/handlers/, pkg/integration/, pkg/apiserver/, and pkg/upstream/ to accept LicenseWrapper
- Replace direct license.Spec.* accesses with wrapper getter methods
- Update imports to use licensetypes package
- Modify LicenseInfo struct to support both v1 and v2 entitlements natively
- Fix tests to construct and use LicenseWrapper pattern
- Update mock store to work with LicenseWrapper
This refactoring maintains backward compatibility with v1beta1 licenses while enabling future v1beta2 license support through the wrapper abstraction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Updates pact contract tests to use LicenseWrapper
Refactors pact test files to use the LicenseWrapper type instead of raw
kotsv1beta1.License pointers, ensuring the contract tests match the new
LicenseWrapper-based API signatures introduced in the license abstraction layer.
Changes include:
- Wrapping v1beta1.License instances in LicenseWrapper{V1: ...} in test setup
- Updating mock store expectations to return LicenseWrapper types
- Adding licensetypes import to all affected pact test files
This maintains pact contract compatibility while supporting both v1beta1 and
v1beta2 license APIs through the abstraction layer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Update v1beta2 license signature handling to match backend
Changes:
- Update InnerSignature struct to support dual-algorithm signatures
(v1beta1 uses MD5, v1beta2 uses SHA-256)
- Change v1beta2.License field from Signature256 to Signature
- Update v1beta2 verification to use V2KeySignature and V2LicenseSignature
- Add complete field-by-field validation for v1beta2 licenses
- Add entitlement signature verification for both v1beta1 and v1beta2
- Add GetV2AppPublicKey helper function for v1beta2 entitlements
- Update kotskinds to latest version from main
The SDK now correctly unmarshals signatures from vandoor's
dual-algorithm format where both MD5 and SHA-256 signatures
are present in the same inner signature structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Fix entitlement signature verification to match vandoor format
Vandoor signs entitlement values using fmt.Sprint(), not JSON marshaling.
Changed verification to use fmt.Sprint() to match vandoor's signing format.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Update kotskinds dependency to get ValidateLicense methods
Updates github.com/replicatedhq/kotskinds from v0.0.0-20251024162531-2174a5b85a4d to v0.0.0-20251024204505-044aa5d007d5 to get the ValidateLicense() methods for both v1beta1 and v1beta2 licenses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Migrate license validation to use kotskinds ValidateLicense
Replaces custom crypto implementation with kotskinds' built-in ValidateLicense() method for both v1beta1 and v1beta2 licenses. This removes approximately 493 lines of custom RSA signature verification, license field validation, and entitlement signature checking code.
The ValidateLicense() method handles:
- MD5 signature verification for v1beta1 licenses
- SHA-256 signature verification for v1beta2 licenses
- License field integrity checks
- Entitlement signature validation
- Old and new signature format support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Bump chart version to 1.10.0
Updates chart version and appVersion from 1.0.0 to 1.10.0 to reflect license validation improvements.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Restores version placeholder
* Add v2 signature field to LicenseFieldSignature for v1beta2 support
The LicenseFieldSignature struct was only capturing v1 (MD5) signatures,
causing v2 (SHA-256) signatures from v1beta2 licenses to be discarded
during JSON unmarshaling. This resulted in empty signature objects when
calling the /license/fields endpoint with v1beta2 licenses.
Updated LicenseFieldSignature to include both v1 and v2 fields to support
signature validation for both v1beta1 and v1beta2 license formats.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Migrate replicated-sdk to use kotskinds/pkg/licensewrapper
This commit completes Phase 2 of the LicenseWrapper consolidation by migrating
replicated-sdk to use the shared licensewrapper package from kotskinds instead
of maintaining its own duplicate implementation.
Changes:
- Updated go.mod to reference kotskinds with pkg/licensewrapper support
- Removed local pkg/license/types/license_wrapper.go (18 methods)
- Updated all imports from local licensetypes.LicenseWrapper to kotskinds licensewrapper.LicenseWrapper
- Simplified pkg/license/util.go to wrap kotskinds loader functions
- Regenerated mock store to reflect new types
- Updated 15 files across the codebase:
- pkg/store (store_interface.go, memory_store.go, mock/mock_store.go)
- pkg/license (license.go, signature.go, util.go)
- pkg/report (instance.go, util.go)
- pkg/integration, pkg/upstream, pkg/handlers, pkg/apiserver
All tests pass and signature validation works correctly using kotskinds ValidateLicense methods.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Update kotskinds dependency to commit 174e89c9 for EntitlementFieldWrapper
Updates kotskinds from b7dd48f3cb2b to 174e89c93554 (commit 174e89c9).
This brings in the merged PR #44 from kotskinds main branch which includes:
- EntitlementFieldWrapper type for version-agnostic entitlement access
- GetEntitlements() method returning wrapped entitlements
- Accessor methods: GetTitle(), GetDescription(), GetValue(), GetValueType(),
IsHidden(), GetSignature()
This enables replicated-sdk to use EntitlementFieldWrapper to simplify
entitlement access and eliminate version-specific conditional logic.
Related: kotskinds PR #44
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Refactor LicenseIsExpired() to use EntitlementFieldWrapper
Replaces duplicated version-specific conditional logic with unified
GetEntitlements() access from kotskinds EntitlementFieldWrapper.
Changes:
- Replace if wrapper.V1/V2 != nil blocks with single GetEntitlements() call
- Use ent.GetValueType() instead of direct val.ValueType access
- Use ent.GetValue().StrVal instead of direct val.Value.StrVal access
- Eliminates 14 lines of duplicated code (36 lines -> 24 lines)
Benefits:
- Single code path for all license versions
- Version-agnostic entitlement access
- Forward-compatible with v1beta3+
- More maintainable and easier to understand
All existing tests pass without modification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Refactor licenseInfoFromWrapper() to use EntitlementFieldWrapper
Updates HTTP handler to use GetEntitlements() internally while maintaining
backward-compatible API response structure.
Changes:
- Replace direct wrapper.V1.Spec.Entitlements access with GetEntitlements()
- Use wrapper.IsV1() and wrapper.IsV2() helper methods
- Add conversion loop to extract underlying EntitlementField structs
- Maintain identical API response structure (v1Entitlements/v2Entitlements)
Benefits:
- Uses unified GetEntitlements() API internally
- Maintains full backward compatibility
- API consumers see no change in response structure
- Cleaner version checking with IsV1()/IsV2() methods
All existing tests pass without modification.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Fix test imports to use licensewrapper from kotskinds
Updates test files to import licensewrapper from kotskinds instead of
the deleted pkg/license/types package.
Changes:
- Replace licensetypes import with licensewrapper from kotskinds
- Update all licensetypes.LicenseWrapper references to licensewrapper.LicenseWrapper
Files updated:
- pact/license_test.go
- pact/instance_test.go
- pact/custom_metrics_test.go
- pkg/integration/integration_test.go
- pkg/report/util_test.go
- pkg/report/instance_test.go
All pkg/ tests pass successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Use unified entitlements field with EntitlementFieldWrapper
BREAKING CHANGE: LicenseInfo JSON response structure has changed
Previously, the LicenseInfo API response included version-specific
entitlements fields:
- v1Entitlements: map[string]kotsv1beta1.EntitlementField
- v2Entitlements: map[string]kotsv1beta2.EntitlementField
Now, there is a single unified entitlements field:
- entitlements: map[string]EntitlementFieldWrapper
The EntitlementFieldWrapper provides version-agnostic access to
entitlement data through accessor methods:
- GetTitle()
- GetDescription()
- GetValue()
- GetValueType()
- IsHidden()
- GetSignature()
Benefits:
- Eliminates version-specific conditional logic in API consumers
- Provides single, consistent entitlements structure
- Simplifies licenseInfoFromWrapper() implementation
- Removes dependency on kotsv1beta1 and kotsv1beta2 imports
All tests pass with this change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Fix entitlements JSON serialization to use EntitlementField not wrapper
The LicenseInfo API response now correctly serializes entitlements as
EntitlementField objects instead of EntitlementFieldWrapper objects.
Previously, the JSON would have looked like:
```json
{
"entitlements": {
"some_field": {
"V1": { "title": "...", "value": "..." },
"V2": null
}
}
}
```
Now it correctly serializes as:
```json
{
"entitlements": {
"some_field": {
"title": "...",
"value": "...",
"valueType": "..."
}
}
}
```
Implementation:
- Convert EntitlementFieldWrapper map to EntitlementField map
- For V1 licenses: use EntitlementField directly
- For V2 licenses: convert v1beta2.EntitlementField to v1beta1.EntitlementField
(they are structurally identical, only signature field differs)
- This maintains the unified entitlements API while providing proper JSON structure
All tests pass with this change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
* Fix: Return version-specific EntitlementField in API response
BREAKING CHANGE (REVERTED): This fixes the previous commit that incorrectly
converted v1beta2 licenses to v1beta1 format in the API response.
The API now correctly returns:
- v1beta1.EntitlementField for v1beta1 licenses (with MD5 signature in v1 field)
- v1beta2.EntitlementField for v1beta2 licenses (with SHA-256 signature in v2 field)
This preserves the actual license format and signature data instead of
incorrectly converting v2 signatures to v1 format.
Implementation:
- Changed Entitlements field type from map[string]EntitlementField to interface{}
- Detect license version with wrapper.IsV1() / wrapper.IsV2()
- Return appropriate version-specific map
- Preserves signature format integrity
This is the correct approach - the API response should reflect the actual
license version rather than forcing everything into v1 format.
All tests pass with this change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
---------
Co-authored-by: Claude <[email protected]>
0 commit comments