generated: '2026-09-12' method: searched source: >- https://secure.agree.com/documentation (Introduction > Authentication) + openapi/agree-com-api-openapi.json (components.securitySchemes) + https://secure.agree.com/.well-known/oauth-authorization-server docs: https://secure.agree.com/documentation#section/Introduction/Authentication name: Agree.com Authentication description: >- Agree.com runs two independent authentication models for two different surfaces. The REST API is protected by a long-lived bearer API key minted in the dashboard. The hosted MCP server is protected by a full OAuth 2.1 authorization server with PKCE and dynamic client registration. Neither is usable against the other: the OAuth server advertises exactly one scope, "mcp", and the REST spec declares only the bearer scheme. summary: types: - http - oauth2 surfaces: 2 schemes: - name: bearer type: http scheme: bearer surface: REST API (https://secure.agree.com/api/v1) description: API key authentication via Bearer token applied: >- Declared in components.securitySchemes and applied per-operation. All 56 operations carry security: [{bearer: []}]. The top-level security[] array is empty, so there is no document-wide default - the requirement is stated on every operation instead. credential: kind: api-key provisioning: Generated in the Agree dashboard under Settings > API Keys. transport: 'Authorization: Bearer ' prefix: null prefix_note: The documentation does not publish a key prefix or any test/live key distinction. scoping: >- None. The documentation states plainly - "Keep this key secure - it provides full access to your organization's data." The key is organization-wide and unscoped; there is no read-only key, no per-resource restriction, and no documented expiry. rotation: >- "If compromised, regenerate it immediately in your dashboard." Rotation is manual and dashboard-only; no rotation endpoint exists in the API. sources: - openapi/agree-com-api-openapi.json - https://secure.agree.com/documentation - name: oauth2-mcp type: oauth2 surface: MCP server (https://secure.agree.com/mcp) description: >- OAuth 2.1 authorization code flow protecting the hosted MCP endpoint. Not declared in the OpenAPI - it was found by probing RFC 8414 authorization server metadata and RFC 9728 protected resource metadata, both of which are served anonymously. flows: authorization_code: authorization_url: https://secure.agree.com/oauth/authorize token_url: https://secure.agree.com/oauth/token refresh_supported: true pkce: S256 pkce_required: true scopes: mcp: >- The single scope the authorization server advertises. Its grants are not documented; see scopes/agree-com-scopes.yml. endpoints: issuer: https://secure.agree.com registration_endpoint: https://secure.agree.com/oauth/register revocation_endpoint: https://secure.agree.com/oauth/revoke client_authentication: - none - client_secret_post - client_secret_basic dynamic_client_registration: true bearer_methods_supported: - header sources: - https://secure.agree.com/.well-known/oauth-authorization-server - https://secure.agree.com/.well-known/oauth-protected-resource webhook_verification: mechanism: HMAC-SHA256 header: X-Webhook-Signature timestamp_header: X-Webhook-Timestamp encoding: hex, lowercase secret: >- Per-endpoint signing secret (whsec_ prefix) returned exactly once, in the response to POST /api/v1/webhooks. It is not retrievable afterwards. computation: HMAC-SHA256 over the raw request body, keyed by the endpoint secret. comparison: >- Constant-time. The documentation ships working Node.js (crypto.timingSafeEqual) and Python (hmac.compare_digest) verification examples. replay_protection: >- PARTIAL. A timestamp header is sent but the documented verification procedure does not include it in the signed payload and states no tolerance window, so the published recipe does not by itself defeat replay. source: https://secure.agree.com/documentation#tag/Webhooks findings: - >- The REST API has no OAuth, no scopes, and no key scoping. A single compromised key is full organization access to contracts, invoices, contacts and revenue reporting. - >- The MCP surface is materially better authenticated than the REST surface it fronts, which is an unusual inversion - most providers in the catalog bolt a weaker key model onto MCP, not a stronger one.