Authentication Issues
MemorySync supports several authentication methods. This page covers each one, the exact error each can produce, and the tenant- and project-binding checks that run after authentication succeeds.
Authentication Methods & Resolution Order
Each request is authenticated by the first supported method that resolves to a valid user. The supported methods are:
| Method | Header | When to Use |
|---|---|---|
| Bearer (dashboard / access token) | Authorization: Bearer <token> | Dashboard sessions and role-aware access tokens |
| Bearer (consumer) | Authorization: Bearer <token> | End-user consumer accounts |
| API Key | X-API-Key: ms_... | Server-to-server integrations and SDK usage |
| OAuth bearer | Authorization: Bearer <token> | Third-party OAuth app integrations |
💡 Key insight: If you send both X-API-Key and Authorization: Bearer, the Bearer token is evaluated first. A valid API key will not help if you also send an invalid Bearer token — remove the Authorization header.
API Key Errors
API key authentication produces a different HTTP status and error message for each failure reason:
| Failure Reason | HTTP Status | Error Message |
|---|---|---|
| No key provided | 401 | "API key missing" |
| Key not recognized | 401 | "Invalid API key" |
| Key revoked | 403 | "API key revoked" |
| Key expired | 401 | "Invalid API key" |
| Key not active | 401 | "Invalid API key" |
Security note: Failed API key attempts are recorded in the audit log under the api_key category. Repeated failures are easy to spot from the dashboard — if you see revoked entries you didn’t make, someone in your organization may have revoked the key you’re using.
Why revoked keys get 403 instead of 401: A revoked key is a previously-valid key that was deliberately deactivated. The 403 signals “we recognize you, but you’re denied” — as opposed to 401 which means “we don’t recognize these credentials at all.”
JWT Token Issues
A failed bearer token quietly causes the platform to fall through to the next supported authentication method. You will only see a 401 if all methods fail to identify a valid user.
Common bearer-token failure scenarios:
- Token expired — refresh or re-issue the token via the appropriate auth endpoint.
- Wrong audience — dashboard, infrastructure, and consumer tokens are not interchangeable. Sending one type to an endpoint that expects another fails validation.
- Signature mismatch — the token was issued before a credentials rotation. Re-authenticate to obtain a fresh token.
- Malformed token — the Bearer value is not a valid token (for example, an API key sent as Bearer). Remove the
Authorizationheader and useX-API-Keyinstead.
⚠️ Gotcha: Consumer tokens are also rejected if the underlying consumer account is not active or has been disassociated from its user, even if the token itself has not yet expired.
OAuth Bearer Errors
OAuth bearer tokens follow the OAuth 2.0 grant types you used to obtain them. Authorization code and refresh-token grants resolve to a specific user account; client-credentials grants resolve to the owning organization’s billing user.
Common failure modes:
- Token not recognized — the token has been revoked or has expired. Re-issue it.
- User no longer exists — the token references a user account that has been removed.
- Owner cannot be resolved — for client-credentials grants, the organization has no billing owner configured. Contact your admin.
On success, OAuth scopes attached to the token are enforced for the rest of the request, so a token issued with read-only scopes cannot be used to perform writes.
Tenant Context Errors
After authentication succeeds, the system must determine which tenant's data the request operates on. This is a critical security boundary — getting it wrong means cross-tenant data leaks.
How tenant context is resolved:
- API key auth: The API key's derived tenant is the sole source of truth. Any
X-Tenant-IDheader that disagrees is rejected with403 "Header/API key tenant mismatch". - JWT/Bearer auth: The user's
tenant_idfield is used. If null, theX-Tenant-IDheader is required. - Tenant switcher: For JWT users, the
X-Tenant-IDheader can override the default tenant — but only if the user has a valid membership in the organization that owns the target tenant.
Error: TENANT_CONTEXT_REQUIRED (400)
This fires when an authenticated request has no tenant context and the endpoint isn't on the exempt list (auth, admin, SCIM, SSO). Fix: add X-Tenant-ID: your-tenant-id to your request headers.
Error: "Invalid tenant context" (403)
The X-Tenant-ID header references a tenant that doesn't exist or has been deleted. Verify the tenant ID in your dashboard.
Project Binding Errors
After tenant resolution, the system enforces project-level isolation. API keys can be scoped to a specific project, and when they are, strict binding rules apply:
| Error | Status | Cause | Fix |
|---|---|---|---|
"Header/API key project mismatch" | 403 | X-Project-ID header doesn't match the key's project | Remove the header — the key's project is enforced automatically |
API_KEY_PROJECT_REQUIRED | 403 | Deployment requires all keys to be project-scoped, but this key has no project | Create a new API key scoped to a specific project |
After both tenant and project are resolved, a final isolation check verifies that the project actually belongs to the resolved tenant. This prevents a subtle attack where a legitimate key for Tenant A tries to access a project owned by Tenant B.
✅ Best practice: Always create project-scoped API keys for production integrations. Org-wide keys without a project scope work but require the caller to send X-Project-ID on every request, which adds complexity and risk.
IP Blocklist
MemorySync supports IP-based access control with blocklists that can contain exact IPs, CIDR ranges, and IPv6 addresses. If your IP is blocked, the request is rejected before any authentication attempt.
Supported formats:
- Exact IP:
"192.168.1.100" - CIDR range:
"192.168.1.0/24","10.0.0.0/8" - IPv6:
"::1","2001:db8::/32"
Debugging a blocklist rejection: IP blocklist rejections happen before authentication is attempted, so you may not receive a structured JSON response. If your requests are failing with a connection-level error and you suspect IP blocking, check with your organization admin whether your IP or CIDR range has been added to the blocklist in the security settings.