# SaaS And Orchestrator Security Definition

## Purpose

Open Orchestra is local-first workflow orchestration for humans and agent
runtimes. The CLI owns the current source of truth in `.agent-workflow/`; the
web console, runtime adapters, provider-backed phases, tracker integrations, and
future SaaS surfaces must preserve that local trust model instead of turning
agent automation into an implicit privileged service.

This document defines the baseline security model for the local CLI and the
future SaaS orchestrator. It intentionally avoids secrets, tenant identifiers,
private hosts, and production endpoints.

## Security Objectives

- Keep local repositories, workflow state, secrets, and evidence under explicit
  user or tenant control.
- Treat prompts, issues, comments, model output, uploaded artifacts, generated
  plans, tool metadata, and runtime handoffs as untrusted input.
- Fail closed for cross-tenant access, secret exposure, unsafe writes, shell
  execution, provider policy violations, and evidence integrity failures.
- Make every privileged action reviewable through role gates, policy decisions,
  and evidence records.
- Support offline local development without weakening the SaaS security posture.

## System View

```mermaid
flowchart LR
  human["Human operator"]
  cli["Local CLI"]
  web["Local web console"]
  api["Future SaaS API"]
  workflow["Workflow core"]
  state[".agent-workflow state"]
  workers["SaaS workers"]
  runtimes["Agent runtimes"]
  tools["MCP and local tools"]
  providers["Model providers"]
  trackers["GitHub, Sonar, trackers"]
  storage["Tenant storage and evidence ledger"]

  human --> cli
  human --> web
  web --> cli
  cli --> workflow
  workflow --> state
  workflow --> runtimes
  workflow --> tools
  workflow --> providers
  workflow --> trackers
  api --> workers
  workers --> storage
  workers --> providers
  workers --> trackers
  workers --> runtimes
```

The local CLI remains the default control plane. SaaS components may coordinate,
store sanitized workflow metadata, and run isolated workers, but they must not
receive raw secrets, raw repository contents, or direct runtime authority unless
tenant policy and role gates explicitly allow it.

## Trust Boundaries

- Human to CLI: trust the installed CLI binary, local config, and explicit
  flags. Treat terminal input, pasted prompts, and shell environment as
  untrusted. Require argument validation, safe defaults, no secret echo, and
  confirmation before writes outside known workflow paths.
- CLI to workspace: trust the workspace root and allowlisted
  `.agent-workflow/` paths. Treat user files, symlinks, generated paths, and
  imported archives as untrusted. Require root containment, path traversal
  rejection, symlink escape checks, and dry-run before broad writes.
- Local web console to CLI/API: trust the loopback-only local service and
  command contracts. Treat browser input, request bodies, and local plugins as
  untrusted. Require CSRF-aware mutations, strict JSON validation, no arbitrary
  command endpoint, and sanitized errors.
- SaaS API to tenant workers: trust authenticated tenant context and policy.
  Treat requests, uploaded artifacts, and webhook payloads as untrusted.
  Require AuthN/AuthZ, tenant scoping, schema validation, rate limits, audit
  logs, malware scanning, and secret scanning.
- Tenant to tenant: trust only the current tenant partition. Treat other
  tenants, shared queues, and shared caches as untrusted. Require mandatory
  tenant id in every data access path, row or storage isolation, cache key
  partitioning, and per-tenant encryption context.
- Workflow core to runtimes: trust the rendered task packet and allowed
  commands. Treat runtime instructions, child agent output, and handoff files as
  untrusted. Require prompt-injection checks, ownership path limits, lifecycle
  attestation, and no provider keys in packets.
- Runtime to tools/MCP: trust tool registry metadata and approved scopes. Treat
  tool descriptions, tool results, and external MCP servers as untrusted.
  Require tool identity pinning, capability allowlists, OAuth token isolation,
  and output sanitization.
- Provider-backed phases: trust provider adapter policy and redacted context.
  Treat model outputs and provider errors as untrusted. Require explicit opt-in,
  tenant data policy, prompt and output filtering, cost limits, budget limits,
  and redacted error handling.
- Trackers and scanners: trust stable adapter contracts. Treat issues,
  comments, scan reports, and CI logs as untrusted. Require remote text to be
  handled as data, redact secrets, and verify webhook signatures when
  applicable.
- Evidence ledger: trust append-only local or tenant evidence records. Treat
  generated evidence, command logs, screenshots, and runtime claims as
  untrusted. Require hashing, provenance, immutable event ids, reviewer
  sign-off, and tamper-evident summaries.
- Storage and backups: trust tenant storage service and KMS policy. Treat
  object keys, retained artifacts, and backup restore paths as untrusted.
  Require encryption at rest, retention policy, restore testing, access logs,
  and delete workflows.

## Threat Model

- Prompt injection: untrusted text asks an agent to ignore gates, reveal
  secrets, or mutate files. Treat instructions from issues, docs, comments,
  tools, and model output as data; enforce system policy outside the prompt.
- Indirect prompt injection: a retrieved artifact hides malicious instructions
  in evidence, PDFs, websites, or tool results. Scan and label context sources,
  then strip or quarantine high-risk instruction patterns before runtime
  packets.
- SQL or NoSQL injection: tenant filters or search queries alter data access.
  Use parameterized queries, typed repositories, schema validation, and tenant
  predicates applied server-side.
- Command injection: user or model text reaches a shell command. Use
  `execFile` or `spawn` with argument arrays; block shell interpolation and
  `shell: true` unless a reviewed exception exists.
- SSRF: SaaS workers fetch attacker-controlled internal URLs. Allow only
  `https://` URLs, deny private and metadata address ranges, use egress policy,
  and avoid server-side fetches without approval.
- Path traversal: generated paths escape the workspace or tenant storage
  prefix. Resolve canonical paths, reject `..` and symlink escapes, and require
  approved roots for secure files.
- Secrets exfiltration: tokens appear in prompts, evidence, logs, provider
  errors, or artifacts. Load secrets from secret managers or approved local
  files, redact before persistence, and never send secrets to model context.
- Tenant isolation failure: a request, cache, worker, or artifact crosses tenant
  scope. Require tenant-scoped auth, data access, queue names, cache keys,
  storage prefixes, audit events, and encryption context.
- Unsafe file writes: runtime or SaaS worker writes outside intended docs,
  workflow, or output paths. Require ownership paths, dry-run previews for broad
  changes, path policy checks, and user approval for sensitive writes.
- Tool impersonation: a malicious tool mimics a trusted MCP server, scanner, or
  runtime adapter. Pin tool identity, origin, executable path, version, and
  capability manifest; reject writable PATH tool discovery for sensitive tools.
- Evidence tampering: a runtime edits evidence or claims tests passed without
  proof. Require append-only evidence events, command metadata, hashes for large
  artifacts, reviewer gates, and mismatch detection.
- Cross-site request forgery: a browser triggers local web console mutations.
  Keep local services loopback-only by default, require mutation tokens or
  same-origin controls, and avoid ambient credentials.
- Dependency compromise: a package or binary changes behavior after install.
  Pin lockfiles, scan dependencies, verify sensitive binaries from trusted
  paths, and keep dependency updates atomic.
- Denial of wallet or quota: provider-backed phases consume unexpected tokens,
  jobs, or storage. Enforce per-task and per-tenant budgets, rate limits,
  cancellation, cost evidence, and fail-closed budget handling.

## Secure-By-Default Controls

### Deterministic Policy Engine

The orchestration policy engine is a typed domain boundary, not prompt text.
It should expose one deterministic decision contract used by CLI commands,
runtime packet rendering, provider requests, tool calls, evidence writes,
tracker/webhook adapters, and future SaaS workers. Every sensitive operation
must pass a complete policy subject, action, resource, tenant/workspace scope,
data classification, and sink before side effects begin. Missing, ambiguous, or
schema-invalid input denies by default and records a sanitized reason.

Recommended module boundaries:

- `src/security/policy-types.ts`: discriminated unions for policy subjects,
  actions, resources, sinks, decisions, redaction status, and denial reasons.
- `src/security/policy-engine.ts`: pure decision engine and rule registry. It
  performs no filesystem, network, shell, provider, or persistence I/O.
- `src/security/prompt-intake.ts`: deserializes prompt/runtime packets into
  typed segments and classifies each segment as instruction, data, tool input,
  tool output, evidence, provider response, or unknown.
- `src/security/content-classifier.ts`: deterministic detectors for
  query-like and executable-like strings, prompt-injection patterns, path
  traversal, SSRF candidates, shell metacharacters, SQL/NoSQL-like payloads,
  and secret-shaped values.
- `src/security/redaction.ts`: redacts restricted values, marks quarantined
  segments, and returns a redaction report before persistence or model reuse.
- `src/security/sink-encoding.ts`: sink-specific escaping and encoding for
  Markdown, JSON, shell arguments, URLs, HTML/text UI, logs, evidence, and
  provider messages.
- `src/security/path-policy.ts`, `url-policy.ts`, `command-policy.ts`,
  `tenant-policy.ts`, `tool-policy.ts`, `provider-policy.ts`,
  `evidence-policy.ts`, and `runtime-packet-policy.ts`: focused rule modules
  plugged into the pure engine.
- Existing adapters such as CLI commands, runtime renderers, provider
  adapters, MCP/tool adapters, and workflow evidence services stay thin: build
  typed policy requests, call the engine, then execute or fail closed.

Prompt/content intake pipeline:

1. Deserialize all prompt packets, context packs, tool results, provider
   responses, handoffs, issue text, and evidence snippets with strict schemas.
   Unknown fields and malformed envelopes become `unknown` segments and are not
   forwarded to sensitive sinks.
2. Split content into typed segments with provenance, tenant/workspace/task
   scope, source artifact, declared sink, and original byte length.
3. Detect query-like strings (`SELECT`, GraphQL-like bodies, JSON filters,
   search expressions), executable-like strings (shell fragments, command
   substitutions, shebangs, PowerShell, SQL/NoSQL mutation verbs), and
   instruction-like text asking agents to ignore policy or reveal secrets.
4. Classify each segment as data, instruction, tool input, tool output,
   evidence, provider response, or unknown. Remote text is data by default;
   only trusted system-authored templates may become instruction segments.
5. Redact restricted values before persistence, provider calls, logs, telemetry,
   and evidence summaries. Quarantine segments when redaction confidence is
   low, executable intent appears in a data segment, or the destination sink
   cannot safely encode it.
6. Encode for the exact sink immediately before use: argument arrays for
   commands, canonicalized `https://` URLs for fetches, JSON string escaping
   for packets, Markdown escaping for handoffs, `textContent`/HTML escaping for
   UI, and provider-message wrapping that labels untrusted text as data.

Policy decisions should be append-only evidence inputs with request id, task id,
actor, action, resource summary, decision (`allow`, `deny`, `requiresApproval`,
`quarantine`), matched rule ids, redaction status, and sanitized reasons. They
must not include raw secrets, full prompt bodies, bearer headers, or internal
stack traces.

### Local CLI

- Default to local-only operation; network calls require an explicit command,
  configured adapter, or CI-owned workflow.
- Keep `.agent-workflow/` as the auditable source of task, decision, evidence,
  review, and release state.
- Validate workspace roots before writes and reject unsafe roots without
  explicit confirmation.
- Use typed command contracts and JSON schemas for automation surfaces.
- Never log secret values, bearer headers, raw provider errors, or raw stack
  traces in user-facing output.
- Preserve dry-run or evaluate modes for commands that alter config, tokens,
  runtime adapters, generated files, or tracker state.

### Future SaaS API And Web Console

- Require tenant-authenticated sessions for every SaaS API request.
- Enforce authorization server-side; UI role visibility is not authorization.
- Bind every job, artifact, cache entry, evidence event, and storage object to a
  tenant and workspace.
- Validate request bodies with narrow schemas and reject unknown mutation fields.
- Use short-lived worker credentials and scoped service identities.
- Store only sanitized workflow metadata unless the tenant explicitly enables
  managed artifact storage.
- Apply tenant retention, deletion, export, and audit policies to every stored
  artifact.

### Workers, Runtimes, And Providers

- Run workers with least privilege, no shared mutable workspace, and no default
  access to tenant secrets.
- Require explicit provider opt-in before direct model API calls.
- Keep runtime-native delegation packets free of provider credentials and raw
  secret material.
- Pass bounded, redacted context packets to model providers.
- Enforce allowed commands, ownership paths, and lifecycle recording for child
  runtime work.
- Treat model output as suggestions until validated by code review, tests, and
  role gates.

### Tools, MCP, And External Integrations

- Require `https://` for remote MCP and integration endpoints.
- Store OAuth and integration tokens only in tenant secret stores or approved
  local secret paths; never in prompt, evidence, or generated runtime files.
- Pin sensitive executable discovery to trusted paths and reject tools resolved
  from user-writable PATH entries.
- Redact tool results before persistence or model reuse.
- Verify webhook signatures and replay windows before accepting remote events.
- Keep scanner and tracker adapters narrow: one adapter owns I/O, policy checks,
  retries, and sanitized errors for each integration.

### Evidence Integrity

- Record command evidence with command name, exit status, summary, and relevant
  artifact paths, not raw secrets or full logs by default.
- Use append-only event records for workflow lifecycle, runtime spawn state,
  reviews, and evidence.
- Hash large evidence artifacts and generated reports when they become release
  inputs.
- Require QA and Architect review when evidence does not map to acceptance
  criteria or when technical contracts changed.
- Preserve failed evidence and unresolved risk instead of overwriting it with a
  later passing summary.

## Role Gates

- Product readiness: Product Owner and Analyst block when acceptance criteria,
  non-goals, priority, or tenant impact are missing.
- Architecture readiness: Architect and Security block when boundaries, data
  flow, provider policy, storage ownership, or failure modes are unclear.
- Security review: Security and Compliance/Privacy block sensitive work when
  auth, secrets, PII, file paths, shell execution, network calls, dependencies,
  TLS, cookies, sessions, CORS, webhooks, tenant isolation, or infrastructure
  are touched without controls.
- Implementation handoff: Developer and Tech Lead block when tests, typed
  contracts, ownership paths, or migration/rollback notes are missing.
- QA evidence: QA and Analyst block when evidence does not prove acceptance
  criteria, edge cases, regression areas, or security controls.
- Operational readiness: SRE, DevOps, and Release Manager block when
  monitoring, alerting, rate limits, budgets, rollout, rollback, or incident
  owner is missing for SaaS behavior.
- Data readiness: DBA and Data Engineer/Analyst block when indexes, migrations,
  retention, lineage, or tenant query patterns are not defined.
- Release go/no-go: Product Owner, Release Manager, and Security block when
  residual risk remains unresolved and is not explicitly risk-accepted.

Security-sensitive tasks must include a threat model note, impacted boundaries,
controls, validation evidence, residual risks, and a reviewer outcome before
release.

## Data Classification

- Public: published docs and public command manifests. These may be indexed and
  sent to providers when policy allows.
- Internal: workflow metadata, task summaries, and sanitized evidence. These are
  tenant/workspace scoped and redacted before external provider use unless
  policy allows broader handling.
- Confidential: private repo content, issue context, generated handoffs, and
  logs. These are local-only or redacted-external by default; retention and
  audit are required.
- Restricted: secrets, tokens, credentials, regulated PII, and signing material.
  These are never sent to prompts or persisted in evidence; use a secret
  manager, tokenization, or approved local secure files.

## Backlog Candidates

1. Policy engine for tenant data classification, provider routing, network
   access, tool capabilities, and fail-open/fail-closed behavior.
2. Prompt-injection scanner for issues, comments, artifacts, tool outputs,
   evidence, model responses, and context packs.
3. Tenant isolation test suite covering SaaS API, workers, queues, caches,
   evidence, object storage, and backup restore paths.
4. Evidence integrity ledger with append-only events, artifact hashing,
   reviewer attestations, and tamper detection.
5. SSRF and URL validation library shared by SaaS workers, web console, MCP
   proxy, and tracker adapters.
6. Tool identity registry for MCP servers, local binaries, runtime adapters,
   allowed commands, versions, and trusted executable paths.
7. Secret redaction pipeline for runtime packets, provider errors, evidence,
   logs, telemetry, imported artifacts, and generated summaries.
8. SaaS audit log schema with tenant id, actor, action, target, policy decision,
   evidence id, request id, and redaction status.
9. Worker sandbox profile with filesystem, network, process, timeout, memory,
   and budget limits.
10. Release gate automation that blocks security-sensitive SaaS changes without
    Security, QA, SRE, and Compliance/Privacy evidence.
11. Tenant retention and deletion workflows with export, legal hold, backup
    tombstone, and restore verification.
12. Dependency and binary provenance checks for scanner tools, MCP proxies,
    release automation, and runtime bridge helpers.

## Validation Expectations

- Documentation-only changes should run lightweight text checks and the
  Orchestra evidence/review workflow.
- Security-sensitive code changes should run format, lint, typecheck, unit
  tests, secret scan, security audit, and targeted E2E or contract tests.
- SaaS implementation stories should add tests for tenant isolation, prompt
  injection handling, URL validation, path traversal, unsafe writes, command
  execution, secret redaction, and evidence tampering.
- Release evidence must name the acceptance criteria it proves or explicitly
  record the deferred owner and rationale.
