Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 76 additions & 15 deletions skills/unity-cli/CHANGELOG.md

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion skills/unity-cli/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

This skill documents the official first-party [`unity` CLI](https://public-cdn.cloud.unity3d.com/hub/prod/cli/). A few of its capabilities are powerful by design and are flagged by automated skill scanners. They are intentional, first-party functionality with the safeguards described below.

<!-- skill-security:accept SEC_POWER_CAP, SEC_INSTALL_PIPE -->
## Accepted risks

These capabilities are accepted by design. Each is documented in full in the sections below; this table is the explicit, human-readable acknowledgment.

| Risk | Capability | Why it is accepted |
|---|---|---|
| `SEC_POWER_CAP` | Local Editor control and C# evaluation | Runs entirely on the local machine, as the current user, against the user’s own Editor — no remote access and no privilege the user lacks at their own terminal. |
| `SEC_INSTALL_PIPE` | Install one-liners piped to a shell | HTTPS to Unity’s first-party CDN only; the installer verifies a SHA-256 pin against a same-origin manifest before executing anything. |
| `SEC_AGENT_CONFIG_WRITE` | Writing agent skill files into AI clients’ configuration directories | Runs only on an explicit user command, is the command’s documented purpose, and is fenced by an ownership ledger — a copy this CLI did not write is never overwritten without `--force` — plus symlink refusals and a warning before project-local installs from the home directory. |

## Accepted, by-design capabilities

### Installing skills into AI clients

`unity skill install` and `unity skill refresh` write skill files — this skill, and the `unity-pipeline` skill a project's `com.unity.pipeline` package ships — into AI clients' configuration directories, which automated scanners flag as an agent-persistence pattern. The writes happen only when the user runs the command (nothing installs at load or in the background), the capability is the command's advertised purpose, and it is fenced: an install ledger records every write and a directory this CLI did not write is reported, never overwritten, without explicit `--force` consent; targets that resolve through a symlinked path component are refused; a package-shipped tree is read with file-count, per-file, and aggregate size bounds and never through symbolic links; and `--local` from the home directory warns first.

### Local Editor control and C# evaluation

`unity command`, `unity command eval`, and `unity shell --protocol ndjson` can drive a Unity Editor that is already open on the same machine and run C# through the project's `com.unity.pipeline` package. This executes **entirely on the local machine, in the current user's account, against the user's own Editor** — it is not remote access and grants no privilege the user does not already have at their own terminal. It is the CLI's core value for AI-assisted and automated Editor workflows.
Expand Down
126 changes: 89 additions & 37 deletions skills/unity-cli/SKILL.md

Large diffs are not rendered by default.

57 changes: 56 additions & 1 deletion skills/unity-cli/references/auth-license-cloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,47 @@ unity auth login --client-id <id> --secret-from-stdin --no-store
# Logout (clears both service-account and OAuth credential slots)
unity auth logout

# Log a specific stored account out, rather than the active one
unity auth logout user@example.com

# Skip the confirmation prompt
unity auth logout --yes
```

#### Multiple accounts

The CLI stores more than one signed-in account and keeps one of them *active*. `unity auth login` adds an account; these three manage the set.

```bash
# List stored accounts; "*" marks the active one
unity auth list
unity auth ls # alias
unity auth list --format json

# Make a stored account active (by email or id) — no browser round-trip
unity auth switch user@example.com

# Show the account a project uses for cloud commands
unity auth default

# Pin this project to an account, regardless of which one is active
unity auth default user@example.com

# Target a project other than the current directory
unity auth default user@example.com --project ./MyGame

# Remove the pin; the project follows the active account again
unity auth default --clear
```

Three behaviors worth knowing before scripting these:

- **A project pin beats the active account.** If a project has a default set, commands run inside it keep using that account even after `unity auth switch` — the switch reports this rather than failing silently. Use `auth default --clear` to hand the project back to the active account.
- **Service-account credentials outrank both.** When `UNITY_SERVICE_ACCOUNT_ID` / `UNITY_SERVICE_ACCOUNT_SECRET` are set (or a service account is signed in), they take precedence over every stored account and `auth switch` says so instead of appearing to work. Unset them, or `unity auth logout`, before switching.
- **`auth switch` is ambiguity-aware.** Given a string matching several stored accounts it fails rather than guessing, and under `--format json` carries the candidates in `data.candidates` so a script can disambiguate. Pass the full email or the account id.

`unity auth default` resolves the project from the current directory unless `--project` is given, and errors if that path isn't a Unity project. Passing both an account and `--clear` is rejected.

**Separate sign-in from Hub.** As of `0.1.0-beta.8`, the CLI and the GUI Hub store their sign-in credentials **separately** — signing in to one no longer signs you out of (or overwrites the account of) the other, so each can stay signed in as a different account. (In earlier betas they shared a single keyring session.)

**Service-account credentials via env vars** (`UNITY_SERVICE_ACCOUNT_ID` + `UNITY_SERVICE_ACCOUNT_SECRET`) mint bearer tokens automatically for the duration of the process — no browser round-trip, no keyring write. If only one of the two is set, the CLI prints a warning on stderr instead of silently falling back to the keyring/OAuth identity.
Expand Down Expand Up @@ -97,12 +134,30 @@ unity cloud org set-default <id-or-name> # set active default org
unity cloud org clear-default # revert to "All Organizations"

# Projects in the active organization
unity cloud project list --format json
unity cloud project list --format json # * marks the active default project

# Default project, stored per organization
unity cloud project current # print the active default project id
unity cloud project set-default <id-or-name> # project UUID, Genesis id, or exact name
unity cloud project clear-default # drop this organization's default

# Override the active organization for a single call
unity cloud project list --cloud-org <id-or-name> # also via UNITY_CLOUD_ORG env var
```

**The default project is per organization.** `set-default` stores the project's UUID against the
active organization's Genesis id, so switching your active organization switches which default
applies, and `clear-default` only drops the active organization's. `cloud project current` and
`clear-default` read and write the settings file directly, so they need no network and no session
when the organization comes from your stored default; passing `--cloud-org <name>` needs a lookup,
so that path requires a session like the rest.

**What consumes it.** Commands that need a Unity Cloud project but were not given one fall back to
the stored default. The order is the explicit flag (`--project-id`), then `UNITY_CLOUD_PROJECT`,
then the cloud link in the project directory's `ProjectSettings/PlayerSettings.asset`, then the
stored default, so inside a cloud-linked project the link still wins. `unity collaboration` and
the `cloud-pipeline` preview family both use this chain.

**Exit codes.** The `cloud` and `auth` commands map an authentication failure (expired or missing session, rejected sign-in) to `3`, and any other operational failure (network, server error) to `6` — so scripts can distinguish "sign in again" from a genuine command failure. `unity auth status` / `logout` follow the same convention.

---
Expand Down
Loading