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

# Security and access

> How Patch handles authentication, team access, API tokens, and optional code signing.

Patch separates who can publish updates (CLI and dashboard auth) from whether clients trust updates (optional code signing).

## Authentication

### Dashboard sign-in

Sign-in uses GitHub, Bitbucket Cloud, or GitLab OAuth. Installs with domains require at least one configured provider; the first admin email must match the verified primary address on that account when `REGISTRATION_MODE=invite_only`.

See [Install](/docs/install#github-oauth-app) for OAuth app setup.

### CLI sign-in

  <TabItem value="react-native" label="React Native">

Developers sign in through the browser — `cmpatch login` opens the dashboard and completes over a localhost redirect (pass `--token` to sign in with a personal access token instead):

```bash
cmpatch login --server-url https://updates.example.com
```

In a project set up with `cmpatch init`, the server URL is already known and
`cmpatch login` needs no flag. Credentials are stored locally in `~/.codemagic-patch/`.

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

`cmpatch-capacitor login` opens the dashboard in a browser and completes sign-in through a localhost redirect. To sign in with a personal access token, pass `--token`:

```bash
cmpatch-capacitor login --server-url https://updates.example.com
```

If `CODEMAGIC_PATCH_SERVER_URL` or a default server (`cmpatch-capacitor config set --server-url`) is set, `--server-url` is not needed. Credentials are stored in `~/.codemagic-patch/credentials-capacitor.json`, readable only by your user and separate from `cmpatch` credentials. `--no-browser` prints the sign-in URL instead of opening it. The URL must be opened on the same machine, so use `--token` over SSH.

  </TabItem>
</SdkTabs>

### API tokens (CI and automation)

For CI and scripting, create personal access tokens:

  <TabItem value="react-native" label="React Native">

```bash
cmpatch token create --name ci
```

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

```bash
cmpatch-capacitor token create --name ci --expires-in-days 365
```

  </TabItem>
</SdkTabs>

- Prefix: `cm_pat_…`
- Shown once at creation: store in your secret manager
- Supply via `CODEMAGIC_PATCH_TOKEN` or `--token`
- Revoke with `token revoke` (or from the dashboard) when compromised

:::warning
Treat `cm_pat_…` tokens like production credentials. Scope pipeline access and rotate on schedule.
:::

### Auth precedence

`--token` → `CODEMAGIC_PATCH_TOKEN` → the credential stored by `login`

## Code signing (update integrity)

Beyond server authentication, Patch supports cryptographic signing of release manifests so clients only install packages signed with your private key.

Enable at app creation or later:

  <TabItem value="react-native" label="React Native">

```bash
cmpatch app create --name MySignedApp-iOS --require-code-signing
cmpatch app setting --app MyApp-iOS --require-code-signing=true
```

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

```bash
cmpatch-capacitor app create --name MySignedApp-iOS --require-code-signing
cmpatch-capacitor app setting --app MyApp-iOS --require-code-signing=true
```

  </TabItem>
</SdkTabs>

Create a private and public key pair with OpenSSL:

```bash
# generate private RSA key
openssl genrsa -out patch-private-key.pem 2048

# export public key
openssl rsa -in patch-private-key.pem -pubout -out patch-public-key.pem
```

  <TabItem value="react-native" label="React Native">

Copy the public key (`cat patch-public-key.pem`, including the `BEGIN` / `END` lines) into native config as `CodemagicPatchPublicKey`. See [Native setup](/docs/setup/native-setup) for `Info.plist`, `strings.xml`, or Expo plugin wiring.

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

Copy the public key (`cat patch-public-key.pem`, including the `BEGIN` / `END` lines) into `capacitor.config.ts` as `publicKey` in each platform block. A `CodemagicPatchPublicKey` native resource overrides this value. See [Native setup](/docs/setup/native-setup-capacitor).

  </TabItem>
</SdkTabs>

Publish signed releases with the private key:

  <TabItem value="react-native" label="React Native">

```bash
cmpatch release-react --platform ios --deployment Staging \
  --private-key-path ./patch-private-key.pem --yes
```

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

```bash
cmpatch-capacitor release create --bundle-path www \
  --app MyApp-iOS --deployment Staging --target-binary-version "1.2.0" \
  --private-key-path ./patch-private-key.pem
```

The signature is an RS256 JWT of the bundle's package hash. The SDK verifies it on the device.

  </TabItem>
</SdkTabs>

  <TabItem value="react-native" label="React Native">

When building a `.cmpatch` artifact with code signing enabled, pass `--private-key-path` to `cmpatch bundle` as well.

  </TabItem>
  <TabItem value="capacitor" label="Capacitor">

`cmpatch-capacitor release create` signs the bundle during upload; there is no separate bundle step.

  </TabItem>
</SdkTabs>

The SDK reads the public key from the binary at launch, so ship a new native build (and reinstall on devices) before clients can verify signed OTAs. OTA updates cannot add or change the public key.

With the key in the binary, the client rejects releases with missing or invalid signatures.

If no public key is configured, the client does not verify signatures and installs both signed and unsigned releases.

## Server secrets

`.env.selfhost` contains production secrets (Postgres, MinIO, OAuth, worker keys). Back it up and never commit it. See [Configuration reference](/docs/reference/configuration).

## CI hygiene

- Store `CODEMAGIC_PATCH_TOKEN` in CI secret stores only
- Use separate tokens per pipeline or environment where possible
- Release to Staging before Production ([CI integration](/docs/using-patch/ci-integration))
