# Sgcwebsockets Auth

> sgcWebSockets Authentication

- Skill: `esegece-com/sgcwebsockets-auth` (Agent Skill, multi-file: 164 files)
- Install (CLI): `npx skillmds@latest add esegece-com/sgcwebsockets-auth`
- Raw SKILL.md: https://api.skillmd.com/api/skills/esegece-com/sgcwebsockets-auth/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: esegece-com (https://skillmd.com/u/esegece-com)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/esegece-com/sgcwebsockets-auth

---


# sgcWebSockets Authentication

Six components covering both halves of authentication: acting as a client that
obtains and presents tokens, and acting as a server that issues and validates
them. OAuth2 and JWT each have a client and a server, and WebAuthn covers
passkeys on the server side.

## When to use this skill

- Sign a user in through an OAuth2 provider and get an access token
- Refresh, revoke or introspect a token
- Run your own OAuth2 authorization server
- Issue JWTs, or validate incoming ones on a server
- Add passkey (WebAuthn) registration and login to a server
- Use DPoP sender-constrained tokens

## Units

Five of the six live in `sgcHTTP`:

```pascal
uses
  sgcHTTP;   // OAuth2 client, OAuth2 server, OAuth2 server provider,
             // JWT client, JWT server
```

`TsgcWSAPIServer_WebAuthn` is the exception and lives in
`sgcWebSocket_Server_APIs`, because it attaches to a WebSocket or HTTP server
rather than standing alone.

These are frequently paired with the REST server in `sgcwebsockets-http`.

## Before you start, ask the developer

Use a structured question tool if your host has one, for example Claude Code's
`AskUserQuestion`. Otherwise ask in chat:

1. **Client or server side?** Consuming someone else's identity provider is the
   client. Issuing your own tokens is the server. They are separate components
   and the answer changes everything that follows.
2. **Which OAuth2 flow?** Authorization code with a local redirect listener is
   the usual one for a desktop application, and it needs a local HTTP server on
   a loopback port, which is what `LocalServerOptions` configures.
3. **Where do the secrets live?** Client id and secret must come from
   configuration. Never generate source with them inline. Note they sit on
   `OAuth2Options`, not on `AuthorizationServerOptions`, which holds the
   provider's endpoint URLs.
4. **Are tokens sender-constrained?** DPoP is off unless asked for. Adding it
   later changes every request, so decide up front.
5. **Do you already have a user store?** Both the OAuth2 server and the JWT
   server take a `TsgcHTTPServer_Users` component, which is shared with the REST
   server.

## Components in this skill

| Component | Side | Use it for |
| --- | --- | --- |
| `TsgcHTTP_OAuth2_Client` | client | Obtain, refresh, revoke and introspect tokens |
| `TsgcHTTP_OAuth2_Server` | server | Run an authorization server |
| `TsgcHTTP_OAuth2_Server_Provider` | server | Define a provider within that server |
| `TsgcHTTP_JWT_Client` | client | Build and sign a JWT to send |
| `TsgcHTTP_JWT_Server` | server | Validate incoming JWTs |
| `TsgcWSAPIServer_WebAuthn` | server | Passkey registration and authentication |

## Quickstart, OAuth2 client

The component runs the flow and holds the result. Configure the endpoints, the
local redirect listener and the credentials, then start:

```pascal
uses
  sgcHTTP;

FOAuth := TsgcHTTP_OAuth2_Client.Create(Self);

// credentials and grant type live on OAuth2Options
FOAuth.OAuth2Options.ClientId := GetClientIdFromConfig;
FOAuth.OAuth2Options.ClientSecret := GetClientSecretFromConfig;

// the provider's endpoints live on AuthorizationServerOptions
FOAuth.AuthorizationServerOptions.AuthURL := 'https://provider/authorize';
FOAuth.AuthorizationServerOptions.TokenURL := 'https://provider/token';

// the loopback listener that catches the redirect
FOAuth.LocalServerOptions.Port := 8080;
FOAuth.LocalServerOptions.RedirectURL := 'http://127.0.0.1:8080/';

FOAuth.Start;

// after the flow completes, the token is on the component
vHeader := FOAuth.TokenType + ' ' + FOAuth.AccessToken;
```

`AccessToken`, `TokenType`, `CurrentExpiresIn` and `CurrentRefreshToken` are all
read-only. You do not assign them, you read them once the flow has finished.

Token lifecycle is explicit rather than automatic:

```pascal
FOAuth.Refresh(FOAuth.CurrentRefreshToken);
FOAuth.Introspect(vToken);          // ask the server if a token is still valid
FOAuth.Revoke(vToken);              // invalidate it
```

## DPoP, when a bearer token is not enough

A plain bearer token is usable by anyone who steals it. DPoP binds the token to
a key your application holds, so a stolen token alone is not enough. Configure
it through `DPoPOptions`, then attach a proof to each request:

```pascal
vProof := FOAuth.GetDPoPProof('GET', 'https://api.example.com/me', FOAuth.AccessToken);
```

The proof is per request, computed from the method and URL, so it cannot be
generated once and reused. `DPoPNonce` carries the server-supplied nonce when
the authorization server requires one.

## Quickstart, JWT

The client builds and signs, the server validates:

```pascal
// client
FJWT := TsgcHTTP_JWT_Client.Create(Self);
// ... configure FJWT.JWTOptions ...
vToken := FJWT.Sign;

// server
FJWTServer := TsgcHTTP_JWT_Server.Create(Self);
FJWTServer.Users := FUsers;
FJWTServer.OnJWTUnauthorized := JWTUnauthorized;
```

The server side is event-driven. It exposes `OnJWTBeforeRequest`,
`OnJWTBeforeValidateToken`, `OnJWTBeforeValidateSignature`,
`OnJWTAfterValidateToken` and `OnJWTUnauthorized`. Use the before-validate hooks
to supply a key or accept a claim, `OnJWTAfterValidateToken` to inspect a token
that passed, and `OnJWTUnauthorized` to shape the rejection.

## Quickstart, WebAuthn

WebAuthn is a challenge and response in both directions, and the component gives
you the two option payloads the browser needs:

```pascal
// registration
vOptions := FWebAuthn.GetRegistrationOptionsResponse(vRequestPayload);
// ... browser creates the credential ...
FWebAuthn.ValidateRegistrationOptions(vBrowserPayload);
FWebAuthn.AddCredential(vCredential);

// authentication
vOptions := FWebAuthn.GetAuthenticationOptionsResponse(vRequestPayload);
FWebAuthn.ValidateAuthenticationOptions(vBrowserPayload);
```

You store the credential records yourself. The component validates, it does not
persist.

## Things that catch people out

- The OAuth2 token properties are read-only. Trying to assign `AccessToken` will
  not compile, and the fix is to run the flow rather than set it by hand.
- Credentials and endpoints live on two different option objects.
  `OAuth2Options` carries `ClientId`, `ClientSecret`, `Username`, `Password` and
  `GrantType`. `AuthorizationServerOptions` carries `AuthURL`, `TokenURL`,
  `RevocationURL`, `IntrospectionURL` and `DeviceAuthorizationURL`. Putting a
  client id on the second one compiles and then fails at the provider.
- `LocalServerOptions.RedirectURL` must match the redirect URI registered with
  the provider exactly, including scheme, port and trailing path.
- Refreshing is not automatic. Watch `CurrentExpiresIn` and call `Refresh`
  before it lapses, or handle the first 401 and retry.
- A DPoP proof is bound to one method and one URL. Reusing a proof across
  requests fails validation.
- The JWT server and the OAuth2 server both want a `TsgcHTTPServer_Users`. Use
  one shared instance rather than one each, or the two will disagree about who
  exists.
- WebAuthn requires a secure context in the browser, so localhost or HTTPS. It
  will not run over plain HTTP on a real hostname.

## Routing

- **Find a component**: `reference/components-index.md` lists every component, its `unit`, and its edition, grouped by Reg module.
- **Uses clause**: add the component's `unit:` value (shown on its API page) to your `uses` clause. Nothing compiles without it.
- **API detail**: `reference/api/<Component>.md` has the Properties, Events and Methods, each in both Delphi and C++Builder form.
- **Option / enum / event types**: property and event types link to `reference/types/<TypeName>.md`, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers.
- **Examples**: `examples/index.md` is the full demo catalog; `examples/<Component>.md` is a focused, real usage snippet for the most-used components.
- **Concepts**: `concepts/overview.md` (getting started + uses-clause rule) and `concepts/editions-and-features.md` (which components your edition includes).
- **Bundled resources**: `concepts/resources.md` lists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN.
- **Version history**: `reference/history.md` lists what changed in each sgcWebSockets release.

## Editions

Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or `concepts/editions-and-features.md`, before relying on a component.

Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.


