| 1 | # Customer Provisioning (Tenancy Setup) |
| 2 | |
| 3 | Customer provisioning is the **admin/engineer workflow** for onboarding a new customer/tenant into CoPilot and the surrounding OSS SIEM stack. |
| 4 | |
| 5 | Provisioning is designed to create the *plumbing* that makes customer data land in the right place and makes dashboards usable immediately. |
| 6 | |
| 7 |  |
| 8 | |
| 9 | <video |
| 10 | autoPlay |
| 11 | loop |
| 12 | muted |
| 13 | playsInline |
| 14 | preload="auto" |
| 15 | poster="/assets/hero/customer-provisioning-walkthrough-thumb.jpg" |
| 16 | style={{ |
| 17 | width: '100%', |
| 18 | borderRadius: 16, |
| 19 | margin: '12px 0 18px', |
| 20 | border: '1px solid rgba(255,255,255,0.08)', |
| 21 | background: 'rgba(255,255,255,0.02)', |
| 22 | display: 'block', |
| 23 | }} |
| 24 | > |
| 25 | <source src="/assets/hero/customer-provisioning-walkthrough.webm" type="video/webm" /> |
| 26 | <source src="/assets/hero/customer-provisioning-walkthrough.mp4" type="video/mp4" /> |
| 27 | </video> |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ## What provisioning sets up |
| 32 | |
| 33 | When you provision a customer, CoPilot will typically create: |
| 34 | |
| 35 | ### Also: customer-scoped integrations and network connectors |
| 36 | |
| 37 | This same customer context is also where you configure: |
| 38 | |
| 39 | - **3rd-party integrations** (for example: Office 365, Mimecast, CrowdStrike, etc.) |
| 40 | - **Network connectors** (firewalls and network devices) |
| 41 | |
| 42 | These are set up **per customer** so that ingestion, routing, and alerting stay tenant-aware. |
| 43 | |
| 44 | ### Also: Shuffle (SOAR) for tickets + notifications |
| 45 | |
| 46 | CoPilot can plug into **Shuffle** (SOAR) so SIEM stack alerts can be forwarded to third‑party tools such as: |
| 47 | |
| 48 | - Jira |
| 49 | - email notifications |
| 50 | - ConnectWise |
| 51 | - other ticketing systems / custom webhooks |
| 52 | |
| 53 | This allows you to take an alert created by the stack and automatically: |
| 54 | - create a ticket |
| 55 | - enrich it with alert context |
| 56 | - route it to the right destination per customer |
| 57 | |
| 58 | #### Per-customer workflows (recommended) |
| 59 | |
| 60 | In many environments, different customers want different routing (different Jira projects, different email recipients, different ticketing systems). |
| 61 | |
| 62 | CoPilot + Shuffle supports this pattern by letting you map alerts to **different Shuffle workflow IDs per customer**. |
| 63 | |
| 64 | Practical example: |
| 65 | - Customer A → Jira Project `SOC` |
| 66 | - Customer B → ConnectWise tickets |
| 67 | - Customer C → email-only notifications |
| 68 | |
| 69 | > Tip: The alert context sent to Shuffle is driven by what you map in **Incident Sources** (title/asset/context fields). |
| 70 | |
| 71 | Video context: |
| 72 | - https://www.youtube.com/watch?v=Ko5jLfkSCrk |
| 73 | |
| 74 | ### 1) Dedicated customer index + routing (Graylog → Wazuh Indexer) |
| 75 | |
| 76 | - A **customer-specific index** (for example: `wazuh-<customer_code>`) with your chosen: |
| 77 | - shards |
| 78 | - replicas |
| 79 | - retention (days of hot data) |
| 80 | |
| 81 | - A **Graylog stream** for the customer’s events |
| 82 | |
| 83 | - Stream rules that match on the customer identifier (commonly `agent.labels.customer == <customer_code>`) |
| 84 | |
| 85 | - Stream → pipeline assignment so the customer’s data gets the expected normalization used by dashboards |
| 86 | |
| 87 | > Why this matters: If events don’t route into the correct per-customer index, everything downstream breaks (alerts, dashboards, searching, reporting). |
| 88 | |
| 89 | ### 2) Wazuh agent groups (per OS) |
| 90 | |
| 91 | Provisioning creates Wazuh groups that encode the customer identity, typically one per OS: |
| 92 | |
| 93 | - `Windows-<customer_code>` |
| 94 | - `Linux-<customer_code>` |
| 95 | - `macOS-<customer_code>` |
| 96 | |
| 97 | Agents enrolled into the customer’s group will emit events tagged with the customer label, enabling Graylog/Indexer routing. |
| 98 | |
| 99 | ### 3) Grafana organization + dashboards |
| 100 | |
| 101 | Provisioning creates (or configures) in Grafana: |
| 102 | |
| 103 | - A **Grafana organization** for the customer (recommended: same as the customer name/code) |
| 104 | - An **OpenSearch data source** pointing at the customer’s index pattern (wildcarded for Graylog daily rotation) |
| 105 | - A dashboards folder (for example: **EDR**) with default Wazuh dashboards |
| 106 | |
| 107 | > This is the big win: the customer gets dashboards immediately without hand-building them. |
| 108 | |
| 109 | --- |
| 110 | |
| 111 | ## Prerequisites |
| 112 | |
| 113 | Before provisioning, verify connectivity in **Connectors**: |
| 114 | |
| 115 | - Graylog |
| 116 | - Wazuh Manager |
| 117 | - Grafana |
| 118 | - (Wazuh Indexer / OpenSearch) |
| 119 | |
| 120 | If any connector is not verified, provisioning may partially fail. |
| 121 | |
| 122 | --- |
| 123 | |
| 124 | ## The two key fields: Customer Name vs Customer Code |
| 125 | |
| 126 | ### Customer Code (most important) |
| 127 | |
| 128 | The **customer code** is the value used across the stack to correlate data to the correct tenant. |
| 129 | |
| 130 | Common approach: |
| 131 | - use a short, stable, lowercase code (examples: `acme`, `contoso`, `socfortress-lab`) |
| 132 | - avoid spaces (use `-`) |
| 133 | |
| 134 | > Once you provision with a customer code, treat it as **immutable**. Changing it later usually means re-provisioning or migrating data. |
| 135 | |
| 136 | ### Customer Name |
| 137 | |
| 138 | The customer name is a human-friendly label (UI display, Grafana org naming convention, etc.). |
| 139 | |
| 140 | --- |
| 141 | |
| 142 | ## Step-by-step: Provision a customer |
| 143 | |
| 144 | High-level flow (matches the provisioning wizard shown in the video below): |
| 145 | |
| 146 | 1) Go to **Customers** and create the customer |
| 147 | 2) (If required) set defaults like the **Grafana URL** |
| 148 | 3) Open the customer details and choose **Provision** |
| 149 | 4) Configure Grafana org name |
| 150 | 5) Configure index settings (name, shards, replicas, retention) |
| 151 | 6) Select which dashboards to provision |
| 152 | 7) Submit and wait for provisioning to complete |
| 153 | |
| 154 | After provisioning, validate the results in: |
| 155 | |
| 156 | - **Graylog**: index exists, stream exists, stream rules look correct, stream is assigned to the Wazuh processing pipeline |
| 157 | - **Wazuh Manager**: customer OS groups exist |
| 158 | - **Grafana**: org exists, OpenSearch data source exists, dashboards folder exists |
| 159 | |
| 160 | --- |
| 161 | |
| 162 | ## Validation checklist (quick) |
| 163 | |
| 164 | - [ ] New customer appears in **Customers** |
| 165 | - [ ] Graylog customer index exists and matches naming convention |
| 166 | - [ ] Graylog stream exists for the customer and stream rules match the customer label |
| 167 | - [ ] Customer stream is assigned to the Wazuh pipeline (normalization) |
| 168 | - [ ] Wazuh groups exist (Windows/Linux/macOS) and include the customer label |
| 169 | - [ ] Grafana org exists |
| 170 | - [ ] Grafana OpenSearch data source index pattern uses wildcard (to include daily rotated indices) |
| 171 | - [ ] Default dashboards exist under the customer org |
| 172 | |
| 173 | --- |
| 174 | |
| 175 | ## Video walkthrough (source) |
| 176 | |
| 177 | This guide is based on the customer provisioning walkthrough: |
| 178 | |
| 179 | - **“Wazuh Dashboards in Grafana & Customer Provisioning in CoPilot!”** |
| 180 | - https://www.youtube.com/watch?v=hC0JHY5WF-U |
| 181 | |
| 182 | (We intentionally store **summaries** in docs and do not commit raw transcripts.) |