You've already forked wc-licensed-product
Add per-license customer secrets for API response verification
- Add static methods to ResponseSigner for deriving customer-specific secrets - Display "API Verification Secret" in customer account licenses page - Add collapsible secret section with copy button - Update server-implementation.md with per-license secret documentation - Update translations with new strings Each customer now gets a unique verification secret derived from their license key, eliminating the need to share the master server secret. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,14 +8,16 @@ The security model works as follows:
|
||||
|
||||
1. Server generates a unique signature for each response using HMAC-SHA256
|
||||
2. Signature includes a timestamp to prevent replay attacks
|
||||
3. Client verifies the signature using a shared secret
|
||||
4. Invalid signatures cause the client to reject the response
|
||||
3. Each license key has a unique derived secret (not the master secret)
|
||||
4. Client verifies the signature using their per-license secret
|
||||
5. Invalid signatures cause the client to reject the response
|
||||
|
||||
This prevents attackers from:
|
||||
|
||||
- Faking valid license responses
|
||||
- Replaying old responses
|
||||
- Tampering with response data
|
||||
- Using one customer's secret to verify another customer's responses
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -323,13 +325,49 @@ Adjust if needed:
|
||||
$signature = new ResponseSignature($key, timestampTolerance: 600); // 10 minutes
|
||||
```
|
||||
|
||||
### Per-License Secrets
|
||||
|
||||
Each customer receives a unique secret derived from their license key. This means:
|
||||
|
||||
- Customers only know their own secret, not the master server secret
|
||||
- If one customer's secret is leaked, other customers are not affected
|
||||
- The server uses HKDF-like derivation to create unique secrets
|
||||
|
||||
#### How Customers Get Their Secret
|
||||
|
||||
Customers can find their per-license verification secret in their account:
|
||||
|
||||
1. Log in to the store
|
||||
2. Go to My Account > Licenses
|
||||
3. Click "API Verification Secret" under any license
|
||||
4. Copy the 64-character hex string
|
||||
|
||||
This secret is automatically derived from the customer's license key and the server's master secret.
|
||||
|
||||
#### Using the Customer Secret
|
||||
|
||||
```php
|
||||
use Magdev\WcLicensedProductClient\SecureLicenseClient;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
|
||||
// Customer uses their per-license secret (from account page)
|
||||
$client = new SecureLicenseClient(
|
||||
httpClient: HttpClient::create(),
|
||||
baseUrl: 'https://shop.example.com',
|
||||
serverSecret: 'customer-secret-from-account-page', // 64 hex chars
|
||||
);
|
||||
|
||||
$info = $client->validate('XXXX-XXXX-XXXX-XXXX', 'example.com');
|
||||
```
|
||||
|
||||
### Secret Key Rotation
|
||||
|
||||
To rotate the server secret:
|
||||
|
||||
1. Deploy new secret to server
|
||||
2. Update client configurations
|
||||
3. Old signatures become invalid immediately
|
||||
2. All per-license secrets change automatically (they're derived)
|
||||
3. Customers must copy their new secret from their account page
|
||||
4. Old signatures become invalid immediately
|
||||
|
||||
For zero-downtime rotation, implement versioned secrets:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user