Pds: PdsSessionService DI registration uses an ephemeral signing key — all sessions invalidate on restart #37

Open
opened 2026-06-10 22:46:51 +00:00 by Grandiras · 0 comments
Owner

AddAtProtoPds() registers PdsSessionService via plain DI:

services.AddSingleton<PdsSessionService>();

Its constructor is PdsSessionService(PdsOptions options, byte[]? signingKey = null) — DI can't supply byte[], so every process start generates a random HMAC signing key, which invalidates all access/refresh tokens on every restart/redeploy. For a production PDS that means all clients are silently logged out whenever the container restarts.

Workaround (what Updraft does): re-register after AddAtProtoPds so the last registration wins:

builder.Services.AddSingleton(sp =>
    new PdsSessionService(sp.GetRequiredService<PdsOptions>(), Convert.FromBase64String(jwtSecret)));

Suggestion: add PdsOptions.SessionSigningKey (base64) and have the default registration use it when set, with a startup warning when falling back to an ephemeral key.

`AddAtProtoPds()` registers `PdsSessionService` via plain DI: ```csharp services.AddSingleton<PdsSessionService>(); ``` Its constructor is `PdsSessionService(PdsOptions options, byte[]? signingKey = null)` — DI can't supply `byte[]`, so every process start generates a **random HMAC signing key**, which invalidates all access/refresh tokens on every restart/redeploy. For a production PDS that means all clients are silently logged out whenever the container restarts. Workaround (what Updraft does): re-register after `AddAtProtoPds` so the last registration wins: ```csharp builder.Services.AddSingleton(sp => new PdsSessionService(sp.GetRequiredService<PdsOptions>(), Convert.FromBase64String(jwtSecret))); ``` Suggestion: add `PdsOptions.SessionSigningKey` (base64) and have the default registration use it when set, with a startup warning when falling back to an ephemeral key.
Sign in to join this conversation.
No description provided.