---
title: How to Secure DigitalOcean Harness Runtime Sessions (public)
description: A checklist for hardening a Harness Runtime session, covering workload isolation, credentials, egress, permission policies, unattended controllers, …
product: Managed Agents
url: https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/secure-sessions/
last_updated: "2026-10-13"
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# How to Secure DigitalOcean Harness Runtime Sessions (public)

DigitalOcean Harness Runtime provides managed, hardware-isolated microVM sandboxes with built-in tools such as Chromium to run harnesses and execute arbitrary code. Rich lifecycle APIs preserve conversational history and working state across sessions, letting you pause, resume, and fork work to control costs and adapt to the nonlinear nature of agentic workflows. Scale complete agents such as Claude Code or use sandboxes independently for code execution, all through the same service. See [What You Can Build](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/what-you-can-build/index.html.md) for example use cases.

An agent can write and execute code inside its sandbox, so what it can reach is whatever you granted it. This page is the checklist: the six things to decide before you run a session that matters, each with a pointer to the concept behind it.

Work through it in order. The first four are settings in the [environment spec](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/reference/environment-spec/index.html.md). The last two are things you do around the session.

## Isolate Users and Workloads

Use a separate session for each user or workload that must not share data.

Sandboxes are isolated from each other, so processes in different sandboxes cannot observe each other. Processes in the *same* sandbox share its files and credentials, which makes the session the unit of isolation. Keep any external session identifiers for a workload associated with its DigitalOcean session ID.

See [Environments and Sandboxes](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/concepts/environments/index.html.md).

## Declare Credentials as Secrets

Put every API key and token under `secrets`, never `env`, and issue each one with the narrowest scope the task needs.

```yaml
secrets:
  PROVIDER_API_KEY: ${PROVIDER_API_KEY}
```

The scope you request at the provider is the real boundary here, because any process the agent runs can read a value injected into the sandbox. Keep credentials out of images, workspaces, logs, and source control, and never save or log a manifest after variable substitution, because the resolved values include secrets.

See [Secrets and Configuration](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/concepts/secrets/index.html.md) for scoping guidance and what the secret store does and does not protect.

For GitHub, a brokered OAuth slot keeps the token out of your shell, local files, and `${VAR}` substitution, because DigitalOcean resolves it server-side. With the default scopes, though, an OAuth connection grants the `repo` scope across every repository the GitHub account can reach, so when the agent needs access to only specific repositories, use a fine-grained personal access token instead. Either way, the resolved token reaches the sandbox as a plaintext environment variable that any process the agent runs can read. See [Connect GitHub](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/connect-github/index.html.md).

## Restrict Outbound Network Access

List only the destinations the workload actually needs.

```yaml
egress:
  - registry.npmjs.org
  - api.internal.example.com
  - mcp.example.com
```

This one matters more than the others, because the default is open. A session with no `egress` field reaches any host on the internet. Naming even one host turns the allowlist on and denies everything else, and the platform then merges in the hosts a session cannot work without, such as GitHub and the model endpoints.

Two cases catch people out. Attaching an MCP server under `tools` does not allowlist its host, so list that host under `egress` as well. Tools reached through [Action Gateway](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/connect-action-gateway/index.html.md) need no entry at all, because the gateway calls the provider from its own infrastructure.

Every host you add is a place workspace data can go. Sandboxes accept no inbound connections from the internet; to reach a service the agent starts, use [port forwarding](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/forward-ports/index.html.md).

See [Network Egress](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/concepts/egress/index.html.md).

## Set a Permission Policy

Add an explicit `permissions` block with a restrictive default and targeted allow rules, so every decision is visible in the spec.

```yaml
permissions:
  default: ask
  rules:
    - tool: bash
      match: { command: "git *" }
      action: allow
    - tool: bash
      match: { command: "rm -rf *" }
      action: deny
```

Validate the policy, then confirm the behavior on a live session with the adapter you deploy, because enforcement differs between adapters. Policies and approvals do not apply at all to `codex-agentapi`, where OpenAI owns the agent loop.

See [Configure Permissions](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/configure-permissions/index.html.md) and [Permission Policies](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/concepts/permissions/index.html.md).

## Protect Unattended Controllers

When a schedule, webhook, or application provisions sessions with no operator watching, verify event authenticity before you create or destroy a sandbox.

Serialize provisioning per session so duplicate or concurrent deliveries do not create multiple billable sandboxes for one logical workload. Platform [triggers](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/run-agents-with-triggers/index.html.md) already verify signatures and drop duplicate deliveries. A controller you write yourself has to implement the same checks, including validating the current session before it creates, resumes, or destroys anything.

## Save Files Before Cleanup

Download or push anything you need before you remove the session, then remove every resource that owns billable compute or external state.

See [Transfer Files](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/transfer-files/index.html.md). Removing a DigitalOcean session tears down its sandbox. If another provider owns a session for the same workload, delete that resource separately and report cleanup failures on either side.

## Next Steps

- [Configure Permissions](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/configure-permissions/index.html.md) walks through policy validation on a live session.
- [Run an OpenAI Agents API Session](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/run-openai-agents-api-session/index.html.md) covers the extra requirements for `codex-agentapi`.
- [Environment Spec Reference](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/reference/environment-spec/index.html.md) documents the `secrets`, `egress`, and `permissions` fields.