generated: '2026-08-09' method: searched source: - openapi/canix-openapi-original.yml - https://api.canix.com/.well-known/oauth-authorization-server - https://api.canix.com/.well-known/oauth-protected-resource docs: https://api.canix.com/api-docs-swagger/index.html description: >- Canix runs two authentication models on one host. The REST API at api.canix.com/api/v1 uses a company-scoped API key in an X-API-KEY header. The MCP server at api.canix.com/mcp uses OAuth 2.1 with dynamic client registration and PKCE. The baseline below was derived from the OpenAPI by 0-working/derive-authentication.py and then upgraded with the OAuth scheme probed from Canix's own well-known documents, which the OpenAPI does not mention. summary: types: - apiKey - oauth2 api_key_in: - header oauth2_flows: - authorizationCode schemes: - name: ApiKeyAuth type: apiKey in: header parameter: X-API-KEY applies_to: https://api.canix.com/api/v1 (REST API, all 74 operations) scope_of_key: company issuance: https://app.canix.com/company/api issuance_gate: >- Key generation is inside the authenticated Canix application. Prospective third-party developers are routed through a "Request an API Key" contact form at https://www.canix.com/developer rather than self-service. rotation: not documented expiry: not documented guidance_from_provider: >- Canix's own OpenAPI description recommends storing the key in a secrets manager (Doppler, AWS, Google Cloud) rather than a dotenv file. sources: - openapi/canix-openapi-original.yml - name: CanixMCPOAuth type: oauth2 applies_to: https://api.canix.com/mcp (MCP server) issuer: https://api.canix.com metadata: https://api.canix.com/.well-known/oauth-authorization-server protected_resource_metadata: https://api.canix.com/.well-known/oauth-protected-resource dynamic_client_registration: https://api.canix.com/oidc/register token_endpoint_auth_methods: - none - client_secret_basic - client_secret_post code_challenge_methods: - S256 bearer_methods: - header scopes: - mcp flows: - flow: authorizationCode authorizationUrl: https://api.canix.com/oauth/authorize tokenUrl: https://api.canix.com/oauth/token revocationUrl: https://api.canix.com/oauth/revoke refreshSupported: true sources: - https://api.canix.com/.well-known/oauth-authorization-server observed_behaviour: anonymous_rest_call: url: https://api.canix.com/api/v1/facilities http_status: 403 body: '{"message":"Access Denied"}' note: >- An unauthenticated REST call returns 403, not the 401 the OpenAPI declares for "Not authenticated". A caller cannot distinguish a missing key from an unauthorized one. anonymous_mcp_call: url: https://api.canix.com/mcp http_status: 401 www_authenticate: Bearer resource_metadata="https://api.canix.com/.well-known/oauth-protected-resource" note: RFC 9728 compliant challenge — the MCP surface handles this correctly. gaps: - No OpenID Connect. The /.well-known/openid-configuration document is byte-identical to the RFC 8414 OAuth metadata and carries no jwks_uri, userinfo_endpoint or id_token signing algorithms, so it is not an OIDC provider despite the path. - No mTLS, no signed requests, no IP allowlisting documented. - No published key rotation, expiry, or revocation procedure for the REST API key. - The REST API has no OAuth path, so a third-party integrator holds a long-lived company-wide key with no scoping and no per-user attribution. x-evidence: - url: https://api.canix.com/api.yaml http_status: 200 fetched: '2026-08-09' - url: https://api.canix.com/.well-known/oauth-authorization-server http_status: 200 fetched: '2026-08-09' - url: https://api.canix.com/api/v1/facilities http_status: 403 fetched: '2026-08-09'