Register an application
The first step on the Applications screen. You click Install protection, paste your MCP server's URL, and AuthSec creates a resource server record that the rest of the launch lifecycle hangs off.
What the UI does
Click Install protection → a side panel asks for:
- Name — human-readable. Shows up everywhere in the admin UI. Doesn't affect runtime behaviour.
- Public base URL — the externally-reachable origin of your MCP server, e.g.
https://20-106-226-245.sslip.io. HTTPS is required for non-loopback hostnames;http://localhostandhttp://127.0.0.1are allowed for local dev. - Protected base path — defaults to
/mcp. This is where your MCP JSON-RPC handler lives. The resource URI gets composed as<public_base_url><protected_base_path>and ends up in tokenaudclaims.
That's it. Submit and you land on the application detail view.
What happens server-side
POST /authsec/resource-servers runs:
- Validates HTTPS unless the hostname is localhost / 127.0.0.1.
- Generates a fresh
introspection_secret(32 random bytes, hex-encoded). The secret is hashed with bcrypt for storage; the plaintext is only returned in this response. - Inserts a row in
resource_serverswithstate = 'pending_scan',scan_generation = 0, andregistration_modes = ['dcr', 'cimd', 'prereg']. - Auto-creates a default
viewerrole (no scopes attached) and a default access policy withenabled = trueand the viewer role as the default role. This is what populates the Access tab in step 5 of the first-run guide. - Kicks off a background tool discovery — best-effort, won't block the response.
The response shape
This is the canonical source of truth for SDK configuration. Paste, don't hand-write:
{
"id": "525da3b4-4206-4070-ad68-90cc3a6de43b",
"introspection_secret": "9b7c5e...",
"issuer_url": "http://localhost:7468",
"jwks_uri": "http://localhost:7468/oauth/jwks",
"introspection_endpoint": "http://localhost:7468/oauth/introspect",
"resource_url": "https://20-106-226-245.sslip.io/mcp",
"scope_matrix_url": "http://localhost:7468/authsec/resource-servers/525da3b4-.../sdk-policy",
"manifest_url": "http://localhost:7468/authsec/resource-servers/525da3b4-.../sdk-manifest",
"validation_mode": "auto",
"scopes_supported": [],
"status": "pending_scan"
}
The Go SDK reference maps every field 1:1 to a Config struct property. The introspection_secret only appears in this response; if you lose it, rotate via POST /authsec/resource-servers/:id/rotate-introspection-secret (admin JWT required).
State machine
| State | Meaning | How you get there |
|---|---|---|
pending_scan | Just registered. Tools haven't been discovered yet. | Initial state after POST /resource-servers. |
needs_setup | Tools discovered. Setup checklist has gaps. | First successful POST /rescan. |
ready | Launched. SDK runtime enforcement is active. | POST /activate after every setup checklist item passes. |
scan_failed | Tool discovery hit an error. | Failed POST /rescan — see tool inventory troubleshooting. |
The "Discovered" badge corresponds to state = needs_setup with scan_generation > 0. "Not launched" is anything except ready.
Auth scheme summary
POST /authsec/resource-servers requires admin JWT — a tenant-admin operation. The Basic-auth credentials you get back (id : introspection_secret) are for the three SDK-facing endpoints only:
| Endpoint | Auth | Caller |
|---|---|---|
POST /oauth/introspect | Basic (rs_id : secret) | SDK runtime |
GET /authsec/resource-servers/:id/sdk-policy | Basic (rs_id : secret) | SDK ScopeMatrixClient |
PUT /authsec/resource-servers/:id/sdk-manifest | Basic (rs_id : secret) | SDK ManifestPublisher |
Everything else under /authsec/resource-servers/:id/... is admin-JWT.
Troubleshooting
400 "public_base_url must use HTTPS". You pasted an http:// URL with a non-loopback hostname. For production servers, fix the deployment. For local dev, use http://localhost:8000 or http://127.0.0.1:8000 literally.
400 "name is required". Self-explanatory.
Background discovery didn't run. The auto-scan happens in a goroutine; if your server is unreachable at registration time, it fails silently and state stays at pending_scan. Hit Scan now on the Tools tab to retry. The last_scan_error column on resource_servers has the reason.
Related
- Tool inventory and discovery — the next step
- Launch the application — activation gate
- Go SDK reference — where the response fields go