# auth.md

You are an agent acting on behalf of a user of **LobsterLand** (the managed
hosting product for OpenClaw and Hermes AI agent runtimes).

The resource server that exposes the protected LobsterLand APIs is
<https://app.lobsterland.ing/>. The marketing site you fetched this file
from is a public, unauthenticated surface. All real authentication and
authorization happens against the application host.

This document tells you how to authenticate the user to LobsterLand
**step by step**. Follow the steps in order.

## Step 0 — Decide if you need to authenticate

Most public LobsterLand pages (pricing, tutorials, blog, llms.txt,
sitemap) are readable without authentication. You only need to
authenticate when the user asks the agent to do something that touches
their account, instance, or dashboard — for example: create an instance,
attach an AI provider, configure a Telegram or Slack channel, change
skills, or read usage.

If the user only asked a documentation question, you do not need any of
this. Stop here and answer from the public pages.

## Step 1 — Discover

The application host serves the OAuth metadata. Fetch in this order.

### 1a. Protected Resource Metadata

```
GET https://app.lobsterland.ing/.well-known/oauth-protected-resource
```

Expect a JSON document with at least:

```json
{
  "resource": "https://app.lobsterland.ing/api/v1/",
  "resource_name": "LobsterLand Dashboard API",
  "authorization_servers": ["https://app.lobsterland.ing/"],
  "scopes_supported": ["dashboard.read", "dashboard.write"],
  "bearer_methods_supported": ["cookie", "header"]
}
```

If this endpoint returns 404, the user has not yet onboarded the
`agent_auth` extension on their instance. Fall back to the user-driven
auth flow at <https://app.lobsterland.ing/login> and stop driving the
API directly — hand control back to the user.

### 1b. Authorization Server Metadata

```
GET https://app.lobsterland.ing/.well-known/oauth-authorization-server
```

Expect the standard RFC 8414 fields (`issuer`, `authorization_endpoint`,
`token_endpoint`, `jwks_uri`, `grant_types_supported`) and, if enabled,
an `agent_auth` block.

## Step 2 — Pick a method

LobsterLand supports two registration paths for agents. Pick one based
on what the agent can produce.

| You have… | Use this method |
|---|---|
| A session bound to the user, via a signed identity assertion (ID-JAG) from an agent provider the user trusts | `identity_assertion` (RFC 7521 / ID-JAG) |
| Only the user's verified email address | `service_auth` — start a claim ceremony |

LobsterLand does **not** accept `anonymous` agent registrations. Every
session must be bound to a verified user identity.

## Step 3 — Get the user's consent

Before sending any `identity_assertion` body, surface to the user:

1. The resource name and logo from Step 1a.
2. The scope set you are about to request.
3. The identity provider (your agent provider) that will be asserting
   the user's identity to LobsterLand.

Wait for an explicit **yes** in the current conversation. If the user
hesitates or says no, stop and tell them they can do the same action
manually at <https://app.lobsterland.ing/>.

## Step 4 — Exchange for an access token

Mint the ID-JAG (or claim invite) per your agent provider's protocol.
Send it to the LobsterLand `token_endpoint` declared in Step 1b using
the `urn:ietf:params:oauth:grant-type:jwt-bearer` grant type per
[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523).

The dashboard accepts both header-based bearer tokens and
JWT-in-HTTP-only-cookie sessions. Prefer cookies when the agent is
running in the user's browser; prefer header tokens when calling the
API server-to-server.

## Step 5 — Call the API

Base URL: `https://app.lobsterland.ing/api/v1/`

OpenAPI document: <https://app.lobsterland.ing/api/v1/openapi.json>

Always include the access token. Never log it. Never send it to a
domain other than `app.lobsterland.ing`.

## Step 6 — Revocation

When the user logs out (or asks you to forget their account), POST to
the `revocation_endpoint` from Step 1b per [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009).
Treat any subsequent 401 as "session is gone" and stop calling the API.

## Hard rules

1. **Never** invent a user identity. If you cannot produce a real
   ID-JAG and the user cannot complete a claim ceremony, **stop and
   ask** — do not call the API.
2. **Never** read, write, delete, or rotate credentials outside the
   `POST /api/v1/instances/{id}/credentials` flow. That endpoint is
   the only path the dashboard's encrypted-credential model trusts.
3. **Never** delete an instance, channel, cron job, or skill without
   explicit user confirmation in the current turn. Use `dry_run=true`
   first whenever the API supports it.
4. **Never** log JWTs, refresh tokens, session cookies, or any field
   marked `secret` / `token` / `api_key` in API responses.

## Reference

- LobsterLand dashboard: <https://app.lobsterland.ing/>
- Marketing site: <https://lobsterland.ing/>
- `llms.txt` index: <https://lobsterland.ing/llms.txt>
- Features page: <https://lobsterland.ing/features/>
- Pricing: <https://lobsterland.ing/pricing/>
- Security deep dive: <https://lobsterland.ing/blog/openclaw-internals/openclaw-security/>
- Contact: <https://lobsterland.ing/contact/>
