Authentication via Cuitty Safe
Scrape stores no secrets. The engine depends on a CredentialProvider, and the live integration can wrap @cuitty/safe/client through createSafeCredentialProvider(config).
Credential Provider
The provider surface is:
| Method | Purpose |
|---|---|
resolve(auth) | Resolve safe-ref or safe-refs into values for the login flow. |
writeSession(ref, storageState) | Persist captured Playwright storage state. |
readSession(ref) | Hydrate a previously captured session. |
health() | Report ok, needs-auth, or unavailable. |
Safe Provider
You can inject a Safe client for tests or let the provider lazy-load @cuitty/safe/client at runtime.
import { createSafeCredentialProvider, type SafeClientLike } from "@cuitty/scrape/auth/safe";
const safeClient = {
secrets: {
async read(ref: string) {
return { value: ref === "safe://example/password" ? "s3cr3t" : undefined };
},
async write(ref: string, value: { value: string }) {
console.log("stored", ref, value.value.length);
},
},
async resolve(refs: string | string[]) {
const list = Array.isArray(refs) ? refs : [refs];
return {
resolved: Object.fromEntries(list.map((ref) => [ref, "resolved-value"])),
failures: [],
};
},
async health() {
return { providers: [{ status: "ok" }] };
},
} satisfies SafeClientLike;
const credentials = createSafeCredentialProvider({ client: safeClient });
const resolved = await credentials.resolve({ kind: "safe-ref", ref: "safe://example/password" });
console.log(resolved.resolved.value);
Auth Reference Types
ScrapeAuthRef supports:
| Kind | Shape | Purpose |
|---|---|---|
none | { kind: "none" } | No auth. |
safe-ref | { kind: "safe-ref", ref } | One credential value. |
safe-refs | { kind: "safe-refs", refs } | Named credentials for multi-field flows. |
session | { kind: "session", sessionRef } | Reuse captured storage state. |
Session Capture
Set captureSessionAs on a request. After a successful run, the engine calls session.storageState() and persists it with credentials.writeSession(ref, state).
import { createScrapeServer } from "@cuitty/scrape/server";
import { createMockCredentialProvider } from "@cuitty/scrape/auth";
const credentials = createMockCredentialProvider();
const server = createScrapeServer({ credentials });
await server.run({
url: "https://example.com",
intent: "Read the page after login",
captureSessionAs: "safe://sessions/example",
});
const saved = await credentials.readSession("safe://sessions/example");
console.log(Boolean(saved));
Session Reuse Flow
Use auth: { kind: "session", sessionRef } on later runs. The engine reads the stored state and calls session.hydrate(storageState) before navigation.