Authentication
Two ways in, both reaching exactly the same catalogue with the same quota. They differ in who holds the credential and what happens when it leaks.
OAuth 2.1 for connectors
Claude, ChatGPT, Cursor and OpenCode sign in with OAuth 2.1. Point the connector at
https://port.harborgovcon.com/mcp and it discovers everything else from the
401 response. This gateway is a self-hosted authorization server, so there
is no third-party identity provider involved and no separate account to create.
POST https://port.harborgovcon.com/mcp # no credentials
401 WWW-Authenticate: Bearer error="invalid_token", error_description="…",
scope="read server:harbor-meta server:usaspending … server:gao-bid-protests",
resource_metadata="https://port.harborgovcon.com/.well-known/oauth-protected-resource/mcp"
GET https://port.harborgovcon.com/.well-known/oauth-protected-resource/mcp
GET https://port.harborgovcon.com/.well-known/oauth-authorization-server
POST https://port.harborgovcon.com/register # Dynamic Client Registration
GET https://port.harborgovcon.com/authorize # sign in and approve
POST https://port.harborgovcon.com/token # PKCE code exchangeAuthorization codes last 60 seconds and are single use. PKCE S256 is
required. Access tokens last an hour and refresh tokens rotate; a replayed refresh token
revokes the whole authorization. Revoke a connector at any time from
Connectors.
API keys for scripts
A static bearer key in the Authorization header. Send it as a header,
never in the query string: the MCP authorization specification prohibits access tokens in
the URI, and a token in a URL ends up in access logs, in browser history and in any
Referer.
Authorization: Bearer YOUR_API_KEYA missing, malformed, revoked, expired or unknown credential returns 401.
Going over your rolling 24 hour quota returns a tool error naming the limit, and nothing
is charged as overage.
Create one key per machine rather than one key for everything. A key scoped to a laptop that gets stolen is one revocation; a key shared across four environments is an afternoon. Test keys are available on the same page and never count against plan quota, which is what makes them safe to use while wiring a client up.
Scopes and what they reach
An OAuth authorization is granted a set of scopes. Every source has its own
server:<slug> scope, so a connector can be limited to the datasets it
actually needs, and the consent screen states exactly what is being requested rather
than assuming a generic read.
The authorization server publishes the full scope list at
https://port.harborgovcon.com/.well-known/oauth-authorization-server,
including one scope per source. A connector granted only
server:usaspending cannot call a SAM.gov tool, even though both are on the
same endpoint.
Revoking access
- Connectors are revoked from Connected apps. Revocation takes effect immediately: the access token stops working and the refresh token can no longer mint a new one. If the connector used a refresh token that has already rotated, the whole authorization is dropped rather than just the latest token.
- API keys are revoked from API keys.
A revoked key returns
401on its next call, and revocation is reversible for a short window in case it was a mistake. - Everything at once is on Settings, which can end every session for the account. That signs you out everywhere as well, so it is the right control when a device is lost rather than when a single integration should stop.
Rotating a key issues a replacement and shows it once. The old key keeps working until you finish the rotation, so a rotation does not need a maintenance window.