Partner authentication
Every partner request sends the customer's integration key and your partner secret, from a registered IP address. The checks, their errors, and rotation.
A partner request carries two credentials and must come from a known place:
X-API-Key: CUSTOMER_INTEGRATION_KEY
X-Partner-Secret: YOUR_PARTNER_SECRET| Credential | Identifies | Issued by | Scope |
|---|---|---|---|
Integration key (X-API-Key) | One customer organization | The customer, in Settings → Integrations → Export | That organization, for your platform only |
Partner secret (X-Partner-Secret) | Your platform | Vitruve, at approval | Every customer that created a key for you |
| Registered addresses | Your servers | Vitruve, from the list you sent | Every request you make |
There are no tokens to exchange or refresh. Send both headers on every request.
What is checked, in order
Each request goes through these checks. The first one that fails decides the answer.
| # | Check | Fails with |
|---|---|---|
| 1 | Your secret, or the address when the request doesn't prove it is yours, is not throttled for failed authentication | 429 Too many failed authentication attempts |
| 2 | X-API-Key is present and is a known, unrevoked key | 401 Missing X-API-Key header or Invalid API key |
| 3 | The customer organization is active | 401 Organization is not active |
| 4 | X-Partner-Secret is present | 401 Partner credentials required |
| 5 | The secret is valid, not revoked, and issued to the platform the key was created for | 401 Invalid partner credentials |
| 6 | Your platform's integration is enabled | 403 This integration is not available |
| 7 | The request comes from one of your registered addresses | 403 Request origin not allowed for this integration |
| 8 | The key is under its rate limit | 429 |
| 9 | The customer's plan includes export integrations | 403 Your plan no longer includes API access |
| 10 | The request is a GET | 405 Method not allowed |
| 11 | The path is one of the partner endpoints | 404 Route not found |
A key created for one platform does not work with another platform's secret, even if both are approved partners.
Every request that passes check 7 counts towards the key's rate limit, whatever it answers: a 403, 404 or 405 costs the same as a 200. A customer key that leaked without your secret therefore can't spend your budget for that customer. Checks 2 to 7 count as failed authentication instead.
The plan check (9) runs on every request, without caching. See Plans and history for what to do when it fails.
Registered addresses
Vitruve compares the address each request arrives from against the addresses registered for your platform: single IPv4 or IPv6 addresses, or CIDR ranges no wider than /24 (IPv4) or /48 (IPv6). Requests from anywhere else answer 403 Request origin not allowed for this integration. To add or change addresses, see Register your egress addresses.
Failed authentication is throttled
Failures of checks 2 to 7 are counted per minute. Where they count depends on whether the request proves it is yours:
| Request | Counts against | Limit |
|---|---|---|
| One of your secrets, current or revoked, from one of your registered addresses | That secret | 600 failures a minute |
| No secret, an unknown one, or an unregistered address | The client address | 30 failures a minute |
Past the limit, every request that counts against the same secret or address is answered 429 Too many failed authentication attempts until the minute ends, whatever key it sends. A request that proves it is yours is never blocked by its address, so other traffic behind your addresses can't lock you out.
A customer key that was deleted, an organization that was closed, or a worker still sending a revoked secret therefore never locks out your other customers or your current secret. A sync that keeps retrying dead keys still stops itself once it spends the 600, so when a customer key answers 401, stop using it and ask the customer for a new one. Fix a missing secret or an unregistered address first: those failures count against your address. Once checks 2 to 7 pass, 403 answers count towards the key's rate limit, not here.
Rotate your secret
Vitruve can issue a second secret while the first still works:
- Ask Vitruve for a new secret.
- Deploy it everywhere you call the API.
- Confirm no request uses the old secret, then ask Vitruve to revoke it.
A revoked secret answers 401 Invalid partner credentials immediately. If you believe your secret leaked, ask Vitruve to revoke it at once and issue a new one.
Keep credentials safe
- Store the secret in a secrets manager and the customer keys encrypted at rest.
- Never log request headers, and never put either credential in a URL.
- Call the API from your servers only. The API does not enable cross-origin (CORS) requests.
- When a customer disconnects your platform, delete their key on your side too.