# Operator quickstart

After [installing Catalyst](https://docs.diagrid.io/operate/hosting), create a governed project that a team can safely build in. This guide covers the common operations you perform as a platform operator, walking that journey end to end with the [`diagrid` CLI](https://docs.diagrid.io/references/catalyst/catalyst-cli-intro): create a project, create the team's workload identities, wire up infrastructure, make it resilient, lock it down with zero-trust controls, and hand it over.

Each step is a command you can run. Every step also has an equivalent in the Catalyst console and a [declarative form](https://docs.diagrid.io/operate/project-operations/declarative-management) you can keep in Git.

## What you'll build

By the end of this guide you'll have a project with apps, scoped infrastructure, resiliency policies, access controls, trace export, and project-scoped team access.

```mermaid
flowchart TB
  WL(Your workloads)
  subgraph PROJECT["Project"]
    APPID(App)
    COMP(Component)
    POL(Policies)
    APPID --> COMP
  end
  INFRA[(Your infrastructure)]
  WL --> APPID
  COMP --> INFRA
```

## Before you begin

- Catalyst is installed (see [Hosting](https://docs.diagrid.io/operate/hosting)), or you have a [Catalyst Cloud](https://docs.diagrid.io/operate/hosting/catalyst-cloud) account.
- The [`diagrid` CLI is installed](https://docs.diagrid.io/getting-started/install-cli) and you are logged in:

```bash
# Authenticate the CLI to your Catalyst organization
diagrid login
```

## 1. Create a project for a team

A [project](https://docs.diagrid.io/concepts/organisations-and-projects) is the isolation boundary you hand to a team or environment. Create a project, then enable only the managed infrastructure required by the workloads that will run in it, and set it as your default so every project-scoped command that follows runs within it:

```bash
# Create a project and set it as the default for later commands
diagrid project create payments --use
```

Provision the managed infrastructure that matches what the team runs:

- **Applications** — add `--deploy-managed-pubsub` and `--deploy-managed-kv` for Catalyst-hosted Pub/Sub and key-value stores.
- **Workflow applications** — add `--enable-managed-workflow` for the managed workflow store.
- **Agents** — add `--deploy-managed-kv`. Agent infrastructure comes with the managed key-value store on cloud projects, so there is no separate flag. (`--enable-agent-infrastructure` still exists on `diagrid project update`, for BYOC and private-region projects, or cloud projects without the managed key-value store.)
- **MCP servers** — no managed infrastructure needed. The project simply routes MCP and service-invocation calls between workloads, acting as a secure gateway.

See [Projects](https://docs.diagrid.io/operate/platform-operations/projects) for the full set of project options.

## 2. Create workload identities

Every workload — an application, an agent, or an MCP server — needs an [ID](https://docs.diagrid.io/concepts/identities), its identity inside the project. The ID does two jobs: it lets the workload **connect to Catalyst**, authenticating every API call it makes, and it is the handle you **scope security to** — components, access policies, and resiliency all bind to it. Create workloads first, so you can scope infrastructure and policies to them in the next steps:

```bash
# An application
diagrid app create orders-api

# An agent
diagrid app create billing-agent

# An MCP server
diagrid app create github-mcp
```

To connect code to the project, the team needs two things: the project's endpoints (shared by every workload) and each workload's API token. Retrieve them and share them securely:

```bash
# Project HTTP and gRPC endpoints
diagrid project get payments

# An App ID's API token
diagrid app get orders-api
```

The team sets these as the `DAPR_HTTP_ENDPOINT`, `DAPR_GRPC_ENDPOINT`, and `DAPR_API_TOKEN` environment variables. — see [Connect to Catalyst](https://docs.diagrid.io/develop/connect). For dev/test, [`diagrid dev run`](https://docs.diagrid.io/develop/local-development/catalyst-cli) injects them automatically. For day-2 operations on apps, see [IDs](https://docs.diagrid.io/operate/project-operations/ids).

## 3. Connect backing infrastructure

Managed services cover Pub/Sub, key-value, and workflow. To wire in infrastructure you operate — your Redis, Postgres, or Kafka, whether it runs on-premises or in a cloud — create a [component](https://docs.diagrid.io/concepts/components). The component abstracts that infrastructure and decouples it from your application: the workload calls a standard Dapr API while Catalyst routes the call to whatever the component points at, so you can swap the backing store without changing application code. Scope it to the workloads that may use it:

```bash
# Register your Redis as a state store, usable only by the orders-api workload
diagrid component create orders-state \
  --type state.redis \
  --metadata redisHost=my-redis.internal:6379 \
  --metadata redisPassword=<password> \
  --scopes orders-api
```

See [Components](https://docs.diagrid.io/operate/project-operations/components) for the full catalog of supported component types.

## 4. Make application and infrastructure interactions resilient

A [resiliency policy](https://docs.diagrid.io/concepts/policies/resiliency) tells Catalyst how to recover from transient failures — timeouts, retries, and circuit breakers — on calls to other workloads and to components, with no application code changes. Define it in a YAML manifest and list the targets it applies to. For example, retry calls to `orders-api` up to three times, five seconds apart:

```yaml
# orders-resiliency.yaml
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
  name: orders-resiliency
spec:
  policies:
    retries:
      defaultRetry:
        policy: constant
        duration: 5s
        maxRetries: 3
  targets:
    apps:
      orders-api:
        retry: defaultRetry
```

Apply it with the CLI:

```bash
# Create the resiliency policy from the manifest
diagrid resiliency create -f orders-resiliency.yaml
```

See [Apply resiliency policies](https://docs.diagrid.io/operate/project-operations/policies/resiliency) for timeouts, circuit breakers, and component targets.

## 5. Bring your own secret store

By default, Catalyst manages secrets for you: when you create a component, endpoint, or configuration, it extracts the sensitive fields — passwords, tokens, keys — into a built-in managed secret store and replaces them with references, so plaintext is never stored in the control plane. No setup required.

If your organization already keeps credentials in **AWS Secrets Manager**, **Azure Key Vault**, or **HashiCorp Vault**, bring it instead. Register it as a `secretstores` component, and Catalyst resolves secret references through it at runtime:

```bash
# Register your own HashiCorp Vault as a secret store
diagrid component create team-vault \
  --type secretstores.hashicorp.vault \
  --metadata vaultAddr=https://vault.internal:8200 \
  --metadata vaultToken=<token> \
  --scopes orders-api
```

The managed store and your own can coexist. See [Manage secrets](https://docs.diagrid.io/operate/project-operations/secrets).

## 6. Lock it down with zero trust

Catalyst gives you project-level isolation by default — the workloads and resources inside a project can reach one another, while everything outside it is denied. From there you tighten access at the workload, component, topic, and workflow levels with these controls:

- **Scope every component to a single workload.** List one workload in the component's `scopes` and only that workload can use it — every other workload in the project is denied the infrastructure behind it:

  ```bash
  diagrid component create orders-state --type state.redis --scopes orders-api
  ```

- **Lock down access between workloads.** Attach a deny-by-default access policy to a target workload and allow-list only its expected callers; any other workload that tries to invoke it is rejected before the call reaches it (see [service invocation](https://docs.diagrid.io/operate/project-operations/policies/service-invocation)). MCP servers are deny-by-default too — [grant a caller access to specific tools](https://docs.diagrid.io/develop/mcp/mcp-access-policies):

  ```bash
  diagrid mcpserver access grant github-mcp --caller billing-agent --allow-tools create_issue,list_issues --wait
  ```

- **Scope pub/sub topics.** On the pub/sub component, `publishingScopes` limits which topics each workload may publish to and `subscriptionScopes` limits which it may subscribe from; anything outside those lists is blocked. Here `orders-api` may only publish to `orders`, and `billing-agent` may only subscribe to it:

  ```yaml
  # orders-pubsub.yaml
  apiVersion: cra.diagrid.io/v1beta1
  kind: Component
  metadata:
    name: orders-pubsub
  spec:
    type: pubsub.redis
    version: v1
    metadata:
      - name: redisHost
        value: "my-redis.internal:6379"
      - name: publishingScopes
        value: "orders-api=orders"
      - name: subscriptionScopes
        value: "billing-agent=orders"
  scopes:
    - orders-api
    - billing-agent
  ```

- **Lock down cross-application workflows.** Allow-list which apps may schedule workflows and activities on a [workflow application](https://docs.diagrid.io/concepts/workflows); a caller that isn't listed is rejected with a `PermissionDenied` error (see [workflow access policies](https://docs.diagrid.io/operate/project-operations/policies/workflows)):

  ```bash
  diagrid workflow access-policy create orders-workflow-policy --scopes orders-api --callers billing-agent
  ```

- **Verify workflow history.** Catalyst cryptographically signs each step it records, so a workflow's history cannot be altered after the fact without detection — giving you a verifiable, provable record of exactly what ran. It can only be enabled at project creation:

  ```bash
  diagrid project create payments --deploy-managed-kv --deploy-managed-pubsub --enable-managed-workflow --enable-workflow-history-signing --use
  ```

  Signed histories persist in the project's workflow state store — the managed one, or a state store you bring yourself. See [Configure the workflow state store](https://docs.diagrid.io/operate/platform-operations/projects#configure-the-workflow-state-store).

Together these give you defense in depth across identity, access, messaging, and execution. For the bigger picture, read [Zero-trust security for distributed applications with Dapr](https://www.diagrid.io/blog/zero-trust-security-for-distributed-applications-with-dapr).

## 7. Export traces to your observability backend

Out of the box, Catalyst gives you [metrics, API logs, and the topology](https://docs.diagrid.io/operate/project-operations/observability) for every workload — no setup required. If you also run a centralized tracing backend, you can export distributed traces to any OpenTelemetry (OTLP) collector — Grafana Tempo, Jaeger, Datadog, or your own — so Catalyst traffic shows up alongside the rest of your telemetry. Create a `Configuration` for trace export and attach it to the apps whose traces you want to export:

```bash
# Create a configuration that exports traces to your OpenTelemetry collector
diagrid configuration create otel-export \
  --tracing-sampling-rate 1 \
  --tracing-otel-endpoint otel-collector.observability:4317 \
  --tracing-otel-protocol grpc

# Attach it to an App ID
diagrid app update orders-api --app-config otel-export
```

For a secured collector, add `--tracing-otel-secure` and `--tracing-otel-header 'Authorization:Bearer <token>'`. A single `Configuration` can combine tracing with access control, so attach one per app.

## 8. Hand the project off

The project is now a secure, ready-to-use space. Give the team access by adding users with a role scoped to this project. The role decides what each person can do:

- **Admin** — full control of the project: create and change apps, components, and policies. Give this to the team that owns the project.

  ```bash
  diagrid user create --email lead@example.com --name "Team lead" --role cra.diagrid:admin:projects:payments
  ```

- **Viewer** — read-only access to every resource, with no ability to change anything. Good for support staff or auditors.

  ```bash
  diagrid user create --email support@example.com --name "Support" --role cra.diagrid:viewer:projects:payments
  ```

Roles in between — such as `cra.diagrid:editor` — grant create and update access without full admin rights. See [Manage access](https://docs.diagrid.io/operate/platform-operations/identity-and-access) for the full role matrix, organization-wide roles, SSO, and API keys for automation.

The team then connects applications and agents (see [Connect to Catalyst](https://docs.diagrid.io/develop/connect)) and creates any additional apps and workloads. From there you operate and observe everything in one place: [workflows](https://docs.diagrid.io/operate/project-operations/workflows), [agents](https://docs.diagrid.io/operate/project-operations/agents), and [metrics, API logs, and the topology](https://docs.diagrid.io/operate/project-operations/observability).

## Manage Catalyst as code

Every command above has a declarative equivalent. Keep your projects, components, apps, and policies as YAML in Git and apply them with a single upsert command that works for any resource kind:

```bash
# Create or update any resource (project, component, App ID, policy) from YAML
diagrid apply -f payments-project.yaml
```

Use `diagrid export` to capture existing resources as YAML, and wire `diagrid apply` into CI/CD for GitOps. See [Declarative management](https://docs.diagrid.io/operate/project-operations/declarative-management).
