{"id":84846,"plugin_id":"plugin_asdk_app_6ad87c5571148191a56673a04a39d2ec","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-06T18:21:07.628Z","digest":"82931661ec3244c7257fdb3ecb7804065398e7561381bc6d7c1e31a6fb3b3112","against":null,"payload":{"description":"Set up SafeGrd for a database, from nothing to a verified backup. Covers signing in, installing the SafeGrd CLI on a host, enrolling the host, the first backup and its restore test, and the local MCP server. Use when the user wants to start protecting a database with SafeGrd. Also adds the experimental guard hook, which takes a locked backup before an agent runs a destructive command, but only when the user asks for it.","included_files":[],"name":"setup-safegrd","skill_md_contents":"---\nname: setup-safegrd\ndescription: Set up SafeGrd for a database, from nothing to a verified backup. Covers signing in, installing the SafeGrd CLI on a host, enrolling the host, the first backup and its restore test, and the local MCP server. Use when the user wants to start protecting a database with SafeGrd. Also adds the experimental guard hook, which takes a locked backup before an agent runs a destructive command, but only when the user asks for it.\n---\n\n# Set up SafeGrd\n\nYou can take the user from nothing to a backup that has been restored and checked, on the\nhost you are running on. Five things are the user's own, and you ask for them instead of\ndoing them: installing the CLI, signing in, choosing how the encryption key is managed,\npaying, and adding a database that SafeGrd backs up from its own machines. Everything else you run yourself.\n\nTwo steps leave something running or configured after this session: the daemon's service\n(step 5) and the local MCP server in `~/.codex/config.toml`. Before each one, tell the user what\nit writes and where, and go ahead only when they say yes. `safegrd daemon uninstall` removes\nthe service; the MCP server is one entry to delete.\n\n## The remote server\n\nThis plugin connects to `https://safegrd.dev/mcp` by signing the user in: Codex opens\nSafeGrd's sign-in page, the user approves for one organization, and the sign-in is listed\nunder Tokens in the console. If a SafeGrd tool answers `401`, the sign-in was revoked or\nexpired: ask the user to connect the plugin again. Never ask them for a token in the chat.\n\n## 1. Find out what there is\n\nCall `list_organizations` and `list_surfaces`. If the database the user means is already a\nsurface with a recent backup and a passed drill, say so and stop: there is nothing to set\nup. If the host you are on has the CLI (`safegrd doctor` runs), skip to step 4.\n\nA database with no host of its own (Supabase, Neon, Railway, Render) is backed up from\nSafeGrd's machines. Point the user to **Back up on SafeGrd** under Surfaces in the console,\nwhich takes the connection string on SafeGrd's page, never in the chat. Then watch for its\nfirst backup with `list_snapshots` and continue from step 6.\n\n## 2. Install the CLI\n\nInstalling the CLI is the user's step: you do not download or run an installer. Check\nfor it with `safegrd version`. If it is not found, ask the user to install it on this host\nfollowing https://safegrd.dev/docs/install (Homebrew: `brew install safegrd/tap/safegrd`)\nand tell you when it is done. Then check again. If it is installed in `~/.local/bin` and\nnot found, add `~/.local/bin` to `PATH` for the rest of the session.\n\n## 3. Sign in and enroll the host\n\nSigning in is the user's step. Two ways, and you drive both:\n\n- **A token the user already made** (in `SAFEGRD_TOKEN`, from Tokens in the console):\n  `safegrd enroll --token env:SAFEGRD_TOKEN`. Nothing to approve.\n- **The browser:** run `safegrd login --no-browser`. It prints a link and a code. Give both to\n  the user, tell them to open the link on any device and check that the page shows the same\n  code, and wait for the command to finish. Then `safegrd enroll`.\n\nBefore `enroll`, ask how the encryption key should be managed. Do not choose for them, and do not\ndescribe either as the weaker choice:\n\n- **SafeGrd-managed key** (the default): SafeGrd keeps the key sealed and releases it only\n  to the organization's enrolled hosts, so they can restore even after losing a host.\n- **Customer-managed key** (`--key-custody local`): only they can decrypt these backups.\n  They keep a copy of the key file somewhere safe.\n\n`enroll` generates the key pair, registers the host and prints its node id. With\n`--project <id or slug>` it goes into that project; without, the organization's default.\n\n## 4. Add the database and where backups go\n\n`safegrd init --database-url env:DATABASE_URL` writes the config with the database as its\nfirst surface. Read the URL from the app's environment or `.env`, never type it into the\nchat. Storage:\n\n- `--storage hosted`: SafeGrd's locked bucket, on a plan that includes it. Nothing to\n  create.\n- `--storage s3 --s3-bucket <bucket> --s3-region <region>`: the user's own bucket with\n  Object Lock on. The policy and the Terraform for one are at\n  `https://safegrd.dev/api/v1/storage/bucket-setup`; the user creates the bucket, you do\n  not have the credentials to.\n\nThen `safegrd doctor`. It checks the database account, the client tools (`pg_dump`,\n`mysqldump`, `mongodump`) and the storage, and prints what to fix. Fix what you can on the\nhost; a database account or a bucket is the user's.\n\n## 5. The daemon\n\n`safegrd daemon install` writes a systemd or launchd service that backs up on schedule and\nruns Fire Drills. Try it plainly first; if it refuses for want of root, run it with `sudo`\nwhen you can, otherwise `safegrd daemon install --user` for a service that runs at the\nuser's login. `safegrd daemon status` lists the surfaces it watches and their ids.\n\n## 6. Take the first backup and prove it\n\n`safegrd backup` takes the first backup now. Then prove it restores: `safegrd verify` runs\na Fire Drill of the newest snapshot. Report one fact per line: the surface, the snapshot\nid, locked until when, and the drill result. A drill that fails is the thing to fix before\nanything else; do not call the setup done.\n\nFrom a chat without a shell on the host, the same two steps are `request_backup` and\n`request_drill`, read back with `list_snapshots` and `list_drills`.\n\n## The local MCP server\n\nOn a host with the CLI, the local server backs up, verifies and restores with that host's\nconfig and key. A restore writes only into a new or empty target. Add it to\n`~/.codex/config.toml`:\n\n```toml\n[mcp_servers.safegrd-local]\ncommand = \"safegrd\"\nargs = [\"mcp\"]\n```\n\n## The guard hook (experimental)\n\nAdd the hook only when the user asks for it by name or asks for\nbackups before destructive commands. Do not offer it or add it as part of setup. It goes in\nthe project's `.codex/hooks.json`; say so and wait for a yes before writing it.\n\nWith the hook, Codex takes a locked snapshot before any command that can destroy\ndata (`DROP`, `TRUNCATE`, `DELETE` without `WHERE`, `dropdb`, `terraform destroy`,\n`prisma migrate reset` and others: `safegrd guard --list`). If the snapshot fails or is not\nlocked, the command is blocked. A command that matches nothing runs with no backup.\n\nA locked snapshot from the last 30 minutes covers a matching command. Without one, the hook\nstarts a backup and waits up to 20 seconds. If the backup is still running then, the command is\nblocked with a message to run it again shortly, and the backup carries on. When you see that\nmessage, wait a minute and run the same command again. It goes through once the snapshot is\nlocked. After a command goes through, the hook tells you the snapshot id and the restore\ncommand. Pass them on to the user.\n\nIt goes in the project, not here, because it names the surface that project works on. Get\nthe surface id from `safegrd daemon status`, then add this to the project's\n`.codex/hooks.json`:\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"safegrd guard --hook codex --surface <surface id> || exit 2\",\n            \"timeout\": 60\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\nThe `|| exit 2` blocks the command if `safegrd` cannot run at all, for example when it is not\non the `PATH` Codex runs hooks with. Check the hook with\n`safegrd guard --matches \"DROP TABLE users\"`, which takes no backup, and with\n`safegrd doctor --agent-proof`, which checks that an agent on this host cannot delete the\nbackups. Details: https://safegrd.dev/docs/agents.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}