本文へ移動
cccskills
無料GitHub で公開

documents-app-integration

Implement the separately maintained Documents React client for AuthCrunch encrypted storage, recovery keys, chunk upload/download, recipient sharing, and safe session handling. Does not implement manager/profile APIs or provision the backend.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md16.7 KB
  • agents/openai.yaml268 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Documents React Integration

This skill is intended for the external React application's agent to read from its AuthCrunch library checkout. Keep implementation in the task's authorized repository; reading this skill does not authorize edits to sibling checkouts. For an app-local AGENTS.md, add a route pointing to this skill at the actual library checkout location. Do not copy a machine-specific path into the app's source or pretend the compiled app already ships in AuthCrunch.

Read the crypto/wire contract and use the portable crypto.mjs module. Vendor a reviewed version into the frontend's source or bundle it via an explicit build dependency. It is plain ESM using native Web Crypto with no third-party runtime dependencies. It is not currently served by a production asset route. Preserve the protocol and test against the interoperability vector. Use the shared Mermaid sequences and design rationale to follow enrollment/unlock, encrypted upload/download, sharing, revocation and reset. They distinguish local crypto and required React UX from implemented server behavior, and explain retries, key context and account-switch protection. Keep these sequences and the protocol aligned when changing a client workflow.

The OpenAPI source describes the API. Its rendered /#tag/documents catalogue documents every operation's fields, request/response messages, state transitions and retry behavior. Every operation has its own method/resource path, expected response schema, parameter/body examples and native Test Request console. No plaintext-upload endpoint, username-directory endpoint or public share link exists. The manager application and profile application are separate products.

Session and capability discovery

The host must explicitly enable APIConfig.DocumentsEnabled; the feature is disabled by default and independent of Admin/Profile. A configured storage path alone does not enable it.

Configure the exact portal origin/base path via the embedding app's trusted bootstrap; API base is <basePath>/api/documents. Every operation has its own method/resource path; use the complete operation table. GET reads; PUT registers keys and writes immutable manifests, chunks or grants; DELETE removes documents or grants; POST allocates, commits and resets. Paths use fetch, never get. For example, fetch a chunk with GET /api/documents/file/{id}/chunk/{idx}/fetch and delete an owned file with DELETE /api/documents/file/{id}/delete. Select from the fixed catalogue; never accept a complete operation URL from untrusted file data. Validate and encode individual path parameters. Use canonical decimal chunk indices without leading zeros. List files with GET /api/documents/files and allocate uploads with POST /api/documents/files/allocate. Own-key operations use /keys/fetch, /keys/register and /keys/reset beneath the API base; recipient lookup remains /key/{user_id}/lookup. The only query is file listing's optional after cursor.

Use relative same-origin fetch URLs and credentials: "same-origin". GET, DELETE and commit have no body. Other writes require Content-Type: application/json and only their documented direct fields. Do not send operation/payload wrappers or repeat resource path parameters in a body. Every success is HTTP 200 with resource fields directly in the response. Validate them against the selected method/path schema. There is no operation or result wrapper. Mutations without resource data return {"success":true}; require the literal boolean true. Failures have an HTTP error status and {status,message}. See the linked protocol's operation table for exact payloads. Bound response reads to 2 MiB; reject oversized or malformed JSON.

For example, capability discovery sends:

const response = await fetch(`${apiBase}/bootstrap`, {
  method: "GET",
  credentials: "same-origin",
  signal,
});
// Read a bounded response, check HTTP status, then validate its direct fields.

Do not store JWTs in JavaScript storage or introduce a token in URLs. The API needs both a valid portal cookie and server-cached local browser login evidence. Do not use access-only JSON login as a substitute. A document recovery key is an additional client-only secret, independent of the portal password and MFA.

GET /bootstrap, verify protocol === "authcrunch-documents", obtain the portal ID, exact local user ID and limits, then key.fetch. Distinguish its 404 (not enrolled) from the bootstrap's 404 (feature unavailable). Handle 401 through a fresh portal browser login. When the host already provides refresh/session coordination, reuse it for expiry; do not invent a competing refresh loop or repeatedly refresh revoked identity evidence. Follow the host's validated return-navigation contract. 403 is a permission/origin/realm failure; 503 is temporary storage unavailability.

Never persist decrypted documents or keys in localStorage, service-worker caches, analytics, error monitoring payloads, logs, query strings or React debug tools. Keep secrets out of React component state where a dedicated worker can own them. On account/portal change, logout or lock, abort requests, clear decrypted state, terminate the crypto worker, and revoke object URLs. Bootstrap user ID/portal must match the unlocked vault before every operation; transformed display names are not ownership identifiers.

Enrollment, unlock, and key loss

enroll(bootstrap) returns {registration,recoveryKey}. The recovery key is a random 256-bit secret encoded as 43-character base64url. Require the user to save it and confirm the backup before key.register with {key:registration} only. Show the key locally; do not send it in telemetry or application API state. Explain that anyone with this key and the encrypted vault can decrypt the user's files and received shares. Login-password reset cannot recover document keys.

On later devices, fetch the registration and call unlock(bootstrap, registration, recoveryKey). Retain the non-exportable private CryptoKey in memory. Wrong keys and tampered vaults must stop before showing files. Never derive a recovery key from the portal password or accept a weak human passphrase in its place; the client has no passphrase KDF.

On lost recovery key, present a deliberate destructive-reset flow. Explain that key.reset with {user_id:confirmedUserID,key_id:confirmedKeyID} removes all owned documents, their shares, and received grants, then allows fresh enrollment; it does not recover plaintext or affect other owners' stored files. Require an explicit user confirmation in the UI before sending that deletion. Capture the user ID and fingerprint from the registration shown in the confirmation UI; do not replace them with a later bootstrap/key value before sending. A cookie account switch or changed registration causes 409 and must invalidate the confirmation. Never automatically retarget or reconfirm a reset after a conflict. This server check closes the gap between a UI check and another tab switching cookies. A different key.register registration returns 409. If an enrollment response is lost, key.fetch and reconcile the fingerprint and vault before retry. Never auto-reset after an unlock or network error.

Upload workflow

  1. Read File.size locally; call describeSize(size) and compare its ciphertext size against the server limit. Send file.allocate with only {size,chunks}. Keep the returned ID/owner/size/chunks immutable. Allocation is not idempotent; after a lost response, inspect the owner's pending list. Concurrent tabs can allocate indistinguishable descriptors: never guess ownership of an operation from size/time or automatically delete a matching candidate. Present uncertain pending entries for deliberate abandonment; fresh attempts use a fresh ID/key.
  2. Call prepareUpload(bootstrap, descriptor, ownRegistration, {name:file.name,type:file.type,size:file.size}). It returns manifest, encryptChunk(idx,bytes) and dispose().
  3. PUT {manifest} to /file/{id}/manifest. Read each Blob slice of at most 1048576 plaintext bytes, encrypt once, then PUT {ciphertext:encode(encryptedBytes)} to /file/{id}/chunk/{idx}/put. No FormData, plaintext metadata or data URLs go to the API. Limit concurrent encryption/network work to bound memory.
  4. Retry uncertain writes using the exact buffered ciphertext. The module rejects encrypting the same idx twice. Do not mix chunks from different prepareUpload calls. If exact upload state is lost on reload, delete/abandon that allocation and allocate a fresh document/key. chunk.fetch does not support pending files.
  5. POST /file/{id}/commit without a body after every chunk succeeds. Identical commits/chunk and manifest writes are idempotent; conflicting ciphertext returns 409. Check the descriptor after an uncertain commit. Finally dispose the upload key buffer.

Crypto calls snapshot input buffers and the context fields they use before their first await. You may clear or reuse your own Uint8Array after starting a call; the helper clears only its owned copies. This includes Node Buffers. Keep concurrency bounded because each pending call owns a copy. This snapshot is not cancellation: dispose prevents new chunk encryption but already started work may finish. After logout or an account switch, discard late results and stop network writes even if the cryptographic promise succeeds.

Cancel aborts requests and may DELETE /file/{id}/delete without a body for the pending owner file. Pending uploads have an absolute TTL; activity does not extend it. Expired uploads return 404. Handle 507 as quota exhaustion, retaining the user's original local file. Empty files still upload one 16-byte ciphertext/tag chunk. Files and metadata are immutable; editing means allocating a new file/key. Revocation-sensitive new versions must use a new key and only wrap it for current recipients.

List and download workflow

GET /files without a body or query for the first page. Follow next using /files?after=<next>. Lists omit metadata/envelopes, so GET /file/{id}/fetch with bounded concurrency for display. After unlock, call unwrapKey(bootstrap, detail, ownRegistration, privateKey) and decryptMetadata(...). Render filenames as text; never use decrypted metadata as HTML or a navigation URL. This API supports flat documents, not server-side folders or plaintext search; any name search happens locally after decryption.

GET every expected /file/{id}/chunk/{idx}/fetch without a body, decode its ciphertext using the module's canonical base64url decoder, and call decryptChunk(bootstrap, detail, documentKey, idx, ciphertext). Verify all tags, indices, lengths and the metadata plaintext size before marking the download complete. Fail closed on corruption/truncation; never offer partial data as a successful file. A bounded Blob fallback can use URL.createObjectURL, an anchor with a sanitized basename in download, and timely URL.revokeObjectURL after the browser accepts the save. Use application/octet-stream for the download; avoid inline execution or preview of uploaded HTML/SVG. For large files, use a supported local streaming save flow with explicit partial-file cleanup on failure.

The client cannot guarantee secure erasure of strings or browser-managed memory. Clear owned Uint8Arrays with fill(0), release CryptoKeys, and stop workers when finished. Avoid buffering an entire large file solely to make an object URL.

Sharing

Use a JSON share code with exactly these string fields:

{"protocol":"authcrunch-documents","portal_id":"<bootstrap.portal_id>","user_id":"<bootstrap.user_id>","key_id":"<registration.key_id>"}

The portal ID and key fingerprint are canonical 43-character base64url values. user_id is the exact canonical lowercase non-nil UUID (36 characters) from the local user database. Never substitute email, username, a hash or an external provider subject. Future federation-to-local mapping is not implemented here. Bound pasted codes to 1 KiB and reject unknown fields, invalid identifiers and unsupported protocols. This is public identity data, not a secret link or a bearer grant. Display the portal and recipient fingerprint for confirmation. Never include recovery/document keys or session credentials.

Compare the code's portal ID against the current bootstrap, then GET /key/{user_id}/lookup and verify its user_id and full fingerprint match the code. The public-key response has no portal ID field. Refuse changed keys and require an explicitly confirmed new code. Owner unwraps the existing document key, calls wrapKey(bootstrap, detail, recipientPublicRegistration, documentKey) and sends PUT /file/{id}/share/{user_id}/put with only {envelope}. Only owners can share. Recipients receive read access and use their own vault/key; no private key is exchanged. GET /file/{id}/share/list returns recipient UUIDs only. DELETE /file/{id}/share/{user_id}/delete without a body stops future downloads. Clearly explain that recipients can keep or redistribute plaintext already read.

Product and integration limits

Present encryption as protection against passive traffic/content inspection, with a server that stores ciphertext. Operation paths, resource IDs and list cursors are visible in URL logs. Decrypted TLS messages also reveal sharing metadata and ciphertext sizes; do not promise otherwise. Do not promise protection against modified JavaScript, compromised browsers/devices, a malicious recipient, traffic analysis, or file recovery without the key. The protocol is public; its security relies on keys rather than obscurity. Recovery-key compromise exposes historical documents; there is no forward-secrecy claim.

The Go repository currently embeds only the existing Profile SPA. This work adds the Documents API and reusable crypto module, not an embedded Documents build or new page route. App build packaging, hosting, route reservation, CSP and frontend links must be integrated explicitly when the external React app is ready; do not place a source tree into the compiled pkg/authn/ui/profile directory or run the profile-only asset refresh script for Documents.

Acceptance tests

Use actual browser Web Crypto and real TLS portal login with two distinct users. Assert actual network requests use each documented method and resource path, with only the optional list cursor in queries. GET, DELETE and commit send no body; other writes send direct JSON without repeated path parameters. Cover rejection of obsolete get paths, operation/payload wrappers and fields that do not belong to the selected operation. Cover enrollment backup/unlock on another device, zero-byte and multichunk files, owner and recipient decryption, outsider rejection, pagination, retry of identical ciphertext, interrupted uploads, stale key fingerprints, reset, revocation, logout, 401 recovery and account switches. Check URLs and decoded TLS-visible request bodies for plaintext filenames, file content, recovery keys and unwrapped keys. Tamper with ciphertext, metadata, portal/owner/document IDs, sizes and chunk ordering and require decryption failure. Verify safe filename rendering and completed download contents. Start encryption/wrapping, immediately clear the input buffers, and verify the original bytes still decrypt; mutate caller-owned context during a pending operation and verify that it uses the call-entry snapshot. Run the independent protocol vector along with the frontend tests. Delay an upload while its login evidence is revoked, and delay a share while the recipient resets and reenrolls. The first request must return 401 without writing a chunk; the second must return 409 without creating a grant for the old fingerprint. Retain the user's source file and require fresh login or explicitly confirmed recipient identity before starting new work. The backend's reference Chrome journey is documents_browser_e2e.cjs. It checks an HttpOnly cookie bootstrap using a session established by real HTML login, then uses bearer transport for isolated multi-user crypto/API assertions. The external app must additionally exercise its own login navigation, cookie-only journey, account switching and session-expiry UI; the reference is not a React UI.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

authdb

無料

Maintain the standalone cmd/authdb server, pkg/httpserver listener and portal routing, HTTP configuration parser, TLS, shutdown, executable tests, and deployment guidance. Use authdbctl for the management client.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

authdbctl

無料

Maintain cmd/authdbctl commands, flags, configuration, terminal input, management retries, output, and executable E2E tests. Use authentication-client for the reusable portal login protocol.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain or embed pkg/authclient for portal login, password/TOTP and API-key authentication, native credential transport, configuration parsing, and credential files. Covers authdbctl login wiring; management commands and the admin API have separate owners.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain conditional authentication challenge policies, reusable authchal and user-transform FromDirectives parsers, safe claim substitution, GitHub ID/organization transforms, registered-factor inventory, passwordless WebAuthn selection, verified AMR access claims, and policy revalidation across portal login, refresh, OIDC, and direct authentication.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain portal cookie configuration, reusable cookie directive parsing, common prefixes and explicit names, domain attributes, factory issuance/deletion, and cookie interoperability with OIDC, refresh, OAuth, and gatekeepers.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain optional cross-device portal login, its directive parser, QR and polling UI, approving-browser binding, single-use transfers, MFA and provider evidence, logout invalidation, and TLS/browser tests.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

greenpau のスキルをすべて見る

このスキルの問題を報告する