diff --git a/packages/docs/content/docs/guides/attestation-signing.md b/packages/docs/content/docs/guides/attestation-signing.md --- a/packages/docs/content/docs/guides/attestation-signing.md +++ b/packages/docs/content/docs/guides/attestation-signing.md @@ -104,6 +104,29 @@ | `key` | string | Key identifier (DID with fragment) | | `signature` | table | Contains `$bytes` (base64-encoded) | +## Security considerations + +`atproto.sign` exposes the instance's signing key to Lua scripts. Treat it as a +privileged capability: + +- **It signs exactly what you give it.** A signature only proves *"this HappyView + instance signed this content"* — it does **not** prove the content is authentic, + is present in anyone's repo, or was authored by any particular DID. Only sign + content you have already verified. +- **It's available to any script**, including ones that run on untrusted input — + record-event and label scripts (triggered by arbitrary firehose records) and + anonymous XRPC queries. In those contexts there is no authenticated caller, so + the signature's `repository` binding is empty. Don't sign untrusted input (a + firehose record, an anonymous request parameter) unless you intend the instance + to vouch for it. +- **Creating scripts requires the `scripts:manage` permission.** The signing key + is therefore only reachable by operators you have trusted with that permission — + grant it accordingly, and review scripts that call `atproto.sign`. + +If you need signatures scoped to a specific verified subject, have the script +verify the subject itself (e.g. confirm the record's `did` and content against the +source) before calling `atproto.sign`. + ## Next steps - [atproto API reference](../api-reference/lua/atproto-api.md#atprotosign) — `atproto.sign` and `atproto.verify_signature` parameter docs diff --git a/packages/docs/content/docs/api-reference/lua/atproto-api.md b/packages/docs/content/docs/api-reference/lua/atproto-api.md --- a/packages/docs/content/docs/api-reference/lua/atproto-api.md +++ b/packages/docs/content/docs/api-reference/lua/atproto-api.md @@ -214,6 +214,8 @@ Signs a record and returns the inline signature object. Only available when an attestation signer is configured — if no signer is configured, `atproto.sign` is `nil`. +> **Privileged capability.** This signs *exactly* the content you pass with the instance's key; it proves only that this instance signed the content, not that the content is authentic. Only sign data you have verified, and be careful in scripts that run on untrusted input (record-event/label scripts, anonymous queries). See [Attestation Signing — Security considerations](../../guides/attestation-signing.md#security-considerations). + | Parameter | Type | Description | | --------- | ----- | ----------------------- | | `record` | table | The record data to sign |