# Advanced

Sandbox limits, splitting the manifest across files, the Kubernetes escape hatch and importing from Score.

## `sandbox` [#sandbox]

```yaml
sandbox: { ttl: 2h, max_ttl: 24h, agent_exec: true }
```

All optional; those are the defaults. `ttl` is how long a sandbox lives from creation. `parity sandbox extend` adds time up to `max_ttl`. `agent_exec: false` stops sandbox tokens from using `parity exec`. Parity's own limits cap these: a manifest can make its sandboxes stricter, never looser.


## `include`: splitting the file [#include-splitting-the-file]

```yaml
# parity.yaml
version: 1
project: shop
include:
  - apps/storefront/parity.yaml
  - apps/billing/parity.yaml
managed:
  db: { type: postgres }
```

```yaml
# apps/billing/parity.yaml
services:
  billing:
    build: .            # apps/billing
    depends_on: [db]    # defined in parity.yaml
```

Split the manifest so each team owns a file, as with Compose's `include`.

- `include` lists files relative to the file that lists it. Any file may include others. No globs, absolute paths or paths outside the root's directory.
- Only the root sets `version`, `project`, `sandbox` and `kubernetes`. Other files add `managed`, `services`, `jobs`, `env_groups`, `externals` and `environments`.
- Each name is defined in one file; a second definition is an error naming both. References work across files.
- Paths in a file (`build: .`, `develop.watch` paths) resolve from that file's directory.
- A file's `environments` changes only what it, or a file it includes, defines. The root may change anything.
- `parity check` cites problems as `file:line`, shows each entry's file, and warns about any `parity.yaml` or `*.parity.yaml` that nothing includes. `parity check --merged` prints the merged manifest, which is what `parity up` sends.


## `kubernetes`: the escape hatch [#kubernetes-the-escape-hatch]

When a field doesn't cover what you need, you can patch a service's Kubernetes Deployment or add Kubernetes objects to the sandbox.

```yaml
services:
  api:
    kubernetes:
      patch:   # nginx writes temp files to /var/cache/nginx
        spec:
          template:
            spec:
              volumes: [{ name: cache, emptyDir: {} }]
              containers: [{ name: api, volumeMounts: [{ name: cache, mountPath: /var/cache/nginx }] }]
kubernetes:
  objects:
    - { apiVersion: v1, kind: ConfigMap, metadata: { name: extra }, data: { a: "1" } }
```

- **`patch`** is a strategic merge patch on the service's Deployment. It may set the Deployment's `spec`, labels and annotations.
- **`objects`** may be a ConfigMap, Secret, Service (ClusterIP), Deployment, StatefulSet, Job, CronJob, PodDisruptionBudget, cert-manager `Certificate` (with `issuerRef: { name: parity-ca, kind: Issuer }`), or KEDA `ScaledObject` or `TriggerAuthentication`. Each is named and has no namespace.
- **A `ScaledObject`** scales a service on a queue, for example a worker from 0 when a Redis list fills. `scaleTargetRef` names a service, `maxReplicaCount` is required and at most 10. Triggers are `redis` and `postgresql` on the sandbox's own managed entries (`address: "cache:6379"`, `host: db`), plus `cron`, `cpu` and `memory`. Credentials come from the target's env (`passwordFromEnv: PGPASSWORD`), or from a `TriggerAuthentication` whose `secretTargetRef` reads a Secret of `objects` into `password` or `username`.
- **Security rules still apply.** Containers run non-root without extra privileges. Host access, privileged containers, added capabilities, service account tokens, network policies and cluster-wide objects are refused. So are probes and lifecycle hooks with a `host`, finalizers and owner references, and annotations starting with `external-dns.alpha.kubernetes.io/`, `cloud.google.com/`, `networking.gke.io/` or `cluster-autoscaler.kubernetes.io/`.


## Importing from Score [#importing-from-score]

`parity import score <dir>` writes a `parity.yaml` from [Score](https://score.dev) workload files. Each workload becomes a service, `postgres`, `redis` and `s3` resources become managed entries, `route` becomes `expose`, and `${resources.db.host}` becomes `${db.host}`. Add jobs, builds, auth and email afterwards. What doesn't map is printed.
