> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runlayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Central Grok Bot setup

> Deploy Grok Bot monitoring with Enterprise Team Setup, provision credentials, and verify each member's coverage.

Use this guide to prepare one centrally managed hook installation for your Grok
Bot organization. An administrator distributes the helper and hook configuration;
each member still provisions a credential on their cloud computer.

<Note>
  Grok Bot monitoring is experimental, disabled by default, and monitor-only.
  Runlayer has verified native hooks against a local stack. Production ingestion
  and Enterprise Team Setup distribution still need validation. Pilot this rollout
  before relying on organization-wide coverage. There is no validated Runlayer
  workflow for centrally pushing the hook credential to every member.
</Note>

## What is configured centrally

| Component                    | Owner and scope                                                        |
| ---------------------------- | ---------------------------------------------------------------------- |
| Runlayer monitoring switches | Runlayer admin, once per Runlayer organization.                        |
| Helper and hook registration | Grok admin, through Enterprise Team Setup for each Grok team in scope. |
| Hook credential              | Provision securely on every member's cloud computer.                   |
| Coverage verification        | Confirm recorded native activity for every member in the rollout.      |

[Grok Bot gives each member one cloud computer](https://cursor.com/docs/grok-bot/teams).
That member's Bots share it, so install once per member, not once per Bot. AI Watch
or MDM on a member's laptop does not install these cloud hooks.

Team Setup requires Enterprise and a team administrator. Without it, repeat the
[single-user setup](/shadow-ai/grok-bot) for each member. Availability of Grok Bot
on a Teams plan does not imply access to Team Setup.

## 1. Prepare Runlayer and the pilot

1. Identify the Grok teams and members in scope. Start by testing the generated
   installer on one pilot cloud computer before saving a team-wide manifest.
2. In **Settings → Organization API Keys**, create keys with only **Grok Bot
   Hooks** access. We recommend a separate key per member's computer so you can
   revoke one installation independently. These remain organization API keys;
   their names do not establish the actor's identity in recorded activity.
3. In **Settings → Agent session monitoring → Cloud agent hooks**, enable
   **Grok Bot** and save. **Full session scanning APIs** must also be enabled.
   Enabling these switches accepts events; it does not deploy anything.
4. Confirm each cloud computer can reach
   `https://YOUR-TENANT.runlayer.com/api/v1/hooks/grok-bot/events`.
   If Grok network controls restrict destinations, allow your Runlayer tenant.

Using a shared hook key is possible, but revoking it affects every computer using
it. Keep an administrator-owned inventory of member, key name, installer revision,
and verification date. Do not put key values in this inventory.

## 2. Build the Team Setup manifest

On your administrator workstation, save the Python helper from
[Add the hook helper](/shadow-ai/grok-bot#2-add-the-hook-helper) as
`runlayer_hook.py`. Replace its `COLLECTOR_URL` with your tenant's literal HTTPS
URL. The helper reads `RUNLAYER_GROK_BOT_HOOK_KEY` at runtime; never embed a key.

Save the following as `build_grok_manifest.py` beside that file. It generates
`runlayer-grok-team-setup.json` for the Team Setup editor and `runlayer-grok-setup.sh`
for the pilot. Neither generated file contains a credential.

The installer preserves unrelated hooks, backs up the original configuration once,
and registers the three native tool events verified by Runlayer. It can be rerun
without duplicating those registrations. If you previously installed Runlayer
under a different helper path, remove that old registration before using this one.

```python theme={null}
import json
from pathlib import Path

helper_source = Path("runlayer_hook.py").read_text()
compile(helper_source, "runlayer_hook.py", "exec")
if "YOUR-TENANT" in helper_source:
    raise SystemExit("Set COLLECTOR_URL in runlayer_hook.py before generating.")

setup = "#!/usr/bin/env bash\nset -euo pipefail\numask 077\n"
setup += "python3 - <<'RUNLAYER_SETUP'\n"
setup += f"HELPER_SOURCE = {helper_source!r}\n"
setup += r'''
import json
import os
import shlex
import tempfile
from pathlib import Path

helper_path = Path.home() / ".grokbot" / "runlayer_hook.py"
config_path = Path.home() / ".cursor" / "hooks.json"
original = config_path.read_text() if config_path.exists() else None
config = json.loads(original) if original is not None else {"version": 1, "hooks": {}}
if not isinstance(config, dict) or config.get("version") != 1:
    raise SystemExit("Expected hooks.json version 1; inspect the existing file.")
hooks = config.setdefault("hooks", {})
if not isinstance(hooks, dict) or any(
    not isinstance(entries, list)
    or any(not isinstance(entry, dict) for entry in entries)
    for entries in hooks.values()
):
    raise SystemExit("Unexpected hooks.json shape; inspect the existing file.")

command = shlex.join(["python3", str(helper_path)])
for event in ("preToolUse", "postToolUse", "postToolUseFailure"):
    entries = [entry for entry in hooks.get(event, []) if entry.get("command") != command]
    entries.append({"command": command, "timeout": 3, "failClosed": False})
    hooks[event] = entries

def atomic_write(path, content):
    path.parent.mkdir(parents=True, exist_ok=True)
    with tempfile.NamedTemporaryFile(mode="w", dir=path.parent, delete=False) as output:
        temporary = Path(output.name)
        output.write(content)
    try:
        os.replace(temporary, path)
    finally:
        temporary.unlink(missing_ok=True)

backup_path = config_path.with_name("hooks.json.before-runlayer")
if original is not None and not backup_path.exists():
    atomic_write(backup_path, original)
atomic_write(helper_path, HELPER_SOURCE)
atomic_write(config_path, json.dumps(config, indent=2) + "\n")
print("Runlayer helper installed. Provision the secret and verify native activity.")
'''
setup += "\nRUNLAYER_SETUP\n"

manifest = {
    "manifestId": "runlayer-grok-monitoring",
    "entries": [{"id": "install-runlayer-hooks", "setup": setup}],
}
Path("runlayer-grok-setup.sh").write_text(setup)
Path("runlayer-grok-team-setup.json").write_text(json.dumps(manifest, indent=2) + "\n")
```

Run `python3 build_grok_manifest.py` on your workstation. Review the generated
files: they should contain your tenant URL and the helper source, with no secrets.
The cloud installer requires Python 3 and runs as the member's cloud-computer user.
It does not install dependencies or download code.

For the pilot, copy `runlayer-grok-setup.sh` to the pilot's cloud computer and run
`bash runlayer-grok-setup.sh` there. Complete steps 3 and 5 for that member before
publishing the manifest to the team.

## 3. Provision credentials for each member

Give each member their assigned scoped key through your organization's approved
secret-sharing process. On their Grok cloud computer, have them use
**Secrets → Add secret** or a secure secret-entry card to save it as
`RUNLAYER_GROK_BOT_HOOK_KEY`. Follow
[Create a scoped key](/shadow-ai/grok-bot#1-create-a-scoped-key) for the tested flow.

<Note>
  Team Setup distributes files and commands. Its manifest is plain text, not a
  secret store. Keep credentials out of the manifest, helper, ordinary Bot chat,
  and shell history. Runlayer does not provide automatic fleet credential enrollment
  for this integration. Each member must complete the secure entry step.
</Note>

An administrator saving a key on their own computer does not provision it on
another member's computer. Missing credentials cause the helper to skip upload
while allowing the Bot to continue. A successful installation therefore does not
mean monitoring is active.

Check delivery from the actual hook process. An ordinary Shell process may not
receive a secret that is available to native hooks. Never print the key to debug it.

## 4. Publish the central installation

After the pilot records activity successfully:

1. In the Cursor dashboard, open **Grok Bot → Team Setup** for the intended team.
2. Create a manifest, switch the editor to **JSON**, and paste the generated
   `runlayer-grok-team-setup.json`.
3. Save it. Repeat for other Grok teams in the rollout.

[Team Setup](https://cursor.com/docs/grok-bot/private-networks#how-team-setup-runs-your-scripts)
runs at computer startup and refreshes roughly daily. This manifest omits the
optional check script so changes to the embedded helper reapply on refresh.
Installation is repeatable. Coordinate a computer reset or recreation with the
member if an immediate application is needed; running work can be interrupted.

Team Setup has no fleet view of script results. Track installation and recorded
activity for each member rather than treating **Save** as rollout completion.

## 5. Verify coverage for every member

Use a fresh Bot after installing hooks; existing executors may cache their prior
configuration. Have each member run a harmless, uniquely labeled command such as
`printf 'runlayer-grok-check-ROLL_OUT_LABEL\n'` on their cloud computer.

For each member, record these results in the rollout inventory:

| Check                    | Required evidence                                                                                                                    |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| Installation             | The expected helper source and native hook registrations are present.                                                                |
| Credential and transport | A native hook authenticates to the intended Runlayer tenant.                                                                         |
| Recorded activity        | **Sessions → Grok Bot** shows the unique test marker and paired tool input/output.                                                   |
| Grouping                 | A second call and a second Bot produce the expected entries in the applicable [identity mode](/shadow-ai/grok-bot#session-identity). |

When native Bot IDs are empty, expect **Grok tool activity — Bot unknown**, one
entry per tool call. A successful test proves that member's tested path works;
it does not establish complete conversation coverage or actor attribution.
The key name and rollout inventory do not fill in missing provider identity.

Use the [native verification and troubleshooting steps](/shadow-ai/grok-bot#4-enable-and-verify)
for failures. HTTP 200, an explicit allow response, and installed files alone do
not prove that activity was recorded. Monitoring also does not imply tool blocking
or AgentGuard behavioral threat scoring.

## Onboarding, updates, and removal

* **New member:** confirm the central installation has applied, provision that
  member's key, and repeat the coverage checks before marking them covered.
* **Helper update:** revise the local helper, regenerate the manifest, test the
  installer on the pilot, then update the existing manifest. Verify a fresh Bot
  after application; an existing executor can retain old hooks.
* **Key rotation:** provision the replacement through the secure entry flow,
  verify native activity, then revoke the old key. Rotate between tool calls:
  in tool-only mode, changing keys changes the pre/post pairing boundary.
* **Member leaves:** revoke their dedicated hook key and remove their saved
  secret. A shared key requires rotation on the remaining computers too.
* **Remove monitoring:** disable Grok Bot in Runlayer and revoke its hook keys.
  Remove the Team Setup manifest to stop reinstalling it, then remove only
  Runlayer's hook entries on each cloud computer. Removing the manifest alone
  does not undo installed files. Keep an allow-only helper at its existing path
  until cached executors no longer invoke it. Preserve unrelated hooks; the
  initial backup may predate other administrators' later changes.
