> For the complete documentation index, see [llms.txt](https://docs.we360.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.we360.ai/deployment-and-it-ops/security-and-hardening/network-and-security-hardening/pre-provisioned-origin-data.md).

# Pre-Provisioned Origin Data

> **Status.** The file name (`zs-origin.json`), per-OS locations, and the ownership/permission enforcement described below are implemented in the agent. Confirm availability for your specific agent version with We360 before planning a hard offline (origin-blocked) rollout.

## Summary

The desktop agent normally performs **service discovery** at startup by calling the origin server (`origin.in.we360.ai`) to fetch its tenant manifest — the addresses of the tenant API gateway and authentication server, shared headers, and SSO configuration. See *Stealth App — Server Communication* for the full exchange.

Pre-provisioned origin data lets an administrator supply that manifest **as a local, protected file** instead. When the file is present and valid, the agent loads discovery data from it and **never performs tenant/device discovery over the network**. The file is also the **single source of truth for every other origin call** (version checks, update-URL lookups, service telemetry, remote commands, connectivity probes): by default those are **proxied through your tenant API gateway**, so the origin host can be **completely blocked at the firewall** while the agent continues to operate normally.

In effect, the root of trust for discovery moves from a network endpoint (vendor-hosted, reachable over the internet) to a **local artifact the customer controls and protects**.

## The file

| Property                  | Value                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Filename**              | `zs-origin.json`                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Location (per OS)**     | **Windows:** `C:\Windows\System32\zs-origin.json` · **macOS:** `/Library/Preferences/zs-origin.json` · **Linux:** `/etc/zs-origin.json`                                                                                                                                                                                                                                                                                                                           |
| **Format**                | JSON containing the tenant manifest the origin server would otherwise return.                                                                                                                                                                                                                                                                                                                                                                                     |
| **Protection (enforced)** | The agent honours the file **only if it is owned by an administrator and not writable by standard users.** On macOS/Linux it must be **owned by `root` and not group- or world-writable** (deploy with `chown root` — `root:wheel` on macOS — and `chmod 644`); on Windows the `System32` location is admin-only via NTFS ACLs. A file that fails this check is **logged and ignored**, and the agent falls back to online discovery. See *Security model* below. |

### Schema

The file mirrors the tenant manifest contract. All string fields are required unless noted:

```json
{
  "status": "active",
  "tenantId": "<tenant-id>",
  "tenantName": "<display name>",
  "baseDomain": "<acme>",
  "apiGatewayUrl": "https://api.in.we360.ai",
  "apiKeycloakUrl": "https://auth.in.we360.ai",
  "apiKeycloakRealm": "<realm>",
  "headers": { "X-Example-Shared-Header": "value" },
  "ssoConfig": { },
  "meta": { "use_origin": 0 }
}
```

* `headers` may be an empty object `{}` if no shared headers are required.
* `ssoConfig` is optional and may be omitted or empty.
* `meta` is optional. Supported keys are listed under **Supported `meta` keys** below.
* Any missing or non-string required field makes the file **invalid**; the agent treats an invalid file as absent (see fallback below).

### Supported `meta` keys

| Key                       | Type                                            | Effect                                                                                                                                                                                                                                                                                                                      |
| ------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `use_origin`              | `1` / `0` (or `true` / `false`)                 | **Default `0`.** With `1`, the agent still enforces this tenant from the file (no network discovery, sign-in pinned to this tenant) but reaches `origin.in.we360.ai` **directly** for version checks, telemetry and update URLs instead of proxying them. Use this when you want tenant pinning without firewalling origin. |
| `auto_create_users`       | `true` / `false`                                | Standard app: zero-credential auto-onboard of the OS user (also requires the tenant-side flag; see *Standard User Auto-Onboard*).                                                                                                                                                                                           |
| `auto_create_users_email` | string (email **suffix**, e.g. `@corp.example`) | Suffix joined to the OS username to form the auto-onboard e-mail.                                                                                                                                                                                                                                                           |

Any other key in `meta` (for example `banner`, `installer_base_url`, `brand`) is server- or portal-side data and is ignored by the agent; leaving it in is harmless.

### Generating the file (recommended)

The file content is exactly what the origin server returns from its **by-base-domain discovery** endpoint. Rather than hand-authoring it, fetch the live response for the tenant and save it as `zs-origin.json` — this guarantees the values match what the agent would otherwise receive online:

```
https://origin.in.we360.ai/discover/tenant_by_base_domain/?baseDomain=<baseDomain>
```

Open that URL in a browser (or `curl` it), replacing `<baseDomain>` with the tenant's base domain — e.g. `?baseDomain=tech-demo`. The JSON body it returns **is** the `zs-origin.json` contents; save it verbatim to the per-OS location in the table above. No fields need to be edited.

> The response includes a few extra fields (`autoUpdate`, `coreServiceUrl`, and server-side `meta` entries) that the agent ignores; leaving them in is harmless. Only the required fields listed under **Schema** must be present and valid.

## Behavior

The file governs **all** origin traffic, not just discovery. The agent resolves a single "origin base" from it and every component (standard app, stealth app, service monitor, updater, installers) uses that resolution:

| `zs-origin.json` state                                | Discovery (`tenant_by_*`, `device_by_host_name`) | All other origin calls (version checks, telemetry, update URLs, remote commands, connectivity probe)         |
| ----------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| Absent, untrusted, or invalid                         | Online, against `origin.in.we360.ai`             | `origin.in.we360.ai`                                                                                         |
| Present (default, `apiGatewayUrl` set)                | **Answered from the file — no network**          | **Proxied via `<apiGatewayUrl>/origin/...`** — origin host may be blocked                                    |
| Present with `meta.use_origin = 1`                    | **Answered from the file — no network**          | `origin.in.we360.ai` directly                                                                                |
| Present but `apiGatewayUrl` empty and no `use_origin` | **Answered from the file — no network**          | **Blocked** — no request is attempted; telemetry is dropped, connectivity probes use the API gateway instead |

* **File present and valid** → the agent persists the gateway/auth values to its config store exactly as if origin had returned them and skips all `origin.in.we360.ai/discover/tenant_by_*` calls, including the periodic manifest-refresh timer.
* **File absent or invalid** → the agent falls back to normal online discovery against the origin server. (Customers who want a hard offline posture should pair provisioning with the firewall block, and validate the file before deployment.)
* **Data path is unchanged.** Authentication, activity sync, screen-recording upload, and live streaming continue to use the tenant gateway and auth server named in the file — over TLS with certificate validation, exactly as today.
* **No other switch exists.** Earlier agent builds accepted a `"so": 1` flag in `zs.json`; it has been removed and is ignored if present. Origin routing is decided only by `zs-origin.json`.

## Blocking origin

Once devices are provisioned with a valid `zs-origin.json`, the following hosts may be **removed from the egress allow-list / actively blocked** for those devices:

* `https://origin.in.we360.ai`
* `https://origin.global.we360.ai`

The tenant gateway (`api.in.we360.ai`), auth server (`auth.in.we360.ai`), the admin portal, and asset/config hosts must remain reachable. See the allow-list guide for the full set.

> **Updater note:** agent version metadata and per-tenant update URLs are also served by origin. With the default file (gateway set, `use_origin` absent) these requests are proxied through the tenant gateway, so auto-update keeps working with origin blocked. Only the *blocked* row in the table above (no gateway URL) disables automatic update checks; plan updates through MDM in that configuration.

## Security model

This capability is a **security improvement** for hardened environments, but it relocates rather than removes the trust assumption:

* **What it removes:** the need to reach a vendor-hosted discovery endpoint over the internet, and with it the network man-in-the-middle / origin-impersonation vectors against the discovery step. There is no discovery request to intercept or redirect.
* **What it relies on instead:** the **integrity of the local file**. Whoever can write `zs-origin.json` can point the agent at an arbitrary gateway — the same power the origin server has today, but now exercised locally. This is why the file must live in a protected, admin-only location and be deployed through managed tooling. **The agent enforces this**: on macOS/Linux it refuses a `zs-origin.json` that is not root-owned or that is group/world-writable (so a non-admin user cannot plant or tamper with one); on Windows it relies on the `System32` ACL. Treat write access to this file as equivalent to administrative control of the agent's destination.
* **Net effect:** the root of trust changes from "a TLS connection to a vendor endpoint, validated against the OS CA store" to "a local file under the customer's own ACLs and MDM control." For organizations that already firewall outbound traffic and manage their endpoints centrally, this is a stronger and more auditable posture, and it lets them eliminate origin egress entirely.

## Deployment checklist

1. Build the `zs-origin.json` for the tenant (values match what origin returns for that tenant — confirm with We360 or read them from a reference install).
2. Validate the JSON against the schema above.
3. Deploy via MDM/GPO to the per-OS location in the table above, with admin ownership and standard-user-read-only permissions (macOS/Linux: `chown root` + `chmod 644`; Windows: the `System32` ACL already enforces this). A file that isn't admin-owned / is user-writable will be **ignored** by the agent.
4. Confirm the agent onboards and syncs with origin still reachable (validation step). Check the agent log for `origin proxy active — routing origin calls via <gateway>/origin` (or `meta.use_origin=1` if you opted in) and no "ignored — ownership/permission" warning.
5. Block `origin.in.we360.ai` / `origin.global.we360.ai` egress for those devices.
6. Move agent updates to your managed software-distribution channel.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.we360.ai/deployment-and-it-ops/security-and-hardening/network-and-security-hardening/pre-provisioned-origin-data.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
