30-day pilot runbook for IT
This runbook takes an IT team from an empty server to a running pilot that covers a few hundred to a thousand people on Windows and macOS, with Chrome and Edge. It assumes you install Shield360 yourself with Docker Compose and push software with Intune (Windows) and Jamf (macOS). Each step says how to check it worked before you move on.
Plan the pilot
Section titled “Plan the pilot”| Week | Goal |
|---|---|
| Before day 1 | Server, DNS name and TLS certificate ready. Trial licence received. An IdP application and the pilot groups created. |
| Week 1 | Shield360 running, SSO working, collectors and the extension on a first wave of 20 to 50 machines. Vendor connectors added. |
| Weeks 2 to 3 | Roll out to the full pilot group. Alerts routed to Teams or Slack. Policies tuned from what the first wave showed. |
| Week 4 | Review findings and costs, export the end-of-pilot report, decide. |
You need:
- A Linux host with Docker Engine 24 or later, 4 CPU cores, 8 GB of memory and 40 GB of free disk. Give it more disk if the pilot covers more than a few hundred people.
- A DNS name for it, for example
shield360.corp.example.com, and a TLS certificate your managed devices trust. Put a reverse proxy (nginx, Traefik, an internal load balancer) in front of port 3000. Browsers, the extension and the collector all reach Shield360 over this one address. - Registry access and a trial licence from Shield360. See Trial licences.
- Rights to create an application in your identity provider, a Windows PowerShell script in Intune, a Jamf policy, and browser policies.
Check Network requirements with your network team before day 1. Devices need to reach only your Shield360 server.
1. Install with Docker Compose
Section titled “1. Install with Docker Compose”aws ecr get-login-password --region us-east-2 \ | docker login --username AWS --password-stdin 959429674945.dkr.ecr.us-east-2.amazonaws.comIMAGE=959429674945.dkr.ecr.us-east-2.amazonaws.com/shield360-selfhosted:2.1.0docker pull "$IMAGE"docker create --name shield360-bundle "$IMAGE"docker cp shield360-bundle:/app/selfhost ./shield360docker rm shield360-bundlecd shield360Use the version Shield360 gave you in place of 2.1.0.
cp .env.example .env && chmod 600 .envReplace every CHANGE_ME with openssl rand -hex 32, then set:
| Variable | Value |
|---|---|
SHIELD360_VERSION | The version you pulled, e.g. 2.1.0 |
SHIELD360_PUBLIC_URL and NEXTAUTH_URL | https://shield360.corp.example.com |
SHIELD360_ADMIN_EMAIL, SHIELD360_ADMIN_PASSWORD | The first administrator (a break-glass account) |
SHIELD360_LICENSE | The trial licence, the single line starting S360L1. |
.env.example lists every other setting with a comment: single sign-on,
alert email, model prices, AI providers and evidence signing. Back up
.env with the data: SHIELD360_VAULT_ENCRYPTION_KEY decrypts stored
credentials.
docker compose up -ddocker compose logs -f shield360Wait for the health check to pass (docker compose ps shows healthy).
The start-up log also says whether the image can force-install the browser
extension:
✅ Browser extension: signed .crx 0.1.123 (ID …) is served for device-management force-installIf it says the extension is not signed, stop and ask Shield360 for a signed image before you plan the browser rollout (step 6).
Check: open https://shield360.corp.example.com, sign in as the first
administrator, and open Settings → Licence. It shows the trial as
Trial — ends <date>, with every module.
2. Licence
Section titled “2. Licence”The licence in SHIELD360_LICENSE is checked offline. To replace it, change
.env and run docker compose up -d, or upload one in Settings → Licence
(only when SHIELD360_LICENSE is empty). A trial ends after 30 days unless
Shield360 set another date, then has 7 days’ grace before configuration goes
read-only. Collection never stops. When the pilot becomes a purchase, install
the full licence over the trial: data, settings and enrolled machines are kept.
See Self-hosted licence.
3. Single sign-on
Section titled “3. Single sign-on”Pick one:
- In Entra ID, create an App registration with the web redirect URI
https://shield360.corp.example.com/api/auth/callback/sso, and a client secret. Add a groups claim if you will map groups to roles. - In
.env:Terminal window SSO_OIDC_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0SSO_OIDC_CLIENT_ID=<application (client) id>SSO_OIDC_CLIENT_SECRET=<client secret>SSO_OIDC_ROLE_MAP={"<admins group id>":"admin","<security group id>":"compliance"} docker compose up -d.
Setting all three closes the email and password form. Keep the first administrator’s email the same as their IdP email so their account is reused. See Single sign-on.
Open Settings → Security and follow SAML single sign-on. Add SCIM provisioning to create and remove members from your IdP.
Under Organisation → Members → Roles, choose who is admitted: By invitation only for a small admin group, or Anyone your identity provider signs in when the IdP application assignment is already the gate.
Check: sign in from a private window with a pilot administrator’s IdP account.
4. Create an install key
Section titled “4. Create an install key”Open Settings → Collection & deployment and create an install key named
for the pilot, for example pilot-2026-11. Copy it now: it is shown once.
The key only enrols machines. Each machine exchanges it for its own token, so revoking the key at the end of the rollout stops new enrolments without touching machines already enrolled. Use a separate key per wave if you want to see who came from where. See Fleet and install keys.
5. Deploy the collector
Section titled “5. Deploy the collector”The collector is the shield360 CLI. Your server serves the install scripts
and the binaries, so machines download nothing from the internet. It installs
per user, without administrator rights. See
Deploy the collector for what
it schedules and collects.
Windows with Intune
Section titled “Windows with Intune”Save as Install-Shield360.ps1:
$env:SHIELD360_URL = "https://shield360.corp.example.com"$env:SHIELD360_INSTALL_KEY = "<pilot install key>"Invoke-WebRequest -UseBasicParsing "$env:SHIELD360_URL/api/cli/install.ps1" | Invoke-ExpressionIn the Intune admin center, open Devices → Scripts and remediations → Platform scripts → Add → Windows 10 and later, upload the script, and set:
| Setting | Value | Why |
|---|---|---|
| Run this script using the logged on credentials | Yes | Installs for the signed-in person, under their profile, with coding-agent hooks |
| Enforce script signature check | No | The script is yours and unsigned |
| Run script in 64 bit PowerShell Host | Yes | Picks the right binary on x64 and ARM64 |
Assign it to the pilot device or user group.
Intune runs a platform script once per user and device. Results appear
under the script’s Device status. On a machine, the Intune Management
Extension log is
C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log.
macOS with Jamf
Section titled “macOS with Jamf”Jamf runs scripts as root. The collector should run as the signed-in person, so the script switches to them.
In Jamf Pro, open Settings → Computer management → Scripts → New. Label parameter 4 Install key, and paste:
#!/bin/bash# Shield360 collector: install and enrol for the person at the console.export SHIELD360_URL="https://shield360.corp.example.com"export SHIELD360_INSTALL_KEY="$4"
user=$(stat -f%Su /dev/console)if [ -z "$user" ] || [ "$user" = "root" ] || [ "$user" = "loginwindow" ]; then echo "Nobody is signed in; try again at the next check-in." exit 1fiuid=$(id -u "$user")launchctl asuser "$uid" sudo -u "$user" --preserve-env=SHIELD360_URL,SHIELD360_INSTALL_KEY \ /bin/sh -c 'curl -fsSL "$SHIELD360_URL/api/cli/install.sh" | sh'Create a policy with the script, the install key in parameter 4, trigger Recurring Check-in, frequency Once per computer, and scope it to the pilot group. Because the script exits with an error when nobody is signed in, Jamf retries it at the next check-in.
curl does not add the quarantine attribute, so Gatekeeper does not prompt for
the downloaded binary. If your server lists a signed shield360-macos.pkg
(check https://<server>/api/cli/targets for "installer": true and
"signed": true), you can deploy that as a Jamf package instead and run only
the enrolment part of the script as the user.
Check: on a pilot machine run shield360 collector status
(%USERPROFILE%\.shield360\bin\shield360.exe collector status on Windows). The
machine appears under Discover → AI usage → Computers after its first heartbeat.
6. Force-install the browser extension
Section titled “6. Force-install the browser extension”The extension sees prompts and AI sites in Chrome and Edge, applies your
data-protection policy, and reports to your server. Your server hosts the
signed extension (.crx) and its update manifest, so browsers install it from
you, not from a store.
Open Settings → Collection & deployment → Browser extension. Build
must say Signed. If the page warns that this server cannot
force-install the extension, follow the fix it shows (usually: pull a
signed Shield360 image) before going further. Device management installs
only a signed .crx; an unsigned one fails silently on every machine.
On the same panel, create or rotate an install key so it fills in, then
choose Show device policy. The panel generates the exact policy for
Chrome and Edge on Windows, macOS profiles, Google Admin and Linux, with
your extension ID, your update URL
(https://<server>/api/extension/updates.xml), and the managed settings
that tell the extension your server and key.
- Intune: add a second platform script that writes the generated
.regfile and runsreg importon it, with Run this script using the logged on credentials: No (it writesHKLM). Or, in a Settings catalog profile, set Google Chrome → Extensions → Configure the list of force-installed apps and extensions and Microsoft Edge → Extensions → Control which extensions are installed silently to<extension ID>;https://<server>/api/extension/updates.xml, and deliver the managed settings with the script. - Group Policy: import the Chrome and Edge ADMX templates, set the same
force-install lists, and deliver the managed settings keys from the
.regfile with Group Policy Preferences → Registry.
Create a Configuration Profile → Application & Custom Settings →
Upload payload for each preference domain the panel lists
(com.google.Chrome, com.microsoft.Edge, and the extension’s managed
settings domains), pasting each generated plist. Scope it to the pilot
group.
Check: open chrome://policy or edge://policy on a pilot machine and
reload policies; the force-install entry shows OK. chrome://extensions
lists Shield360 as installed by your organisation. Under Visibility →
Fleet, the browser appears as browser:<id> within a few minutes.
7. Connect OpenAI and Anthropic billing
Section titled “7. Connect OpenAI and Anthropic billing”Collectors and the extension show what people use. The cost connectors add what the vendors billed, so the pilot report can compare the two. Both need an admin key: an organisation-level key that only an organisation owner or admin can create. It is not an ordinary API key.
- OpenAI: an organisation owner signs in to the OpenAI platform and creates an admin key under the organisation’s settings (admin keys are separate from project keys).
- Anthropic: an organisation admin signs in to the Anthropic Console and
creates an Admin API key under the organisation’s settings. It starts
sk-ant-admin.
Open Connectors (/connectors), choose Add connector → AI spend,
and add OpenAI API costs and Anthropic API costs. Paste each key, or
store it in the Vault
and name the entry. Save, then use the test button: it reports what it
found, for example Synced $1,234.56 over 31 days.
Add any other vendors in the pilot (GitHub Copilot, Cursor, ChatGPT Enterprise, Azure OpenAI) the same way. See Spend connectors.
8. Route alerts to Teams and Slack
Section titled “8. Route alerts to Teams and Slack”Open Alerts (/alerts) → Channels.
- In Teams, open the channel, choose ⋯ → Workflows, and pick the
template Post to a channel when a webhook request is received.
Choose the team and channel and copy the URL it gives
(
…logic.azure.com/…or…api.powerplatform.com/…). - In Shield360, Add channel → Microsoft Teams, and paste the URL.
Do not use the old Incoming Webhook connector
(…webhook.office.com/…): Microsoft is retiring Office 365 connectors in
Teams. Shield360 still accepts those URLs so existing channels keep working
until then, but set new channels up with Workflows.
- In Slack, create an app with Incoming Webhooks, add a webhook to the
channel, and copy its URL (
https://hooks.slack.com/services/…). - In Shield360, Add channel → Slack, choose the webhook option, and paste the URL.
Then, under Rules, send the alerts the pilot cares about (spend, guard
decisions, fleet problems) to those channels. For email alerts, set
ALERTS_EMAIL_FROM and an SMTP relay in .env. See
Alerts.
Check: use the channel’s test button. A message arrives in the channel.
9. Verify data is flowing
Section titled “9. Verify data is flowing”Check these at the end of week 1, then weekly:
| Where | What you should see |
|---|---|
| Discover → AI usage → Computers | Each pilot machine, and each browser as browser:<id>, with a recent check-in. Compare the count with your Intune and Jamf assignment. |
shield360 collector status on a machine | Scheduled yes and a recent Last report. |
| Installed AI software | AI apps, local model runtimes, IDE extensions and MCP servers found on machines. |
| Shadow AI | AI in use that no tracked subscription covers: personal plans, API keys, AI websites. |
| Violations and AI interactions | Extension decisions on prompts (warned, blocked, masked) once people use AI sites. |
| Costs → Actual vs estimate | Vendor-billed spend from the connectors beside the estimate from usage. |
| Alerts → Inbox | Alerts firing and reaching Teams or Slack. |
If a machine is missing: check its Intune or Jamf result, then
shield360 collector status on it, then the server’s log for its enrolment.
10. The end-of-pilot report
Section titled “10. The end-of-pilot report”In week 4, put together what the pilot found. Everything is in the product, so the report is a set of exports, not a project:
| Section | Where it comes from |
|---|---|
| Coverage: machines and browsers enrolled against the pilot group | Discover → AI usage → Computers |
| What AI is in use: apps, sites, models, coding agents, MCP servers | Installed AI software, AI inventory |
| Shadow AI: unsanctioned tools and personal accounts | Shadow AI |
| What it costs and whose it is: by person and department, billed against estimated | Executive view, Costs → Actual vs estimate, CSV export |
| Sensitive data in prompts: what the extension warned on, blocked or masked | Violations |
| Findings and alerts | Findings, Alerts → Inbox |
| Compliance evidence: a signed package with a PDF report | Evidence package. Set SHIELD360_EVIDENCE_SIGNING_KEY first so the package is signed. |
After the pilot
Section titled “After the pilot”- Continue: install the full licence over the trial. Nothing is lost.
- Stop: revoke the install key, remove the Intune scripts and Jamf
policy, push
shield360 collector uninstallandshield360 coding uninstall, remove the extension policies, revoke the OpenAI and Anthropic admin keys, and stop the server. Keep or delete the data volumes according to your retention policy.