# Ona Changelog Source: https://ona.com/docs/changelog Product updates and announcements ## Compare Automation models and usage per run Choosing an Automation model is easier when you can compare what each run used. Anyone who can view an Enterprise Automation run can now see its effective model and reasoning effort. Organization admins, Automation admins, and eligible Billing Viewers also see final Intelligence usage. Open an Automation's **Execution History** and select a completed run. Managed usage appears in credits, while bring-your-own-key usage uses configured prices or falls back to token counts when rates are missing. Automation runs flowing into a model and usage comparison panel [Learn how Automation run usage is calculated](/docs/ona/automations/running-automations#execution-history) ## What else we've shipped * Environment inventory filters now live in table headers, remain available on narrow screens, and persist in the URL for sharing. * New direct LLM integrations now use AWS Bedrock, AWS Bedrock Mantle, or OpenAI, while existing Anthropic and Google Vertex AI integrations remain editable. * Runner settings now use consistent lists and actions for providers, repository access, and environment classes. * Automation execution histories load faster as the number of retained runs grows. * OpenAI integration forms no longer show a model selector when there is only one available option. * VS Code and the CLI now show each port's effective admission level. * Dashboard dropdowns now handle pointer clicks reliably, including in secret creation forms. * Linear integrations now start the correct OAuth flow on first enable, while GitLab merge request Automations run only when commits are pushed. * Concurrent secret changes now propagate reliably to every affected environment. * Python SDK event streams now deliver updates as they arrive, including environment lifecycle and agent wait events. * Terminals recover after an environment restarts, and environment headers report lifecycle status without agent activity overriding it. ## Queue and steer Codex while it works Long Codex sessions no longer make you wait to share the next instruction. You can send follow-up prompts while Codex is running, see them in a queue, and steer the session toward the work that matters next. Review or remove pending prompts before Codex processes them. The conversation outline stays visible for supported sessions, so you can jump between turns as the thread grows. Generally available. Follow-up prompts entering a live Codex conversation with queue, steering, and outline controls ## What else we've shipped * File links in Codex responses now scroll the selected line into view. * Slack links and agent access tokens use the correct origin for organizations with custom domains. * Multiline slash commands preserve their review context when Codex expands them. * Custom environment classes once again show the instance type selector. * Environment inventory pagination remains clickable when the support launcher is hidden. ## Send user details to your model gateway Organizations that route Codex through an OpenAI-compatible gateway can now add request headers for each environment creator. Use them to route requests, apply gateway policies, or attribute model usage without maintaining a separate user mapping. Configure a fixed header or build one from signed identity details such as the creator's email or identity-provider attributes. Ona resolves these values when a conversation starts. If it cannot resolve one header, the conversation continues with the remaining headers. User identity details flowing through request headers to a model gateway [Learn how to add custom request headers](/docs/ona/agents/llm-providers/openai#add-custom-request-headers) ## What else we've shipped * Codex Goal sessions resume more reliably after an agent restart. ## Run Automations with parameters Automation parameters flowing into a Run with options form and completed runs Manual Automations can now ask for the inputs they need before a run begins. Add a named parameter such as `{{ .Parameters.ticket_id }}` to a prompt, command, pull request field, or agent context. When you click **Run**, Ona opens **Run with options** and requires a value for each parameter. You can also choose different projects or repositories for that execution without changing the Automation. Parameters work through the API too, so external tools can start the same Automation with different inputs. [Learn how to run an Automation with parameters](/docs/ona/automations/running-automations#run-with-parameters) ## What else we've shipped * `ona environment port open` now requests creator-only port access by default, while older runners fall back to public access with a warning. * Organization settings now separate policy and security controls while grouping secrets with other environment settings. * Cost & Budgets pre-fills published prices for supported OpenAI models when you configure your own provider key, without replacing saved rates. * Live conversations display updated responses without retyping, prevent duplicate question responses, and recover file diff rendering reliably. * OAuth flows and integration links keep custom-domain users on the correct Ona domain, while GitHub reauthentication replaces stale credentials correctly. * Maximum environment lifetime changes apply to existing environments, and recently changed environment resources refresh without stale state. * Codex preserves each conversation's model routing and resumes Goal sessions reliably. * Sidebar search remains readable in dark mode, and environment file searches expand to use the available space. ## Search sessions from the sidebar A magnifying glass scanning a list of sessions Busy sidebars make the session you need hard to spot. You can now search sessions by environment name or ID, branch, repository, project, and agent task details. Search works across **Project** and **Recently active** views while keeping related parent and child sessions together. ## What else we've shipped * Core and Enterprise members can choose a default auto-stop timeout from **Account Settings > Preferences** for newly created environments unless a timeout is set explicitly. * The AI home prompt now has compact controls for choosing a project, repository URL, or existing environment before starting work. * The CLI can archive one or more environments by ID or name with `ona environment archive`, and uses the current environment when no reference is given. * Editor, OIDC, billing, and general settings pages now use consistent page headers, actions, and mobile layouts. * Conversations with large environment log histories load faster and use less browser memory. * Codex model choices and context window settings stay consistent while settings and policies load and after a run starts. * Enterprise members can open Automations shared with them and follow direct links even when they cannot create new Automations. * Large organizations can grant the Projects Admin role reliably, including across thousands of projects. * Custom OpenAI-compatible endpoints keep their configured path prefixes when Ona sends Responses or Chat Completions requests. * VS Code on Windows preserves quoted Ona SSH proxy commands, so Remote SSH connections open correctly. ## Connect multiple GitHub organizations Three GitHub organizations connected to one Ona GitHub App Repositories do not always live under one GitHub organization. You can now connect one Ona organization to multiple GitHub organizations through the Ona GitHub App. Add each installation from **Organization Settings > Integrations**, then choose the matching `github.com/` source when configuring a pull request-triggered Automation. Each installation can be enabled, disabled, or removed independently. The built-in Ona service account uses GitHub App credentials for repositories covered by each installation, so PR review Automations do not need a separate personal access token. [Learn how to connect GitHub organizations](/docs/ona/integrations/configure-github) ## Pin sessions in the sidebar A sidebar session moving into a pinned group at the top of the list You can now pin active sessions in the sidebar to keep important work easy to find as you continue iterating. Pinned sessions stay at the top of both **Project** and **Recently active** views, so you can jump back into ongoing work without digging through your session history. Pinning a session does not change its environment retention or lifecycle policy. ## Pull usage data through the API Usage metrics flowing from Ona into connected API dashboards Enterprise teams can now pull more usage data out of Ona without opening the dashboard. New API and SDK access covers AI cost usage and Insights metrics, so platform teams can feed spend, adoption, co-authoring, agent trace, and pull request trends into their own reports. Use personal access tokens or service accounts with the right billing or insights viewer role. The Insights API is documented with copy-pasteable requests and examples for each endpoint. ## What else we've shipped * Organization policy settings are easier to scan, with environment, project, security, command, and identity controls grouped in the newer settings layout. * Agent policy settings now use clearer sections and inline availability controls. * Members and service accounts now see a more consistent integration authentication flow. * Billing pages stay available when current balances are temporarily unavailable, and Core subscription setup handles retry cases correctly. * Insights API `userId` filters scope results to one user instead of returning organization totals. * Conversations with older history now show visible messages correctly while earlier messages load. * Interrupted agent runs recover more reliably instead of leaving an agent busy. ## Claude Sonnet 5 is now available A glowing model core marked 5 surrounded by orbiting neural rings Anthropic's latest model, Claude Sonnet 5, is now available on Ona Cloud and Enterprise. On Cloud, the next time you start the Ona agent it uses Sonnet 5 automatically. On Enterprise, availability depends on your administrator's configuration. Sonnet 5 brings stronger reasoning and coding to your agents with no setup required. ## What else we've shipped * Linear agents are now available to every organization, so you can drive Ona sessions straight from Linear issues. * Slack agents are now available to every organization, letting you start and follow Ona sessions from Slack. * Admins can set a Goal mode policy for Codex agents from organization Agent settings, controlling whether members can run agents in goal mode. * A page-load notification now tells you when sessions have been archived, with a link to review them and an option to silence future reminders. * The context window usage popover in the chat footer is clearer, showing context pressure, token rows, and monthly budget at a glance. * Model colors on the daily usage chart stay consistent from day to day, so a model keeps the same color instead of swapping as spend changes. * The Codex logo now appears on the Conversation tab as soon as you select a Codex model, even before the first run starts. * The prompt input is focused automatically when you open a new conversation, so you can start typing right away. ## Switch sessions with keyboard shortcuts Sidebar sessions with numbered shortcut pills and a selection highlight jumping between rows Jumping between sessions no longer means reaching for the mouse. Hold Cmd (or Ctrl on Windows and Linux) and the sidebar reveals a numbered pill on each visible session. Press the matching number, from 1 to 9, to switch straight to that session. The shortcuts are always on in Ona Desktop. On the web, turn them on from your account preferences, and the same keys work from inside a conversation so you can move between tasks without leaving the one you're in. ## What else we've shipped * Codex agents now run shell commands inline: prefix a prompt with `!` to execute it as a shell command instead of sending it to the model. * You can archive an environment directly from its sidebar menu, without opening the environment first. * GitHub App integrations are now available to all organizations using GitHub.com, so admins can install the App from Organization Settings and use it as a pull request trigger source. * Dashboard lists load faster and refetch less often across environments, runners, projects, members, secrets, and prompts. * The "some AI usage is not included in spend" banner on Cost & Budgets now has a button that opens the rate-management dialog directly. * Stale Gitpod branding in the dashboard has been replaced with Ona branding. * Conversation file links open the right file even while the environment is still loading. * Review comments now go to the session you have selected in the conversation. * SCIM group membership updates handle duplicate member additions correctly, so directory syncs stay reliable. ## Older updates ## User budgets for AI usage Per-user budget bars rising toward a dashed monthly budget line Enterprise admins can now set monthly AI usage budgets for every member of their organization. Set one default budget for all users, then override it for individual users where needed. Budgets cover credit-billed AI usage and model spend through your own provider keys (BYOK), and each user sees their own utilization in the chat input as they work. Budgets are soft limits for visibility: nobody is blocked when they exceed one. Over-budget users are highlighted on **Settings > Usage**, and budgets are included in CSV exports. [Learn more about user budgets](/docs/ona/billing/user-budgets) ## Configure archive timing for environments Archive timing policy controls for the environment lifecycle Admins can now choose when stopped environments move to Archived. Set the organization policy from **Settings > Organization > Policies**, with options from 1 to 30 days. Enterprise environments archive after 3 days by default. Core environments continue to archive after 3 days and auto-delete 4 days after archival. [Learn more about archive and auto-delete](/docs/ona/environments/archive-auto-delete) ## What else we've shipped * Ona now supports Devin Desktop. * Admins can now disable start-from-scratch environment creation for non-admins while keeping project and Git URL creation available. * Automation task failures now appear in the environment view, with a direct action to open logs or review failed tasks. * Agents now have built-in dev container setup guidance for creating or repairing repository development environments. * Automation names and descriptions can now be edited inline and saved with the rest of the automation draft. * Autocomplete fields behave more consistently with keyboard navigation and assistive technology. * Billing, usage, insights, terms, and automation summary pages respond faster. * Core subscription setup completes faster and shows steadier loading states while payment details are saved. * Long agent questions scroll correctly instead of overflowing the clarifying-question drawer. * The dashboard sidebar responds correctly on iPad Safari. * GitLab merge request listing avoids timeouts on larger projects. ## Read-only billing and insights access Read-only organization roles for Insights Viewer and Billing Viewer Enterprise organization admins can now assign **Insights Viewer** and **Billing Viewer** roles to groups. Use these roles when finance, customer success, or engineering leaders need reporting access without full organization admin privileges. Insights Viewers can open **Insights** from the sidebar and review platform usage, Velocity, and AI Adoption data for projects where insights are enabled. Billing Viewers can open **Settings > Billing** and **Settings > Usage** where those pages apply to their organization, but cannot change subscriptions, payment methods, top-ups, or budgets. [Learn more about organization roles](/docs/ona/organizations/organization-roles) ## What else we've shipped * Scheduled Automations can now run every weekday, so recurring work can run Monday through Friday without a custom cron expression. Daily schedules are still available for runs that should include weekends. * The Insights sidebar item now appears for members with the Insights Viewer role, matching direct access to the Insights page. ## Bitbucket Cloud support Bitbucket bucket logo with glowing light beam Bitbucket Cloud is now available as a source control provider. Ona agents can create, review, and manage pull requests, add inline comments, check CI status, and search repositories in Bitbucket, just like they already do with GitHub and GitLab. You can also set up automation triggers from Bitbucket webhooks. Trigger automations on PR events (opened, updated, merged) the same way you do with GitHub and GitLab. [Learn more about webhooks](/docs/ona/automations/webhooks#creating-a-webhook). ## What else we've shipped * Agents authenticate with the `gh` CLI for GitHub API operations, so tools that call the GitHub API directly work without extra configuration. * Permission checks and role lookups are faster across the dashboard. * The GitHub App install flow no longer redirects when the app is already installed. * Agents can restart stopped environments without a false billing error. * Plan selection no longer flashes during subscription changes. * Conversations scroll to the latest message on page reload. * Streaming conversations display all messages reliably mid-response. * Diff rendering works correctly after a dependency update. * Automation search returns results correctly when filtering by name. ## Set auto-stop timeouts from the CLI CLI prompt and blinking cursor flanking a clock with a countdown arc The CLI now supports an `--inactivity-timeout` flag for environments. Set how long an environment stays running after you stop interacting with it. Useful when scripting environment creation or adjusting timeouts without opening the dashboard. ```bash theme={null} ona environment create --class-id --inactivity-timeout 1h ona environment update --inactivity-timeout 3h ``` Request no auto-stop: ```bash theme={null} ona environment update --inactivity-timeout 0s ``` The same policy enforcement applies as in the dashboard. Values remain subject to your organization's plan and maximum timeout policy. ## What else we've shipped * Run `/ona:about` to see which tools are loaded, which are available on demand, and which skills are active along with their source. * Agent conversations restore faster after reconnecting. * Conversations recover automatically after a brief network interruption without requiring a page reload. * Agent sessions start reliably and preserve context across multi-step tasks. * Insights correctly attributes AI-authored code in squash-merged PRs across GitHub, GitLab, and Bitbucket. * The usage page loads correctly for 31-day months in DST-shifted timezones. * Project settings save succeeds even when a previously configured environment class was removed. ## Sort the sidebar your way Three sidebar view cards shuffling between Project, Recently Active, and Archived views The sidebar now lets you switch between three views. By default you see the **Project** list you're used to today. Select **Recently active** for a chronological view grouped and sorted by recent activity, or **Archived** to view environments soon eligible for clean-up. Your choice of **Project** or **Recently active** is remembered across sessions. ## What else we've shipped * The agent's plan steps appear as a live todo list in the conversation. * The agent explores your codebase faster by reading files concurrently. * Integration tool failures are now visible in the dashboard status panel. * Large repositories initialize faster. * Dashboard pages across billing, integrations, and runner settings load faster. * Environments stay active while you are using the dashboard. * Stopping the agent mid-response no longer shows an error banner. * The agent recovers cleanly after a brief restart without leaving a stale error message. * Runner availability warnings only appear when a runner is genuinely unavailable. * Custom domain authentication completes reliably. ## Port authentication is now available Shield with lock surrounded by orbiting port nodes and flowing access tokens Shared ports now require authentication. When you open a port from the dashboard or CLI, you choose an access level: creator only, organization members, or anyone. Ona validates the visitor's identity before serving the port, so a shared URL no longer means unrestricted access. Organization admins can cap the maximum admission level from **Settings > Organization > Policies**, preventing members from sharing ports more broadly than policy allows. If a user requests a wider level than the cap, the dashboard disables the option and the CLI rejects the request. Set the access level in the dashboard's Open Port dialog, or pass `--admission` on the CLI: ```bash theme={null} ona environment port open 3000 --admission creator_only ona environment port open 8080 --admission organization ``` See the [port sharing documentation](/docs/ona/integrations/ports) for the full access-level reference and the browser retry flow. ## What else we've shipped * Agent sessions now show a "Thinking…" indicator while the model is processing, so you can tell the agent is working before any output appears. * You can filter sessions by project, recently active, or archived status from the sessions list. * Slash commands like `/clear` and `/support-bundle` are now surfaced in the agent prompt, so you can discover them without memorizing syntax. * User messages in the agent chat display a footer with the message type, timestamp, and a copy button. * The prompt textarea now shows a character count and blocks submission when the message exceeds the limit. * Drag-and-drop reordering in the dashboard now supports full keyboard navigation. * Typing in the agent prompt textarea is responsive again after a lag that could reach \~1s per character. * Environments start noticeably faster. * Error messages when insights prerequisites are missing now describe the actual issue instead of suggesting a retry. * Idle agent conversations are cleaned up automatically when no longer active. * The review button in the agent chat now diffs the branch against main, not just uncommitted files. * MCP tool errors now surface the actual error message so you can act on them. * The user settings page loads correctly in all configurations. * Dark mode checkboxes are easier to see with improved contrast for the unchecked state. * Insights caches now refresh correctly when you toggle project insights on or off. * New environments created from prebuilds now start with a clean git identity. ## Bring your own Terms of Service to Ona Terms document flowing into an acceptance report with CSV export Enterprise organization admins can now require members to accept a custom terms of service before using Ona. Write the terms in Markdown from **Settings → Organization → Terms of Service**, and members are prompted to read and accept on their next dashboard load. Editing the text publishes a new immutable version and prompts members to re-accept; earlier versions remain queryable for compliance. Track per-member status under **Settings → Organization → Members → Terms Acceptance**, and export the report as CSV when you need it outside the dashboard. See the [Terms of Service documentation](/docs/ona/organizations/terms-of-service) for setup, the supported Markdown subset, and the CSV column reference. ## What else we've shipped * Organization roles now include **Environments Reader**, so service accounts and groups can list every environment in an organization without receiving update or delete access. * GitHub pull request mentions now understand `@ona-agent stop` and `@ona-agent cancel`, so anyone who can mention the agent can stop an active run on that PR. * Organization admins can set a maximum port admission level for shared ports, including creator-only, organization-only, and public access. * GitHub App uninstall events now cancel any active PR-mention sessions for that installation, so runs do not keep retrying after the app loses access. * Agent runs that lose their runner or stop making progress are now stopped automatically instead of remaining active indefinitely. * Ports can be deleted correctly when an organization has a restrictive maximum port admission policy. * GitHub PR mentions clear the watching reaction when a pull request is closed or its branch is deleted. ## Tag @ona-agent on a GitHub pull request An @ona-agent mention on a GitHub pull request flowing into an Ona agent Comment `@ona-agent` on a pull request and an Ona session starts on the PR and replies in the thread. Use it for follow-up changes, missing tests, or fixes you spot during review. Mentions work in PR comments, inline review comments, and review submissions. The agent reads the PR diff and recent comments, then follows the prompt you wrote alongside the handle. Mention `@ona-agent` on its own and the agent reviews the PR. Install the [Ona GitHub App](/docs/ona/integrations/configure-github) on your organization to enable it. Available on the Free and Core plans. [Contact sales](https://ona.com/contact/sales) to enable it for Enterprise. [Learn more about mentioning Ona](/docs/ona/integrations/github-pr-mentions) ## What else we've shipped * The Ona GitHub App can now drive PR-triggered automations directly, so you no longer need to set up a separate webhook to run automations from pull request events. * A built-in Ona service account ships with every organization and uses the GitHub App for source control, replacing manually-rotated personal access tokens. * The terminal in the dashboard is available to everyone, so you can open a shell next to your conversation without leaving the browser. * `ona insights analyze-pr-stats` now works with GitHub Enterprise, GitLab, and Bitbucket Cloud, on top of GitHub.com. * You can bulk-select prebuilds on a project's Prebuilds tab and cancel or delete them in one action. * Register for the [Background Agents Virtual Summit](https://background-agents.com/summit) directly from the dashboard. * VS Code Desktop and VS Code Browser now open directly into the editor without the embedded Ona environment details and conversation view. The embedded view duplicated the dashboard experience, was constrained by VS Code's webview capability which prevents building a rich user experience. * Port authentication cookies refresh automatically when they go stale, so previewing a service no longer needs a manual reconnect. * The environment list is easier to navigate with assistive technologies and offers larger touch targets on mobile. * The Activity button shows a blue unread dot when the sidebar is collapsed, so you don't miss new notifications. * The "Run Prebuild" button is clearly labelled instead of just "Prebuild". * Clarifying questions from the agent render as markdown, so links and code spans display correctly. * Insights summary cards report the same active-user count as the chart and tab below them. * The browser panel now has a reconnect button when the preview disconnects. * The browser address bar accepts `localhost:port` URLs without rewriting them. * Conversation history downloads reliably, even when an agent run has no captured logs to attach. ## Bring your own MCP servers to your organization Custom MCP servers plugging into an organization Administrators can now add custom MCP servers to an organization from the dashboard. Enable a server once in [Settings > Integrations](https://app.ona.com/settings/org-integrations) and it becomes available to every member of the org. The first time a member uses the integration, Ona handles the OAuth handshake with the server. Each user then connects their own account from [User Settings > Integrations](https://app.ona.com/?user-settings=integrations), and agents act with that user's permissions. Add MCP Integration dialog with name, MCP URL, and description fields See the [MCP documentation](/docs/ona/mcp#custom-organization-mcp-integrations) for setup and current limitations. ## What else we've shipped * Environments can now issue short-lived OIDC tokens for keyless authentication to AWS, GCP, Vault, and anything else that accepts OIDC trust policies. Configure them in Settings > Login & Identity. New organizations start on OIDC V3 by default. * Settings in the dashboard are grouped into sections like Login & Identity, Billing, and Agents, so you can find the page you need without scanning a long flat list. * File paths in chat are clickable now. Jump straight to the file the agent is referring to without copy-pasting. * Collapsed agent actions show a summary of how many files were read, written, and touched overall, so you get the gist without expanding every step. * The file tree in the dashboard handles large repositories noticeably faster. * Attached images in chat render as square, scroll-friendly thumbnails instead of stretching the conversation layout. * The Create PR button hides itself once the agent has already opened one, so you can't accidentally open a second PR for the same change. * The CLI log commands now default to print-and-exit, with `--follow`/`-f` to tail. The previous `--no-follow` flag is removed. Scripts that relied on `--no-follow` will need updating. * Insights default date ranges exclude today, so charts reflect complete days only. * Your terminal agent selection is remembered between sessions. * Recent Tasks shows your environment's current name after you rename it. ## A new way to collaborate with Ona Redesigned conversation view showing the two-panel layout with conversation and code changes side by side We redesigned the way you collaborate with Ona, focusing around the relationship between you and the agent. Your conversation and the agent's output now live side by side so you can move from exploration to review without rebuilding context. * Your conversation and code changes sit side by side in a two-panel layout. The agent stops being a separate window you talk to and becomes a partner looking at the same screen you are. * Leave inline comments on any changed file — they feed directly back into the conversation so the agent can act on your feedback without a context switch. * Ports, services, and logs move into a collapsible bottom drawer. They stay accessible without competing for the same visual priority as your dialogue or your code. * Browse your conversation, file changes, and comments even when the environment is stopped. The interface works with whatever context is available so you can pick up where you left off. * A searchable file tree with inline diffs replaces the previous changes panel — review what the agent touched without switching away from the conversation. * Purpose-built tabs for conversation, files, and environment give each phase of your workflow a focused view. ## Self-serve GCP Runners Self-serve GCP Runners You can now deploy GCP runners directly from the dashboard. A three-step setup wizard using the public [Terraform registry module](https://registry.terraform.io/modules/gitpod-io/ona-runner/google/latest) walks you through generating credentials, defining the module in `main.tf`, and running `terraform apply`. The [GCP runner docs](/docs/ona/runners/gcp/setup) have been updated to match. Available on [Enterprise plan](https://ona.com/pricing). ## What else we've shipped * Draw annotations on the browser viewport and send annotated screenshots to the agent with a text comment. * Agent conversations show a shimmering status indicator during environment startup and while the agent is thinking. * Right-click any file or folder in the file tree to copy its path to the clipboard. * Automation services can now be triggered during prebuilds, matching the behavior already available for tasks. * CLI log commands (`environment logs`, `environment devcontainer logs`, `automations service logs`, `automations task logs`) support a `--no-follow` flag to print existing logs and exit. * The sidebar create-environment button shows a smooth spinner animation while the environment is being created, then fades out when it finishes. * VS Code and JetBrains extensions find the `ona` CLI correctly on systems that upgraded from the previous `gitpod` binary name. * Dragging a non-image file into the chat now explains how to share it via the workspace file explorer instead of showing a generic error. * Annotated browser screenshots send reliably, even at high display resolutions. ## Install the CLI with Homebrew Terminal showing brew install gitpod-io/tap/ona The Ona CLI is now available via [Homebrew](https://brew.sh/) on macOS and Linux: ```bash theme={null} brew install gitpod-io/tap/ona ``` The formula auto-detects your OS and architecture. Updates are handled by `brew upgrade ona`. [CLI documentation](/docs/ona/integrations/cli) ## What else we've shipped * Type `@` followed by a filename in the chat input to get file suggestions and insert file references into your prompt. * Automation triggers now support up to 500 projects and repositories, up from 25 and 100. * SSO login preserves the return URL and no longer auto-redirects in the desktop app. * The support widget hides when VS Code fills the browser viewport. * Idle environments now time out reliably instead of running indefinitely. * Admins can no longer modify automation steps that run as another user. ## Granola integration Granola integration settings page Ona agents can now connect to your [Granola](https://www.granola.ai/) account to search meeting notes, read transcripts, and extract action items. Ask an agent to find a past discussion, pull out follow-ups, or cross-reference a meeting decision with your code, all without leaving the conversation. An admin enables Granola under **Organization Settings > Integrations**, then each user connects their account in **User Settings > Integrations**. Once connected, agents can query any meeting you own by title, date, or attendee. ## What else we've shipped * Ona now knows today's date, so time-relative questions like "what merged this week?" work without extra context. * After completing a recurring task, Ona suggests turning it into an automation you can run on a schedule or on PR events. * Dev container rebuilds now pause the conversation until the environment is back, instead of continuing while the rebuild runs. * Image attachments in the chat input persist when you switch between conversations. * Terminal input is noticeably faster when typing quickly or pasting large blocks of text. * Members and projects lists show the total result count alongside pagination controls. * Ona handles long responses gracefully instead of surfacing internal continuation messages in the conversation. * The sidebar status correctly shows "Waiting for environment" when Ona is waiting for an environment to start. ## Warm pools are generally available Warm pool configuration in project settings Opening a new environment for a large project can take minutes while the runner provisions an instance and loads your prebuild. Warm pools change that. They keep ready-to-use instances standing by so environments start in seconds instead of minutes. Enable a warm pool on any project from its [project settings](/docs/ona/projects/warm-pools). Set a minimum and maximum pool size, and Ona keeps instances pre-initialized with your latest prebuild. The number of warm instances scales dynamically based on load, staying within the range you configure. **What you can do now:** * **Start environments in \~10 seconds** for projects that previously took minutes, especially large monorepos and heavy dev containers. * **Set min and max pool sizes.** The pool scales dynamically based on load within the range you set, so you're not paying for idle capacity during off-hours. * **Instances stay fresh.** Warm pool instances rotate daily so they always run the latest OS and software updates. Warm pools require an Enterprise plan and a [runner upgrade to the latest version](/docs/release-notes/aws-runner#20260402401). If your runner needs an upgrade, the dashboard will show a prompt. See the [warm pools documentation](/docs/ona/projects/warm-pools) to get started. ## What else we've shipped * Members and projects lists show the total result count alongside pagination controls. * Terminal input is noticeably faster when typing quickly or pasting large blocks of text. * The automation list shows who triggered the last run, not who created the automation. * The webhook selector dropdown in automation settings no longer appears empty. * The CLI auth code page now shows visible borders around code blocks. ## Ona can merge pull requests Ona merging a pull request from the conversation Ona can now merge pull requests and merge requests directly from the conversation. Ask Ona to merge a PR and it handles the merge method (merge, squash, or rebase), sets the commit message, and deletes the source branch afterward. Works with both GitHub and GitLab, including GitLab's merge-when-pipeline-succeeds option. This completes the PR lifecycle inside Ona. You can now create a branch, write code, open a PR, review changes, address feedback, and merge, all without leaving the conversation. ## What else we've shipped * Import a `.env` file to bulk-create secrets on any secrets page. Drag and drop or browse, preview parsed variables, and import them all at once. * File search in the `All Files` panel now returns a flat, relevance-ranked list with fuzzy matching instead of expanding tree nodes. * The `Review` button shows a dropdown of your organization's review skills when available, so you can pick a review style without typing slash commands. * Opening the command palette (Cmd+K) now lists your environments immediately, with running ones sorted first. * Ona can create new projects directly from a conversation. * Copy the current branch name from the environment header dropdown. * The project home page shows live `Speed`, `AI Adoption`, and `Authors over Time` insight cards with real data. * Insights chart labels and descriptions are clearer, with explanations moved below the graph. * Press Esc to dismiss the clarifying questions panel. * Terminal reconnections are smoother, with no visual flicker when resuming a session. * Environments with persisted file tabs stay stopped until you explicitly start them. * Cmd+W on macOS hides the Desktop window instead of quitting the app. * Slack sessions resume automatically after completing OAuth connection. * Dot-prefixed files and directories now appear in the file tree. * Automations run more reliably through long multi-step tasks. ## Maximum environment lifetime Maximum environment lifetime policy settings The [maximum environment lifetime](/docs/ona/organizations/policies/environment-lifetime) policy is now available to all organizations. Set a maximum age for environments and optionally block restarting expired ones, useful for enforcing security policies, ensuring fresh base images, or meeting compliance requirements for environment rotation. Configure it under **Settings > Organization > Policies**. Pick a duration (1 day to 6 months), and new environments receive an expiry based on the configured duration. Once an environment passes its expiry, it becomes non-compliant. Turn on **strict enforcement** to prevent users from restarting expired environments entirely. A compliance banner shows how many environments are affected and how many will expire within 24 hours. ## What else we've shipped * Send individual review comments to Ona from the per-comment dropdown menu, in addition to the existing bulk action. * Failed environments show a one-click retry button when a transient error prevents them from starting. * The ports empty state now matches the services UI with clearer guidance on what to do next. * You can select a default environment class directly on the project details page. * The dashboard loads faster by deferring terminal resources until you open a terminal tab. * Disabled actions now show a tooltip explaining why they are unavailable when the agent is working. * Environments can be restarted from the dashboard while still stopping. * SSH tunnels through ports work without requiring separate authentication. * The diff viewer handles lines starting with "--" correctly. * Port access tokens now last 24 hours instead of expiring prematurely. * File search in environments skips .git and node\_modules directories. * Agent conversation history is preserved when the runtime shuts down. ## Live secret propagation Live secret propagation Secrets now propagate to every environment in their scope the moment you create, update, or delete them. Organization secrets reach all environments in the org. Project secrets reach all environments in the project. User secrets reach all environments for that user. File-based secrets and container registry credentials update in place. Environment variable secrets may need a dev container rebuild — when that happens, a prompt appears in VS Code and the dashboard with a one-click rebuild button. ## What else we've shipped * [Personal access tokens](/docs/ona/integrations/personal-access-token) can now be scoped to read-only or read & write access. * Service account tokens can now be set to never expire or expire after one year. * Dashboard tables have sticky headers and a floating action bar for working with multiple items at once. * Credit auto top-up is now available to all organizations on the core tier. * Environments start noticeably faster. * A new Audit Log Reader role lets you grant read-only access to your organization's audit logs. * Resource usage warnings are clearer and include suggestions for what to do next. * Secrets added or changed while an environment is running now appear inside the container without a restart. * Repositories with submodules now clone correctly in more environment configurations. * Scheduled automations run more reliably on their configured schedule. ## Faster, smoother, more helpful Speed, onboarding, and CLI improvements This week we focused on speed, onboarding, and fixing the small things that add up. Environments start faster. The CLI is more forgiving. And if you're new to Ona, the product now meets you where you are. **Environments start faster.** Internal caching improvements shave time off every environment start. The dashboard sidebar also loads noticeably quicker. **Getting started has fewer steps.** GitLab users can now sign in during onboarding with one click. GitHub users skip a redundant login because Ona reuses your existing credentials for Git access. And if your repository doesn't have an environment configuration yet, a notification guides you through creating one. **The CLI speaks your language.** Reference environments by the first few characters of their ID instead of copying the full UUID. ## What else we've shipped * Prebuild details now show how much disk space each snapshot uses. * Automations can now be created and managed through the API. * The environment details page has a cleaner layout for services, ports, and tasks. * When a runner is having issues, a direct link to download diagnostic logs appears in the dashboard. * The CLI reconnects automatically when a connection drops instead of hanging silently. * SSH connections work correctly when Ona is installed in a folder path that contains spaces. * Questions from the agent now appear outside collapsed sections, so you never miss a prompt that needs your input. * Code changes update in real time in the session panel. * When no machines are available, the error message now explains what happened and what to do next. ## Plan mode
Start every task with a plan. Plan mode adds a structured planning phase to Ona sessions where the agent gathers requirements through interactive questions, writes a specification, and waits for your approval before writing any code. Select "Plan" from the mode dropdown in the session input or from the home screen. Describe your task, and the agent asks clarifying questions as clickable multiple-choice options. Pick a choice, type a custom answer, or skip. Once the agent has enough context, it writes a `spec.md` with the full implementation plan. Review the spec, then click **Build** (or press `Cmd+Shift+Enter`) to start implementation. Available on all plans. ## What else we've shipped * Forward environment ports to your local machine with `ona environment port forward`. * Ona prompts you to rebuild the dev container when you change a secret, so the new value takes effect immediately. * PR links and preview URLs now appear as clickable outputs in the session. * Environments start faster, especially for repositories with many files. * Sessions with screenshots respond faster. * A banner in the session view suggests converting a repository to a project for faster startups. * Long-running agent tasks no longer disconnect mid-stream. * The CLI reconnects automatically instead of hanging on a dropped connection. * Stale action buttons are cleared when they no longer apply. ## Code review experience
Review code changes and request reviews from Ona directly in the session. **Leave inline comments** — Review Ona's work by leaving inline comments in the code changes panel, just like reviewing a PR. Highlight the relevant code lines, leave your questions or feedback, and send them off to Ona. Ona will act on the comments accordingly. **Request a review from Ona** — Ask Ona to review the current code changes before merging. Ona examines the diff, leaves inline comments with suggestions, and flags potential issues — giving you a second pair of eyes without waiting for a teammate. **Create a PR directly** — Once you're happy with the changes, create a pull request straight from the session. No need to switch to your Git provider — Ona commits, pushes, and opens the PR for you. ## Organization skills [Agent Skills](https://agentskills.io) now work at the organization level. Create reusable skills that Ona Agent discovers and uses proactively across every session in your organization. Skills capture your team's best practices (code review checklists, test strategies, deployment procedures) and share them with everyone. **What you can do:** * **Create and edit skills** with a name, description, and prompt. The description tells the agent when to apply the skill automatically. * **Optional slash commands.** Toggle a `/trigger` so users can also invoke a skill manually in the chat. * **Import defaults.** Start with a curated set of skills (Pull Request, Documentation, Explain Code, Catch Up) and customize from there. * **Search and filter.** Find skills by name, description, or trigger. * **Migrate legacy commands.** Existing slash commands can be migrated to skills with one click, preserving their trigger while enabling proactive discovery. Manage skills from **Settings → Agents** in the dashboard. Ona settings interface for creating a new skill with name, description, prompt, and optional slash command trigger [Learn more about organization skills](/docs/ona/skills) ## Organization roles for groups Delegate administrative responsibilities in your [Enterprise](https://ona.com/pricing) organization without granting full admin access. Assign organization roles to [groups](/docs/ona/organizations/groups) so team members can manage specific resource types across the organization. **Available roles:** | Role | Grants admin access to | | --------------------- | ---------------------- | | **Runners Admin** | All runners | | **Projects Admin** | All projects | | **Groups Admin** | All groups | | **Automations Admin** | All automations | Toggle role checkboxes directly in the groups table under **Settings → Members → Groups**. When a role is assigned, all group members immediately receive admin permissions on existing and future resources of that type. Groups table showing organization role checkbox columns [Learn more about organization roles](/docs/ona/organizations/organization-roles) ## Automations Automations execute multi-step workflows across your repositories — from routine maintenance to large-scale refactoring. Define steps, choose a trigger, and let them run in isolated environments with your tools, dependencies, and guardrails. Automation configuration showing steps, trigger, and guardrails **How it works:** 1. **Define** — Combine steps in sequence: prompts (agent-driven tasks), shell scripts, pull request creation, and report extraction 2. **Trigger** — Run manually, on pull request events via [webhooks](/docs/ona/automations/webhooks), or on a [time-based schedule](/docs/ona/automations/triggers/timebased) 3. **Execute** — Run across repositories in parallel, each action in its own isolated environment 4. **Review** — Monitor progress in real time, inspect logs, and approve PRs before merging Automation execution dashboard with action statuses and logs **Templates** — Start from pre-built templates for common workflows: Sentry error triage and fix, 10x engineer (picks up your top Linear issue and delivers a PR), code review, and more. Templates are gated on required [integrations](/docs/ona/integrations/overview), so you only see what you can run. Template grid showing available automation templates **Sharing and access control** — Share automations with everyone in your organization, individual users, or [groups](/docs/ona/organizations/groups). Assign roles to control what recipients can do: | Role | Permissions | | ------------ | --------------------------------------------- | | **Admin** | Edit, delete, share, run, view all executions | | **Executor** | Run and view own executions | | **Viewer** | Read-only access | **Service accounts** — Run automations as a [service account](/docs/ona/organizations/service-accounts) for scheduled and event-driven workflows. Commits and PRs appear under the service account identity, separating automation work from human work. **Guardrails** — Control execution with concurrency limits, total action caps, [command deny lists](/docs/ona/command-deny-list), environment isolation, and [audit logging](/docs/ona/audit-logs/overview). **Webhooks** (Enterprise) — Create standalone [webhook](/docs/ona/automations/webhooks) endpoints for GitHub or GitLab. Scope to a repository or organization, and reuse a single webhook across multiple automations. **Availability** — Automations are available on Core and Enterprise plans with [plan-based limits](/docs/ona/automations/plans-and-limits) on automations, concurrent actions, and features like webhooks. [Learn more about automations](/docs/ona/automations/overview) · [Create your first automation](/docs/ona/automations/configure-automations) · [Automations in practice](/docs/ona/automations/automations-in-practice) ## SCIM provisioning (beta) Ona now supports SCIM (System for Cross-domain Identity Management), letting your identity provider automatically create, update, and deactivate user accounts. Link SCIM to an existing SSO provider, and directory changes in your IdP are reflected in your Ona organization without manual intervention. Currently supported identity providers: * **Microsoft Entra ID** [Learn more about SCIM provisioning](/docs/ona/scim/overview) ## New MCP integrations: Atlassian, Notion, and Sentry Ona Agent now supports three new MCP integrations — Atlassian, Notion, and Sentry. Once enabled by an organization admin and authenticated by individual users, agents can interact with these services directly from sessions. * **Atlassian** — Manage Jira issues, search Confluence, and link code changes to tickets. [Configure Atlassian](/docs/ona/configure-atlassian) * **Notion** — Search pages, read documentation, and access project wikis. [Configure Notion](/docs/ona/configure-notion) * **Sentry** — View errors, analyze stack traces, and track regressions. [Configure Sentry](/docs/ona/configure-sentry) You can check the status of all MCP integrations — including connection errors and warnings — using the **MCP Integrations** button in the session input. MCP Integrations panel showing available integrations with status indicators [Learn more about integrations](/docs/ona/integrations/overview) ## Secrets available during Dev Container builds Organization and project secrets may now be used during Dev Container image builds via [secret mounts](https://docs.docker.com/build/building/secrets/#secret-mounts) — without baking them into the final image. Each `RUN` step in your Dockerfile must explicitly request the secrets it needs: ```dockerfile theme={null} FROM node:20 RUN --mount=type=secret,id=/usr/local/secrets/npm-token,target=/tmp/npm-token \ echo "//registry.npmjs.org/:_authToken=$(cat /tmp/npm-token)" > .npmrc && \ npm ci && \ rm -f .npmrc ``` User secrets are not available during builds because built images are cached and shared across the project, so personal credentials could be exposed to other team members. Docker Compose mode is not yet supported. [Learn more about using secrets during builds](/docs/ona/configuration/devcontainer/overview#using-secrets-during-builds) ## Ona now runs on Claude Opus 4.6 We've upgraded Ona to Claude Opus 4.6, Anthropic's latest flagship model. At the same price as Opus 4.5, you'll see significantly better results across a range of tasks, especially for complex problems. Ona Agent confirming it runs on Claude Opus 4.6 by Anthropic **What's new** * **Adaptive thinking** - The model decides when to think deeper, no manual tuning needed. * **More output tokens**: Twice the previous limit, better for large refactors and file generation. * **Improved tool use**: More accurate code edits and fewer mistakes. The upgrade is live now. No action needed on your end. Credits will be consumed at the same rate as before. [**Try now**](https://app.ona.com). ## AWS eu-south-2 region now supported You can now install a Runner in AWS region `eu-south-2` (Spain). When you do, a default environment class is created: **Extra Large (Spot)**. From there, you must configure additional environment classes as custom classes. For `eu-south-2`, we recommend using instance types from the `m7i` (compute) and `g6` (GPU) families. **Getting started:** * [Default Classes](/docs/ona/runners/aws/environment-classes#default-classes) * [Creating Custom Classes](/docs/ona/runners/aws/environment-classes#create-custom-classes) * [Requirements](/docs/ona/runners/aws/environment-classes#supported-instance-types) * [AWS instance types by region](https://docs.aws.amazon.com/ec2/latest/instancetypes/ec2-instance-regions.html#instance-types-eu-south-2) ## Automatic credit top-ups Core plan organizations can now enable automatic credit top-ups. When your credit balance runs low, Ona automatically purchases additional credits using your default payment method. Enable auto top-up and choose a top-up amount at **Settings → Billing**. [Learn more about auto top-up](/docs/ona/billing/overview#automatic-credit-top-up) ## Service account tokens and secrets Service accounts now support tokens and secrets, enabling programmatic API access and secure credential management for automations. **Tokens** — Organization admins can issue long-lived tokens (up to 90 days) on behalf of service accounts. Use these for CI/CD pipelines and external scripts that need to start automations or query the API. Service account token creation dialog **Secrets** — Attach secrets to service accounts. When an environment runs with a service account identity, those secrets are automatically injected. Service account secret creation dialog [Learn more about service accounts](/docs/ona/organizations/service-accounts) ## Share resources with individual users Sharing a project with a colleague no longer requires creating a group or asking an org admin. Resource admins can now share directly with individual users. Share dialog showing user and group selection **What's new:** * **Project creators become admins** — Creating a project automatically makes you its admin. This aligns with how runners and automations already work. * **Share with individual users** — Admins of projects, runners, and automations can now share directly with individual users. No group required. * **Share with existing groups** — Previously, only org admins could share resources with groups. Now any resource admin can share with groups, even if they are just a member of the organization. [Learn more about sharing resources](/docs/ona/organizations/sharing-resources) ## Home Notices Organization admins can now display notices to communicate important information to all organization members on the Ona home page. **What's new:** * **Admin settings page**: Configure notices from Settings → Organization → Announcements * **Markdown support**: Format messages with bold, italic, and links * **Live preview**: See exactly how your notice will appear before publishing * **Toggle control**: Quickly enable or disable the notice without losing your message **Getting started:** 1. Navigate to **Settings → Organization → Announcements** 2. Enable the home notice toggle 3. Enter your message (up to 1,000 characters) 4. Click **Save** to publish Home notice displayed on the Ona home page This feature is available exclusively to Enterprise customers. [Learn more about home notices](/docs/ona/organizations/announcement-banner). ## CLI: Action Required - Force Update A recent CLI release contained a version format issue that breaks automatic updates. If your CLI shows a version like `main-gha.XXXXX` when running `gitpod version`, auto-update will not work. **To fix**, run: ```sh theme={null} gitpod version update --force ``` After updating, `gitpod version` should show a version in the format `YYYYMMDD.HHMM.N` (e.g., `20260120.0512.0`). Read more about the CLI in its [documentation](/docs/ona/integrations/cli). ## JetBrains Warmup for Prebuilds Prebuilds now support JetBrains warmup, significantly reducing editor startup time for JetBrains users. When enabled, prebuilds download and install the JetBrains backend and build project indexes ahead of time. **What's new:** * **Backend pre-installation**: JetBrains backend is downloaded and installed during prebuilds * **Index building**: Project indexes are built during prebuilds using the JetBrains warmup command * **Recommended editors**: Configure which editors to recommend for your project, which also determines which JetBrains editors to warm up **Benefits:** * Skip editor backend download when opening JetBrains editors * Instant code navigation and analysis with prebuilt indexes * Consistent experience across all team members **Getting started:** 1. Enable JetBrains warmup in your project's prebuild configuration 2. Configure [recommended editors](/docs/ona/projects/recommended-editors) to specify which JetBrains editors to warm up 3. Trigger a prebuild to create a warmed-up snapshot [Learn more about JetBrains warmup](/docs/ona/projects/prebuilds#jetbrains-warmup) Prebuild JetBrains warmup logs ## Claude Opus 4.5 for Ona Cloud Ona Cloud users now have access to Claude Opus 4.5 for new agent sessions. This model upgrade brings improved reasoning and code generation to your development workflows. **What's new:** * New agent sessions on Ona Cloud now use Claude Opus 4.5 * Existing sessions continue with their original model **Getting started:** * Start a new session with Ona Agent to use Claude Opus 4.5 * [Learn more about Ona Agents](/docs/ona/agents/overview) ## Agent Skills support Ona Agent now supports [Agent Skills](https://agentskills.io) - an open format for multi-step workflows. Add `SKILL.md` files to `.ona/skills/` and the agent discovers and uses them when relevant. [Learn more about skills](/docs/ona/agents-md#skills-for-repository-specific-workflows) ## TODO grouping in sessions Ona Agent sessions now group TODO items together, making it easier to follow the agent's progress on multi-step tasks. **What's new:** * **Grouped display**: TODOs created together appear in a single collapsible container * **Progress tracking**: See at a glance how many tasks are completed (e.g., "3/5") * **Status indicators**: Each TODO shows its current state—pending, in progress, or done * **Expandable details**: Click any TODO to see the work performed under it * **Live updates**: Watch the agent's progress in real-time as it works through each item TODO grouping ## Security Agents now generally available Security Agents configuration is now available to all organizations in **Settings > Policies**, allowing you to enable CrowdStrike Falcon protection for your workspaces. Security Agents section showing CrowdStrike Falcon toggle in Settings > Policies ## CLI improvements The CLI continues to add new commands and quality-of-life improvements. **New commands:** * `gitpod environment keep-alive` — Prevent automatic shutdown during long-running tasks by watching a process or PID * `gitpod logout` — Sign out of the CLI * `gitpod network-troubleshoot` — Diagnose connectivity issues * `gitpod user dotfiles` — Manage your dotfiles configuration **SSH improvements:** * Running `gitpod env ssh` without specifying an environment now shows an interactive picker * Stopped environments automatically start when you connect via SSH **New flags:** * `--param key=value` for `ai automation start` — Pass parameters to automations * `--phase` for `environment list` — Filter by phase (running, stopped, etc.) * `--name` for `environment create` — Set a custom environment name ## Recommended editors Projects can now configure recommended editors in project settings. Users will see these as recommended options when opening environments, and this also determines which JetBrains IDEs are warmed up during prebuilds. Recommended Editors section in project settings ## Before-snapshot automations Automations now support a `before_snapshot` trigger type. Use this to run cleanup tasks, update dependencies, or perform other operations automatically before an environment snapshot is created. ## Other improvements * Markdown files now show a rendered preview in the diff viewer. * Snapshot progress displays completion percentage during snapshotting. * "Ask Ona" button appears on devcontainer build failures for quick troubleshooting. * New split button for selecting editor versions. * New modal for upgrading AWS EC2 runners. * New account settings modal for managing personal settings. * Prompt input, contexts, and environment class persist across sessions. * VS Code Browser and agents are now exempt from port sharing policy by default. * Audit logs now include login and logout events (Enterprise). * Email invites show pending status and warn before navigating away with unsent invites. * Ona Agent no longer returns 502 errors with Claude Opus 4.5 or Sonnet 4.5 when provider fallback is enabled. * Ona SWE no longer fails when Anthropic environment variables are set in your workspace. * SCP file transfers no longer fail over slow networks. * Hosted compute now allows exposing ports 1024-2999 (previously only 3000+). ## Prebuilds now available on GCP Prebuilds are now supported on GCP Enterprise runners. Teams running Ona on Google Cloud infrastructure can now use prebuilds to reduce environment startup times. **Requirements:** * [Update your Terraform stack](/docs/ona/runners/gcp/update-runner#updating-infrastructure) to the latest version to enable snapshot permissions **Getting started:** * [Learn about prebuilds](/docs/ona/projects/prebuilds) * [Set up prebuilds](/docs/ona/projects/prebuilds-setup) ## Ona now integrates with Linear Ona agents can now connect with Linear to manage your project tasks directly from your development environment. **What you can do:** * **Create and manage issues**: Ask agents to create Linear issues from code, errors, or sessions * **Search and filter**: Find issues by status, assignee, labels, or content * **Update metadata**: Add comments, change status, update labels, and assign issues * **Access project context**: Retrieve project information to inform development decisions **How it works:** 1. **Organization setup**: Admins enable integrations at the organization level 2. **User authentication**: Individual users authenticate to grant agents access to their accounts 3. **Natural interaction**: Simply ask your agent to perform actions—no special commands needed **Example interactions:** * "Create a Linear issue for this bug with steps to reproduce" * "Show me all high-priority issues assigned to me" * "Update issue ABC-123 to mark it as in progress" Organization integration configuration **Get started:** * [Read the integrations documentation](/docs/ona/integrations/overview) * [Learn about Ona Agents](/docs/ona/agents/overview) ## Custom domains for secure management plane access Enterprise customers can now access the Ona management plane through their own custom domain with full TLS termination. This enables organizations to route all traffic through their controlled infrastructure, meeting strict security and compliance requirements. **Why this matters:** * **Security control**: All traffic to the management plane flows through infrastructure you own and manage * **Compliance ready**: Meet organizational requirements for domain ownership and traffic routing * **SSO integration**: Works seamlessly with your existing Single Sign-On configuration * **Enforcement options**: Optionally block access via the default domain, ensuring all users go through your custom domain **Supported cloud providers:** * **AWS**: Uses VPC Endpoints and Network Load Balancer for private connectivity * **GCP**: Uses Private Service Connect (PSC) and regional HTTPS Load Balancer with support for both internal (private) and external (public) load balancer configurations **How it works:** 1. Register your custom domain in the Ona dashboard with your cloud provider details 2. Deploy the required infrastructure in your AWS or GCP account 3. Configure DNS to point your domain to the load balancer 4. Optionally enforce custom domain access for all users **Getting started:** * Review the [Custom domain documentation](/docs/ona/custom-domain) for setup instructions * For GCP deployments, [contact Ona](https://ona.com/contact/sales) to get access to the Terraform module This feature is available exclusively to Enterprise customers. ## Enterprise Runner now available in AWS Paris (`eu-west-3`) region The Ona Enterprise Runner is now available in the AWS Paris (`eu-west-3`) region, expanding deployment options for teams requiring data residency in Western Europe. **Why this matters:** * **Regional compliance**: Meet data residency requirements for France and the EU * **Lower latency**: Improved performance for teams based in Western Europe * **Enterprise ready**: Full Enterprise Runner capabilities including AI agent integration and direct connectivity * **Flexible deployment**: Deploy in your VPC with custom networking configurations **Getting started:** * [Contact sales](https://ona.com/contact/sales) to enable Enterprise Runner * Follow the [AWS Enterprise Runner setup](/docs/ona/runners/aws/enterprise-runner/setup) guide * Configure your runner to use the eu-west-3 region This expansion is available exclusively to Enterprise customers. ## Extended Single Sign-On (SSO) support SSO configuration panel showing multiple identity provider options We've significantly expanded our SSO capabilities to support more complex organizational structures and authentication requirements. **What's new:** * **Multiple email domains per login provider**: Configure several email domains for a single identity provider, ideal for organizations with multiple subsidiaries or acquired companies * **Multiple identity providers per organization**: Set up more than one identity provider (e.g., both Okta and Azure AD) to accommodate different teams or authentication requirements * **Cross-organization domain support**: Use the same email domain across different organizations—users are presented with a list of login options to select their organization **Why this matters:** * **Enterprise flexibility**: Large organizations with complex structures can now centralize authentication across all their domains * **M\&A ready**: Easily onboard acquired companies without forcing immediate identity provider migrations * **Multi-team support**: Accommodate different authentication requirements for employees, contractors, and partners within the same organization **Getting started:** * Navigate to [Settings → Organization → SSO](https://app.ona.com/settings/sso) * Add additional email domains to existing login providers or configure new identity providers * Learn more in our [SSO documentation](/docs/ona/sso/overview) This feature is available exclusively to Enterprise customers. ## Run prebuilds as service accounts Prebuilds can now run as [service accounts](/docs/ona/organizations/service-accounts), decoupling prebuild execution from individual user accounts. This ensures prebuilds continue working regardless of user availability or permission changes. **What's new:** * Configure the prebuild executor in project settings * Choose between a user (default) or a service account **Why this matters:** * Prebuilds no longer break when team members leave or change roles * Dedicated credentials for prebuild execution **Getting started:** * [Learn about prebuild executors](/docs/ona/projects/prebuilds#prebuild-executor) * [Configure the executor](/docs/ona/projects/prebuilds-setup#4-configure-the-executor) * [Set up service accounts](/docs/ona/organizations/service-accounts) This feature is available exclusively to Enterprise customers. ## Automation logs in prebuilds Prebuild logs now include output from automation tasks, making it easier to debug prebuild failures and understand what ran during prebuild execution. See [Viewing Logs](/docs/ona/projects/prebuilds-management#viewing-logs) for details. ## Editor version restrictions for organization policies Organization administrators can now restrict which versions of editors their team can use, in addition to controlling which editors are available. This provides greater control over development environment consistency and security. **Why this matters:** * **Stability**: Standardize on tested versions before adopting the newest releases * **Security**: Control version updates to verify security patches before organization-wide deployment * **Compatibility**: Ensure all team members use versions tested with your workflows and integrations **How it works:** * Configure version restrictions in the same "Manage Editors" dialog as editor restrictions * Currently available for JetBrains IDEs (IntelliJ IDEA, PyCharm, GoLand, etc.) * Users attempting to use non-allowed versions automatically fall back to the latest allowed version **Getting started:** * Navigate to [Settings → Organization → Policies](https://app.ona.com/settings/policies) * Click "Manage Editors" and select the specific versions you want to allow * Learn more in our [Organization Policies documentation](/docs/ona/organizations/policies#editor-restrictions) ## Prebuilds: Faster environment startup times Prebuilds reduce environment startup times by pre-executing your Dev Container build, lifecycle commands, and automation tasks. When you create an environment from a project with prebuilds enabled, it starts from a snapshot instead of running the full setup process. **How it works:** * Configure prebuilds at the project level with a daily schedule * Prebuilds run your Dev Container build, `onCreateCommand`, `updateContentCommand`, and automation tasks with the `prebuild` trigger * A snapshot is created and used for all new environments from that project * Prebuilds are automatically deleted after 7 days **Availability:** * AWS Enterprise runners * GCP Enterprise runners * Ona Cloud **Pricing:** * **Ona Cloud**: Environment usage is billed normally during prebuild creation. Snapshot storage is currently free (pricing may be introduced in the future). * **Enterprise**: You pay for compute resources during prebuild creation and storage costs for the snapshot. Storage is billed only for actual data stored (e.g., 50GB used on a 100GB volume = 50GB billed). **Getting started:** * [Learn about prebuilds](/docs/ona/projects/prebuilds) * [Set up prebuilds](/docs/ona/projects/prebuilds-setup) * [Manage prebuilds](/docs/ona/projects/prebuilds-management) ## Ona Agents now available on GCP Runner Ona Agents are now fully supported on GCP Runner, bringing AI-powered development assistance to your Google Cloud infrastructure. Teams using GCP Runner can now leverage Ona Agents to accelerate development with up to 4x productivity gains—all while keeping code and data secure within your VPC. **Why this matters:** * **AI-powered development in your VPC**: Use Ona Agents with the same security and compliance benefits of GCP Runner * **Flexible LLM options**: Configure Google Vertex AI or other supported LLM providers to power your agents * **Enterprise-grade control**: Maintain full control over your AI infrastructure with your own LLM provider * **Native integration**: Agents work with your GCP Runner environments **Getting started:** * [Contact sales](https://ona.com/contact/sales) or reach out to your account executive to enable GCP Runner with Ona Agents * Review the [GCP Runner overview](/docs/ona/runners/gcp/overview) and [setup guide](/docs/ona/runners/gcp/setup) * Learn about [Ona Agents](/docs/ona/agents/overview) and supported capabilities * Configure your [LLM provider](/docs/ona/agents/llm-providers/overview) (Google Vertex AI recommended for GCP) This feature is available exclusively to Enterprise customers. ## Organize teams and control access with Groups Ona now supports Groups, giving you fine-grained control over who can access projects and runners in your organization. Organize teams by function or infrastructure needs, add members, and share resources with them. Dropdown menu showing group sharing options including specific groups selection **Why this matters:** * **Keep workspaces focused**: Developers see projects relevant to their work, not everything * **Share smarter**: Give the right access without making everyone an admin * **Support compliance**: Route EU developers to EU runners, ML engineers to GPU infrastructure **How it works:** * Create groups in **Settings → Members → Groups** * Share projects and runners with specific groups using the Share dialog * Assign role-based permissions: User (view/use), Editor (manage), or Admin (full control) * Built-in warnings prevent access issues when projects and runners aren't aligned Learn more in our [Groups documentation](/docs/ona/organizations/groups) and [Resource Sharing guide](/docs/ona/organizations/sharing-resources). ## Enterprise Runner now available in AWS Mumbai (`ap-south-1`) region The Ona Enterprise Runner is now available in the AWS Mumbai (`ap-south-1`) region, expanding deployment options for teams requiring data residency in South Asia. **Why this matters:** * **Regional compliance**: Meet data residency requirements for India and South Asia * **Lower latency**: Improved performance for teams based in the region * **Enterprise ready**: Full Enterprise Runner capabilities including AI agent integration and direct connectivity * **Flexible deployment**: Deploy in your VPC with custom networking configurations **Getting started:** * [Contact sales](https://ona.com/contact/sales) to enable Enterprise Runner * Follow the [AWS Enterprise Runner setup](/docs/ona/runners/aws/enterprise-runner/setup) guide * Configure your runner to use the ap-south-1 region This expansion is available exclusively to Enterprise customers. ## Ona is now Available in Google Cloud. We’re expanding where great software gets built. From today, Ona can also run natively in Google Cloud, in your VPC. GCP Runner configuration interface in the Ona dashboard If your company bet on GCP for scale, security, and data residency, you can now bring Ona right to your VPC. Your code stays in your infrastructure. Your controls stay yours. The developer experience gets dramatically better. **Why this matters:** * **Get started in minutes**: a Terraform apply stands up everything you need. * Keep traffic where you want it: external or internal HTTPS load balancing. * **Use your standards**: CMEK, proxy, custom images, labels, enterprise IAM. * **Ship faster**: native access to private GAR images, observability out of the box. * **Agent Ready**: Google Cloud is Ona Agents ready. Learn how to use [Ona Agents](/docs/ona/agents/overview) and join our customers in getting up to 4x more productivity. Google Cloud is available exclusively to Enterprise customers. **Get started:** * [Contact sales](https://ona.com/contact/sales) to enable Enterprise * Follow the [GCP Runner setup](/docs/ona/runners/gcp/setup) and read the [Overview](/docs/ona/runners/gcp/overview) ## View and Review Code changes directly from mobile Mobile interface showing code changes with file diff viewer You can now view all code changes made in an environment on mobile in a dedicated "Code changes" page. * The "Changes" tab shows you a list of changed files in the environment. You can expand each file to view the diff of the file. * The "Files" tab gives you a tree view of all the changed files, which you can use to navigate to the diff of the file you want. To open the page, go to the "Git status" panel in "Environment details" page, click on any changed file, and you will be taken to the corresponding file diff. ## Visualize architecture and workflows with Mermaid diagrams Ona Agent can now generate and render Mermaid diagrams directly in sessions, making it easy to visualize system architecture, dependencies, workflows, and data relationships without leaving your development environment. **How to use:** Simply ask Ona Agent to create diagrams using natural language: * Draw an architecture diagram showing how our microservices communicate * Create a sequence diagram for the authentication flow * Generate an ER diagram for our database schema Ona Agent will generate the appropriate Mermaid diagram, which you can preview, zoom, and copy directly in the session. The agent handles all the Mermaid syntax, so you can focus on describing what you want to visualize. **Supported diagram types:** * Flowcharts and decision trees * Sequence diagrams * Class diagrams * Entity-relationship diagrams * State diagrams * Gantt charts * Git graphs Learn more in our [Mermaid diagrams documentation](/docs/ona/agents/mermaid-diagrams). ## Claude Sonnet 4.5 now available Claude Sonnet 4.5 is now available in Ona, bringing enhanced reasoning capabilities and improved code generation to your development workflow. **How to enable Sonnet 4.5:** * **Free and Core tiers**: Sonnet 4.5 is automatically available, no setup or changes are required * **Enterprise tier**: Organization admins can [configure your LLM provider](/docs/ona/agents/llm-providers/overview) by selecting Sonnet 4.5 in the settings for each runner. Ensure you are on [the latest runner version runner](https://ona.com/docs/ona/runners/aws/update-runner) to update. Removing a previous LLM integration on a runner will break existing sessions. **Learn more:** * [LLM Providers Overview](/docs/ona/agents/llm-providers/overview) * [Anthropic Configuration](/docs/ona/agents/llm-providers/anthropic) * [AWS Bedrock Configuration](/docs/ona/agents/llm-providers/bedrock) * [Google Vertex AI Configuration](/docs/ona/agents/llm-providers/google-vertex) * [Updating AWS Runner](https://ona.com/docs/ona/runners/aws/update-runner) ## Encode your expertise into slash commands Ona interface showing slash command autocomplete menu with options like /pr and /review Encode your team's best practices into reusable slash commands that work across your entire organization in Ona. Useful for automating standards such as PR or commits patterns and for turning complex workflows into simple and consistent actions. * Ensure everyone follows the same PR format or review process * Capture your best reviewer's approach in commands like `/review-like-sarah` * Automate common tasks like `/pr`, `/fix-ci-build`, or `/weekly-digest` Every command runs in a fully-configured Ona environment with all of your dependencies, authentication, and secrets set up. So `/test` can run against real databases and integrations and `/fix-ci-build` has everything it needs to succeed. All environments are isolated so there's never the risk of breaking your laptop or your flow. For more, see the [skills docs](/docs/ona/skills) and our [best practices guide](/docs/ona/best-practices). ## Track agent progress with todos Ona agent todo list showing task progress with checkboxes As agents become more autonomous and handle longer workflows, you need a way to monitor progress without watching every detail. That's why before starting to work Ona Agents create and manage their own todo lists. * See the plan at a glance instead of reading through detailed agent output * Quickly spot when an agent might need steering without monitoring every action * Add, remove, or modify todos mid-task to adjust your agent's approach With todos you can check in to see the big picture, and intervene only when needed. With each agent maintaining its own todo list, you can start to orchestrate your own fleet of agents without losing track of who's doing what. See our [best practices guide](/docs/ona/best-practices) for more. ## Ona now supports AGENTS.md AGENTS.md file open in Ona environment showing project conventions Ona now supports AGENTS.md, the emerging open standard for guiding AI coding agents used by thousands of open-source projects and supported by tools like OpenAI and Google. AGENTS.md provides a consistent way to communicate project conventions to your coding agent. Add to the file any project-specific commands, coding standards, and architecture guidance that will help your agent write code that fits your team's patterns. If you already use AGENTS.md with another agentic tool, Ona automatically loads it into every environment. See the [agents.md documentation](/docs/ona/agents-md) for more. ## Keep momentum on any device from mobile to iPad Ona mobile interface showing agent session on smartphone Capture ideas the moment inspiration strikes. Whether you're waiting for coffee or commuting home, Ona gives you the full power of development environments from any device without any tunnels or complex setups. So ideas can become reality, wherever you are. ## Privacy-first coding agent inference with Bedrock and Vertex LLM provider configuration showing Bedrock, Vertex AI, and Anthropic options Ona Enterprise supports LLM inference via Amazon Bedrock, Google Vertex and Anthropic giving you secure control over your AI inference from within your private VPC. Your code, prompts, and AI interactions never leave your network. Meet strict regulatory needs with inference that runs entirely within your security perimeter. Combined with Ona's existing VPC deployment this creates an end-to-end secure development environment platform. This feature is available today for all Ona Enterprise customers. Learn more about [Ona Enterprise](https://ona.com/enterprise). ## Sandboxed AI software development with Dev Container Dev Container configuration with devcontainer.json editor Unlike AI coding tools that run on shared infrastructure or on developer machines, Ona provides true sandboxing for writing software with agents. Agents can't access each other's work or leak secrets between projects. Ona Agents execute within isolated environments defined by Dev Container. * **Complete agent isolation**: Each agent runs in its own Dev Container with OS level isolation, preventing cross-contamination between source control and projects. * **Ephemeral by design**: Environments are created newly for each task (e.g. issue, bug, feature) and destroyed on completion, ensuring no persistent attack surface. * **Standardized environments**: Dev Containers are defined in code and pre-configured with your exact dependencies and access credentials. If you're already using the Dev Container specification, Ona will automatically use your existing devcontainer.json. For new projects, Ona can help generate appropriate Dev Container configurations based on your codebase. Available for all Ona pricing tiers. Learn more about [Ona Dev Container support](/docs/ona/configuration/devcontainer/overview). ## Standardized JetBrains plugin management via devcontainer.json You can now configure JetBrains IDE plugins directly in your devcontainer.json file, enabling fully standardized plugin management across development environments. This update lets teams pre-install essential plugins from the JetBrains Marketplace using their plugin IDs, ensuring consistent tooling for all team members. It eliminates the need for manual plugin installation, reducing setup time and improving onboarding speed. **Key capabilities:** * **Plugin installation**: Specify plugin IDs from the JetBrains Marketplace for automatic installation. * **Team consistency**: Guarantee the same set of plugins across every developer environment. * **Faster onboarding**: Remove the manual step of plugin setup for new contributors. **Example configuration:** ```json title="devcontainer.json" theme={null} { "name": "My Project", "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "customizations": { "jetbrains": { "plugins": ["org.intellij.plugins.hcl", "com.intellij.kubernetes"] } } } ``` This enhancement removes the previous limitation of non-customizable JetBrains plugin setups, bringing a consistent, repeatable configuration to the entire Dev Container ecosystem. See the [JetBrains documentation](/docs/ona/editors/jetbrains) to learn more. ## HTTPS support for environment services via port sharing You can now expose environment services over HTTPS using Gitpod's port sharing feature. This enables secure communication with applications running in your environment, which is ideal for testing HTTPS-only setups or integrating with services requiring encrypted transport. **What's new:** * **UI integration**: Select https as the protocol in the port sharing dialog * **CLI support**: Use `--protocol https` with `gitpod environment port open` to expose environment service ports securely. **Use cases:** * Applications with HTTPS-only redirects or policies * Streaming APIs requiring secure connections See [port sharing documentation](/docs/ona/integrations/ports) for setup instructions. ## Support for multiple region-aware environment classes per project We're excited to announce that Gitpod now supports Multiple environment classes for a project, a highly requested feature that enhances reliability and flexibility for organizations. With this new feature, you can: * Configure up to 30 environment classes per project, providing built-in regional redundancy * Set a default environment class while offering alternatives for user selection * Avoid creating multiple projects for the same repository across different regions * Benefit from automatic fallback options when a preferred environment class is unavailable **Highlights:** * **Enhanced Resilience**: Eliminate single points of failure with multiple region support in a single project * **User Flexibility**: Users can select their preferred environment class through an intuitive UI * **Intelligent Fallback**: When a selected environment class is unavailable, users receive informative error messages and alternative options * **Preference Persistence**: The system remembers user preferences for future project launches * **Simplified Project Management**: Reduce project proliferation by consolidating multi-region support Learn how to configure multiple environment classes for a project in our [documentation](/docs/ona/projects/overview). ## Archive & Auto-delete for Environments We're excited to announce Archive & Auto-delete, a new feature that automatically manages your environment lifecycle to help reduce storage costs. With this new feature, you can: * Automatically archive inactive environments after 7 days of inactivity * Configure auto-deletion policies to remove archived environments after 1, 2, or 4 weeks * Set organization-wide retention limits to ensure consistent storage management **Highlights:** * **Two-stage lifecycle**: Environments are archived first (reversible), then auto-deleted based on your preferences * **Flexible policies**: Users can set preferences within organization-defined limits * **Bulk management**: Delete all archived environments at once with safety controls * **Visual indicators**: Archive badge shows when you have archived environments This feature helps reduce storage costs while maintaining control over environment retention. Organization-wide auto-delete policies are available for Enterprise customers. Learn how to configure Archive & Auto-delete in our [documentation](/docs/ona/environments/archive-auto-delete). ## Organization Secrets support We're excited to announce that Gitpod now supports Organization secrets, alongside existing User and Project secrets. With this new feature, you can: * Configure organization-wide secrets for all Environments in the organization * Ensure consistent access to shared credentials and API keys for all team members **Highlights:** * **Files**: Secrets can be mounted as files for complex structures e.g. JSON. * **Environment Variables**: Inject secrets as environment variables. **What's the benefit of files?** Files offer better security by avoiding issues like process visibility, crash logging leaks, and unintentional inheritance by child processes. Learn how to configure organization secrets in our [documentation](/docs/ona/organizations/organization-secrets). ## VPC endpoint support for Enterprise AWS runners Enterprise AWS runners now support VPC endpoints, allowing you to connect to Gitpod's management plane using AWS PrivateLink. This enhancement provides: * **Increased security** - All traffic between your runner and Gitpod stays within AWS's network backbone * **More reliable connectivity** - Eliminates dependency on internet routing and potential connectivity issues * **Compliance ready** - Ideal for customers with strict security requirements that prohibit internet-bound traffic **How it works:** With VPC endpoints enabled, your Enterprise AWS runner connects to Gitpod's management plane through AWS PrivateLink: * **DNS resolution** - app.gitpod.io automatically resolves to VPC endpoint IP addresses within your VPC * **AWS PrivateLink** - Traffic flows through Amazon's network infrastructure via VPC endpoints * **No runner changes** - No changes required to your existing runner configuration **Getting started:** To enable VPC endpoints for your Enterprise AWS runner: 1. Create an Interface VPC Endpoint in your AWS account pointing to Gitpod's service 2. Configure the endpoint in the same VPC where your runner is deployed 3. Enable DNS names for automatic resolution The runner dashboard will automatically detect and display "via VPC endpoint" as the connection type once configured. Learn more about setting up VPC endpoints in our [Enterprise runner setup documentation](/docs/ona/runners/aws/enterprise-runner/setup). **Availability:** This feature is available to Enterprise customers using AWS runners. ## Enterprise AWS runner with AI agent and direct connectivity Enterprise AWS Runners are now available for Enterprise customers, providing additional capabilities beyond our AWS Runners. **Key features:** * **Ona AI Agent Integration**: AI-powered assistance for automatic Dev Container generation and environment setup * **Direct Connectivity**: Bypass Gitpod's central gateway using your own Network Load Balancer with custom domain and SSL/TLS certificate * **Advanced Networking**: Custom VPC configurations with flexible subnet architecture for internal-only or internet-facing deployments * **Flexible Deployment**: Deploy behind corporate firewalls with future HTTP proxy support **Availability:** Enterprise AWS Runners are exclusively available to Enterprise customers. If you're on the Enterprise tier, contact your Gitpod account manager to get started. **Coming soon:** We're continuing to enhance the Enterprise Runner with additional enterprise-focused features: * **HTTP Proxy Support**: Custom HTTP proxy configuration for environments behind corporate firewalls * **Custom CA Certificate Support**: Integration with enterprise certificate authorities and custom certificate chains Learn more about setting up your Enterprise AWS Runner in our [documentation](/docs/ona/runners/aws/enterprise-runner/overview). ## Introducing our AI powered Development Environment setup workflow Ona's Enterprise SWE agent, Ona agent, now automatically analyzes repositories and generates Dev Container and automations configurations, helping you discover the value of Gitpod much faster. When developers open an environment without existing Dev Container configurations, Gitpod offers to run our AI powered workflow to generate the configuration automatically. Ona works relentlessly, rebuilding and testing the generated configuration until it is confident it gives you a productive setup. AI agent generating Dev Container configuration for a repository **How it works:** 1. Open an environment in Gitpod without an existing Dev Container configuration 2. Gitpod offers to run our Ona powered setup agent automatically 3. Ona generates devcontainer.json and automations.yaml based on detected dependencies and best practices 4. Review and commit configurations for your team 5. All subsequent environment launches use the optimized configuration **Availability:** This feature is available to our enterprise customers. [Contact sales](https://ona.com/contact/get-demo). ## Gitpod now supports Windsurf editor Gitpod now supports Windsurf as an editor option for your development environments. Windsurf integrates advanced AI capabilities directly into your development workflow, enhancing productivity through natural language interaction and intelligent code assistance. Experience features like Tab-to-Import, real-time linting, and Cascade AI assistant to streamline your coding process. **Using Windsurf with Gitpod:** Windsurf editor selector dropdown in the Ona interface To get started with Windsurf in Gitpod, simply select Windsurf from the editor selector dropdown by clicking on the dropdown arrow next to the editor button on the action bar. Check our [documentation](/docs/ona/editors/windsurf) for more details on how to use Windsurf with Gitpod. ## Faster development environment start times for AWS with Dev Container build caching Development environment starts are now faster for organizations using AWS Runners with the addition of a new Dev Container build cache Runner setting that uses Amazon ECR. With this setting enabled you get: * Faster startup times from minutes to seconds for environments with identical Dev Container configurations * Reclaimed developer time: Convert 5 minute development environment startup delays into 30-second starts * Automatically optimized start times performance without any configuration changes required **How does it work?** With the setting enabled on your AWS runner, the first environment created from a project will cache the built Dev Container image. Any changes to the Dev Container configuration will trigger a new cache build on the next environment creation. * All subsequent starts using the same project will benefit from significantly faster startup times. * Images are cached for 30 days before automatically expiring to manage storage costs. * The cache is restricted to users of the project and can be disabled in runner settings if needed. The build cache speeds up developers workflows and incentivizes developers to use secure short-lived development environments. **Getting started:** For new AWS runners: The Dev Container image cache is enabled by default. For existing AWS runners: 1. Update your CloudFormation stack to the latest version that supports the cache 2. Go to Settings → Runners in your Gitpod organization 3. Select your AWS runner and toggle Dev Container image cache to enabled **Note:** Upgrading CloudFormation templates from January 2025 or earlier will cause existing environments to become inaccessible due to SSH port changes. Before upgrading, either stop existing environments or manually update the security group after the upgrade. Learn more about configuration, security considerations, and troubleshooting in our [Dev Container image cache documentation](/docs/ona/runners/devcontainer-image-cache). ## Analyze your organization's Gitpod usage with Insights Insights dashboard showing environment usage metrics and charts We're excited to announce the launch of Gitpod Insights, an analytics dashboard that helps Enterprise organizations understand and optimize their Gitpod usage and cloud cost. With Gitpod Insights, you can: * **Analyze environment usage** across your entire organization * **Optimize cloud costs** by identifying opportunities to right-size resources * **Monitor adoption** by tracking active users and environment metrics The Insights dashboard provides key metrics, including: * **Active Users**: Track weekly active users and engagement patterns * **Environment Usage**: Monitor total environments and runtime hours * **Resource Distribution**: View usage by projects, users, and environment classes Organization administrators can access Insights directly from the Gitpod dashboard by selecting "Insights" from the left navigation menu. The dashboard offers flexible time range options from daily to yearly views, with automatically adjusted data granularity for optimal analysis. Learn more about Gitpod Insights in our [documentation](/docs/ona/organizations/insights). ## Create development environments from scratch without a Git repository You can now create development environments from scratch directly from the environment creation modal. This new option allows you to: * Start with a clean slate using your organization's default environment image * Start an environment without requiring a git provider configured on a runner * Begin development immediately without needing to clone an existing repository To create a blank environment: 1. Click the `Create Environment` button 2. Select `Create Environment From Scratch` 3. Choose your preferred environment class 4. Click `Create` to start your new environment See [default environment image documentation](/docs/ona/organizations/policies/default-image) for details. ## Organization policies to manage cost, security and developer experience Organization policies are now available on our Enterprise plan for organizations, giving administrators centralized controls to manage security, developer experience, and resource costs. With Organization policies, you can: * **Enhance security** - Restrict development environments to only run in the cloud (e.g. not locally) and control which editors developers can use to access your code * **Standardize experience** - Create a consistent "golden path" by defining allowed editors and default container images * **Control costs** - Set auto-stop timeout limits and maximum environment counts to prevent unexpected resource usage * **Enforce governance** - Require environments to be created only from approved projects * **Manage resources** - Limit concurrent running environments per user for optimized resource allocation Discover how to configure Organization Policies in our [documentation](/docs/ona/organizations/policies). ## Gitpod now supports VS Code in the Browser Gitpod now supports VS Code in the browser as well as regular desktop IDEs and editors. Giving developers access to secure development environments without installing any local tools, cloning any source code or managing any dependencies. Development environments that are fully automated and standardized. With Gitpod and VS Code in the Browser, you can: * Drive down your developer onboarding times by eliminating all manual setup for your development teams. * Help developers review code easily by launching new development environments running in their browser tab. * Drive down incident response times with SREs able to do on-the-go incident response direct from their mobiles. * For secure enterprises, Gitpod [paired with a secure browser (like Island)](https://www.gitpod.io/blog/replace-vdi-with-gitpod-and-island) is a secure and performant alternative to traditional [VDI](https://www.gitpod.io/solutions/vdi). ### Getting started To get started, simply click the "Open in VS Code in the Browser" button when starting a Gitpod environment. Check our [documentation](/docs/ona/editors/vscode-browser) for more details on features and capabilities. ## Gitpod now supports JetBrains Toolbox App The JetBrains Toolbox App, a desktop application that helps you manage JetBrains IDEs and projects, now supports remote development in Gitpod environments. This means you can: * Use the familiar Toolbox App interface to manage your IDEs in Gitpod * Connect to Gitpod environments from your desktop * Install and update JetBrains IDEs in your remote environment To get started, install the latest JetBrains Toolbox App (2.6+) and connect it to your Gitpod environments. Check our [documentation](/docs/ona/editors/jetbrains) for setup instructions. Learn more about the JetBrains Toolbox App 2.6 release in the [official announcement](https://blog.jetbrains.com/toolbox-app/2025/04/toolbox-app-2-6-is-here-with-remote-development-support). ## User Secrets support We're excited to announce that Gitpod now supports User secrets, alongside existing Project secrets. With this new feature, you can: * **Configure personal secrets** for all of your Environments * **Integrate against 3rd party systems which use Personal Access Tokens** to authenticate seamlessly, and even use [atuin](https://atuin.sh/) to have persistent terminal history in your Environments. Highlights: * **Files**: Secrets can be mounted as files for complex structures e.g. JSON. * **Environment Variables**: Inject secrets as environment variables. **What's the benefit of files?** Files offer better security by avoiding issues like process visibility, crash logging leaks, and unintentional inheritance by child processes. Learn how to configure your personal secrets in [our documentation](/docs/ona/configuration/secrets/user-secrets). ## AWS ECR private registry support We're excited to announce that Gitpod now supports AWS ECR private registries with IAM-based authentication when using AWS EC2 runners. With this new feature, you can: * **Securely access private ECR repositories** without manually managing credentials * **Simplify authentication workflows** using EC2 runner's IAM role * **Seamlessly work with private container images** in your development environment This native integration works automatically when: * You're using AWS EC2 runners for your environments * Your ECR registry and EC2 runners are in the same AWS account (or have appropriate cross-account access) Setting up ECR registry access is straightforward through the Project Secrets interface. Simply select Container Registry Basic Auth, enter your ECR registry hostname, and the system will automatically configure runner-native authentication. Learn how to configure IAM permissions and set up your ECR registry in our [documentation](/docs/ona/configuration/secrets/container-registry-secret#using-aws-ecr-with-iam-authentication). ## Domain Verification for SSO Domain Verification is now available, allowing organization admins to verify ownership of their email domains through DNS TXT records. This feature strengthens security by confirming domain ownership before enabling SSO functionality. This ensures that only authorized users can access your organization using the specified domain. Learn how to verify your domain from our [documentation](/docs/ona/sso/overview#step-1-verify-your-domain). ## Private container registry support We're excited to announce that Gitpod now supports Container Registry Secrets, allowing you to securely authenticate with private container registries. With Container Registry Secrets, you can now: * Pull Dev Container images from private registries * Authenticate with container registries during your development workflow * Work with private images in your Flex environment without exposing credentials This feature supports all major container registries using basic authentication, including: * Docker Hub * GitHub Container Registry * GitLab Container Registry * Azure Container Registry Setting up Container Registry Secrets is straightforward through the Project Secrets interface. You'll need to provide the registry hostname, username, and password/token to create the authentication secret. Learn how to set up and use Container Registry Secrets in our [documentation](/docs/ona/configuration/secrets/container-registry-secret). **Note:** This initial release supports basic authentication only. Support for AWS ECR and other authentication methods will be coming in future updates. ## Dotfiles Support for Gitpod Gitpod now supports dotfiles. Dotfiles are a way to customize your developer environment according to your personal needs. Just configure what dotfiles repository to use and Gitpod will clone and install the dotfiles in every environment, ensuring everything is just the way you like it. Head over to the [documentation](/docs/ona/configuration/dotfiles/overview) to learn how to get started. ## Introducing Gitpod SSO We're excited to announce that Gitpod now supports Single Sign-On (SSO), making it easier than ever to manage access for your team. With SSO, your team can log in using their existing accounts with trusted Identity Providers like Okta, Azure AD, or Google using OpenID Connect (OIDC) integration. This feature simplifies authentication by eliminating the need for separate credentials, enhances security by centralizing user management, and streamlines access across your organization. As an admin, you can easily set up SSO in your organization's settings using your IdP credentials and manage access with just a few clicks. Learn how to set up SSO in our [documentation](/docs/ona/sso/overview). ## Introducing Gitpod secrets & environment variables Gitpod now supports secrets and environment variables. Securely store and inject sensitive data such as API keys and access credentials into your development environment. Secrets are encrypted using AES256-GCM and stored securely. Only environments launched from an associated project can access it's secrets. Highlights: * **Environment Variables**: Inject secrets as environment variables. * **Files**: Secrets can be mounted as files for complex structures e.g. JSON. **What's the benefit of files?** Files offer better security by avoiding issues like process visibility, crash logging leaks, and unintentional inheritance by child processes. See [secrets docs](/docs/ona/configuration/secrets/overview) for more. ## Migrate from .gitpod.yml to devcontainer.json We recently announced that Ona now supports Dev Container. To help ease your migration you can run the following command directly from a Ona environment: ```sh theme={null} gitpod env migrate ``` # Add your first secret Source: https://ona.com/docs/ona/add-first-secret Store API keys and credentials so agents can connect to external services. Agents need credentials to connect to external services - Linear for issue tracking, AWS for cloud resources, API keys for MCP servers. Secrets store these credentials securely and inject them into your environments automatically. ## What you'll do Add a secret that your environments and agents can use. We'll use a Linear API key as an example, but the process is the same for any credential. ## Choose a scope Secrets can be configured at three levels: | Scope | Best for | | ---------------- | ------------------------------------------------------------------------------- | | **User** | Personal API keys (Linear, GitHub tokens). Only available in your environments. | | **Project** | Shared credentials for a specific repository. Available to all project members. | | **Organization** | Company-wide credentials. Available across all projects. | For personal API keys like Linear, use **User secrets**. ## Add a user secret 1. Go to **Settings** > **My Account** > **Secrets** User secrets settings page showing list of personal secrets 2. Click **New Secret** 3. Configure: * **Secret type**: Environment variable * **Name**: `LINEAR_API_KEY` * **Secret**: Your Linear API key (from Linear Settings > API) New secret dialog with Environment Variable type selected showing name and value fields 4. Click **Add** The secret is now available as an environment variable in all your environments. **Security tradeoff**: Environment variables can leak through process listings and logs. [File secrets](/docs/ona/configuration/secrets/files) are more secure, but many tools (including MCP servers) expect credentials as environment variables. For API keys that can be rotated, this tradeoff is often acceptable. For passwords and private keys, prefer file secrets. ## Import from a .env file If you already have a `.env` file, you can import all its variables as secrets at once. 1. Go to **Settings** > **My Account** > **Secrets** 2. Click **Import .env** 3. Drag and drop your `.env` file, or click **browse** to select it 4. Review the parsed variables. Duplicates of existing secrets are flagged and skipped 5. Click **Import** The file must use standard `KEY=VALUE` format, one variable per line. Comments and blank lines are ignored. This works the same way on **Project** and **Organization** secret pages ([Enterprise plan](/docs/ona/organizations/organization-secrets) required for organization secrets). ## Verify it works Start an environment and check the secret is injected: ```bash theme={null} echo $LINEAR_API_KEY ``` You should see your key (or a masked version). Agents can now use this secret to connect to Linear. ## Common secrets for agents | Secret | What it enables | | ------------------- | -------------------------------------------- | | `LINEAR_API_KEY` | Issue creation and management via Linear MCP | | `GITHUB_TOKEN` | Enhanced GitHub access via GitHub MCP | | `AWS_*` credentials | Cloud resource access | To use your ChatGPT plan with Codex, connect [Codex](/docs/ona/integrations/configure-codex) in **User Settings > Integrations** instead of adding an API key as a secret. ## Secret precedence If the same secret name exists at multiple levels, user secrets override project secrets, which override organization secrets. This lets you use personal credentials while teams share defaults. ## Next steps * [Configure Linear](/docs/ona/integrations/configure-linear) to use your API key * [Learn about MCP servers](/docs/ona/mcp) that use secrets * [Secrets reference](/docs/ona/configuration/secrets/overview) for all secret types # Teach agents your codebase Source: https://ona.com/docs/ona/agents-md Help agents understand your project conventions, commands, and architecture with AGENTS.md. Every codebase has conventions — how you name branches, which commands run tests, where important files live. Without context, agents guess: they run `npm test` when your project uses `yarn test`, or put a component in the wrong directory. AGENTS.md teaches them your conventions, commands, and architecture so they produce code that fits your project. [AGENTS.md](https://agents.md) is an open standard stewarded by the Linux Foundation, supported by Ona and other AI coding tools. Think of it as a README for agents — the tribal knowledge that senior engineers carry in their heads. ## Create your AGENTS.md Create an `AGENTS.md` file in your repository root: ```markdown theme={null} # Project Guidelines ## Commands - `npm test` - Run tests - `npm run build` - Build for production - `npm run lint` - Check code style ## Project Structure - `src/components/` - React components - `src/utils/` - Helper functions - `src/api/` - API client and types ## Code Style - Use TypeScript for all new files - Components use PascalCase (e.g., `UserProfile.tsx`) - Utilities use camelCase (e.g., `formatDate.ts`) ``` Agents automatically load this file at the start of every session. ## Keep it concise Shorter is better. As instruction count increases, instruction-following quality decreases. Aim for: * **Under 300 lines** - the recommended maximum * **Under 60 lines** - ideal for most projects If you need more detail, link to other files rather than duplicating content: ```markdown theme={null} ## Code Style Follow the guidelines in [CONTRIBUTING.md](./CONTRIBUTING.md) ``` ## What to include **Commands** - The most important section. Tell agents exactly how to: * Run tests * Build the project * Start the dev server * Lint and format code **Project structure** - Where things live: * Key directories and their purpose * Where to add new components or features **Conventions** - How your team does things: * Branch naming patterns * Commit message format * Code style rules **Security considerations** - What to avoid: * Files that should never be committed * Sensitive patterns to watch for * Security-related commands to run ## Make critical rules stand out Agents pay attention to emphasis. For rules that must not be broken: ```markdown theme={null} **IMPORTANT**: Always run `npm run typecheck` before committing. **ALWAYS** use the `useApi` hook for data fetching, never raw fetch calls. **NEVER** commit .env files or API keys. ``` ## Use nested files for large projects For monorepos or large codebases, you can place AGENTS.md files in subdirectories. Agents read the nearest file in the directory tree, so each package can have tailored instructions: ``` repo/ ├── AGENTS.md # Global conventions ├── packages/ │ ├── api/ │ │ └── AGENTS.md # API-specific instructions │ └── web/ │ └── AGENTS.md # Frontend-specific instructions ``` ## Example ```markdown theme={null} # Project Guidelines ## Commands - `npm test` - Run test suite (required before PR) - `npm run build` - Production build - `npm run dev` - Start dev server at localhost:3000 - `npm run typecheck` - TypeScript validation **IMPORTANT**: Run `npm test` and `npm run typecheck` before creating a PR. ## Project Structure - `src/components/` - Reusable UI components - `src/features/` - Feature-specific code - `src/lib/` - Shared utilities ## Conventions - TypeScript for all files - Components: PascalCase (`UserCard.tsx`) - Branch naming: `initials/short-description` ## Security **NEVER** commit `.env` files or hardcode API keys. Run `npm run security-check` before merging to main. ``` After adding AGENTS.md, start a session and ask the agent to make a change. If it misses a convention, add emphasis or move that rule higher in the file. ## Skills for multi-step workflows [Agent Skills](https://agentskills.io) are `SKILL.md` files that live in your repository. For repeatable, multi-step procedures (deployment workflows, triage runbooks, PR checklists), use [repository skills](/docs/ona/agents/skills). The agent discovers and loads them automatically when a task matches. For organization-wide workflows that apply across all projects, use [organization skills](/docs/ona/skills). ## Getting notified when an agent finishes Enable the completion sound in [Settings > Preferences](https://app.ona.com/settings/preferences) to hear when a task completes. For webhook-style notifications, add an instruction to your `AGENTS.md` that tells the agent to run a `curl` command after completing all work: ```markdown theme={null} After completing all tasks, run in the background: curl -X POST -H "Content-Type: application/json" \ -d '{"status": "done"}' https://your-webhook-url.com/ ``` You can also monitor task completion programmatically via the [WatchEvents API method](https://ona.com/docs/api-reference). ## Next steps * [Create organization skills](/docs/ona/skills) for organization-wide workflows * [Set up your first environment](/docs/ona/configuration/devcontainer/getting-started) so agents have a reliable run loop * Learn more at [agents.md](https://agents.md) # Codex Agent Source: https://ona.com/docs/ona/agents/codex Run the open-source Codex harness in Ona Cloud or on a supported customer-managed runner. Available on the Core plan and higher. Codex Agent runs on Ona Cloud and supported customer-managed runners. [Contact sales](https://ona.com/contact/sales) to learn more. Codex Agent runs the [open-source Codex harness](https://github.com/openai/codex) in an Ona environment with your project context, environment isolation, integrations, and guardrails. ## How Codex Agent works Codex Agent can read your repository, use configured tools, run commands, and open pull requests while following your organization's policies. On Ona Cloud, Codex Agent uses the model access available to your organization. Core users can connect their ChatGPT account so Codex model requests use their ChatGPT plan instead. On a customer-managed runner, Codex Agent uses OpenAI model access provided by Ona Intelligence or an OpenAI-compatible LLM integration configured for that runner. See [Model access](/docs/ona/agents/llm-providers/overview) for the available options. ## Prerequisites * Your organization is on a Core or Enterprise plan. * Codex Agent is enabled for your organization. * Customer-managed runners require OpenAI model access through Ona Intelligence or an OpenAI-compatible LLM integration. Core users who want to use a ChatGPT plan for Codex model requests also need a ChatGPT account with Codex access. See [Connect Codex to ChatGPT](/docs/ona/integrations/configure-codex). ## Start Codex Agent 1. Start an environment. 2. Open the conversation menu. 3. Choose **Codex**. 4. Describe the task you want Codex Agent to work on. ## Organization controls Administrators can control Codex Agent behavior for the organization. ### Goal mode Goal mode lets members set Codex goals that keep running until achieved. It is **enabled** by default. To change it, go to **Organization Settings** > **Agents** and toggle **Goal mode** in the Codex settings. When disabled, members can still run Codex Agent, but requests that ask it to run in goal mode are rejected. ## Usage and billing Compute and model usage follow your organization's plan and model-access configuration: * On Core, the environment consumes OCUs while Codex Agent runs. If you connect your ChatGPT account, OpenAI manages usage and limits for Codex model requests, and Ona does not charge OCUs for those model requests. * On Enterprise, model usage follows the Ona Intelligence or BYOK configuration for your runner. See [Cost & Budgets](/docs/ona/billing/usage) and [Model access](/docs/ona/agents/llm-providers/overview) for details. ## Related setup * [Connect Codex to ChatGPT](/docs/ona/integrations/configure-codex): use your ChatGPT plan for Codex model requests * [Model access](/docs/ona/agents/llm-providers/overview): configure model access for customer-managed runners * [AGENTS.md](/docs/ona/agents-md): add project context for agents * [MCP servers](/docs/ona/mcp): extend agent capabilities with external tools # Image attachments Source: https://ona.com/docs/ona/agents/image-attachments Attach screenshots and images to agent prompts for visual context. Attach PNG or JPEG images to your prompts so the agent can use them as context. This is useful for sharing error screenshots, UI mockups, design references, or terminal output. **Example prompts with images:** * "This button is misaligned, fix it" (with a screenshot of the UI) * "Implement this design" (with a mockup attached) * "Why is this test failing?" (with a screenshot of the error output) ## How to attach images ### Click the attach button Click the paperclip icon in the prompt input bar, then select one or more image files from your file system. Prompt input bar showing the paperclip attach button ### Drag and drop Drag image files from your file system directly onto the prompt input area. A visual indicator appears when files are detected. ### Paste from clipboard Copy an image or screenshot to your clipboard (e.g. with a screenshot tool), then paste it into the prompt input with **Cmd+V** (macOS) or **Ctrl+V** (Windows/Linux). ## Attached images in the prompt After attaching, images appear as thumbnails above the prompt text. Click a thumbnail to preview it at full size. Click the **X** button on a thumbnail to remove it before sending. ## Limits | Constraint | Limit | | ------------------ | ----------------------------------- | | Supported formats | PNG, JPEG | | Maximum file size | 4 MB per image | | Maximum dimensions | 8192 x 8192 pixels | | Inputs per message | Up to 10 (text and images combined) | Files that exceed these limits are rejected. ## When to use image attachments * **UI bugs**: screenshot the broken UI and ask Ona to fix it * **Design references**: attach a mockup and ask Ona to implement it * **Error messages**: screenshot a stack trace or error dialog * **Terminal output**: screenshot complex terminal output that is hard to copy as text * **Diagrams**: share architecture diagrams or flowcharts for context ## Viewing images in sessions Attached images appear inline in the session history. Click any image to open it in a lightbox for full-size viewing. Session showing an attached image displayed inline in a user message ## Troubleshooting Only PNG and JPEG files are supported. Other formats (GIF, WebP, SVG) are not accepted. Check that the file is under 4 MB and its dimensions do not exceed 8192 x 8192 pixels. # Anthropic direct API (deprecated) Source: https://ona.com/docs/ona/agents/llm-providers/anthropic Maintain an existing direct Anthropic API integration in Ona. **Direct Anthropic API integrations are deprecated and maintenance-only.** New integrations cannot be created. Existing Enterprise integrations keep working and remain editable. You can rotate the API key, change the model, enable or disable the integration, or remove it. ## Manage an existing integration 1. Go to the [Runners settings page](https://app.ona.com/settings/runners). 2. Select the environment runner with the Anthropic integration. 3. Scroll down to the "LLM Providers" section. 4. Click **Edit** on the Anthropic integration to rotate the API key, change the model, or enable or disable the integration. You can also remove it from here. ## Verify the integration 1. Create a new environment with an enabled runner. 2. Open [Ona Agent](/docs/ona/agents/overview) and confirm it can access the configured Claude model. 3. Test the integration with a code generation request. # AWS Bedrock Runtime (deprecated) Source: https://ona.com/docs/ona/agents/llm-providers/bedrock Maintain an existing Anthropic Claude integration through AWS Bedrock Runtime. **AWS Bedrock Runtime integrations for Ona Agent are deprecated and maintenance-only.** Do not create new integrations. Existing Enterprise integrations on AWS EC2 Runners keep working. You can update the model ID or token limit, or enable, disable, or remove the integration. [AWS Bedrock Mantle](/docs/ona/agents/llm-providers/bedrock-mantle) is not deprecated. It provides OpenAI model access for Codex Agent. This page documents existing IAM-based AWS Bedrock Runtime integrations that use `bedrock://` endpoints to provide Anthropic Claude models to Ona Agent. ## Requirements for existing integrations * An AWS account with Bedrock enabled and access to the configured model. * An Ona Enterprise organization. * An AWS EC2 Runner in the same AWS account with IAM permissions to invoke Bedrock. ## Network access (VPC endpoints) If your runner operates in a private subnet without internet egress, you need a VPC endpoint for the Bedrock Runtime service. Ona only calls the **Bedrock Runtime** API (`bedrock-runtime`). No other Bedrock endpoints are required. Create an interface VPC endpoint for `com.amazonaws..bedrock-runtime` in the VPC where your runner is deployed. See the [AWS documentation on Bedrock VPC endpoints](https://docs.aws.amazon.com/bedrock/latest/userguide/vpc-interface-endpoints.html) for setup instructions. ## Maintain AWS permissions and model access * Keep access to the configured Claude model enabled in the [AWS Bedrock console](https://console.aws.amazon.com/bedrock/). * Keep the runner's IAM permissions to invoke the Bedrock Runtime API. * Keep the configured model available in the runner's AWS region. See the [AWS Bedrock Model Access documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) for access requirements. ## Check the Bedrock endpoint ### Endpoint format ```bash theme={null} bedrock:// ``` Check the configured model ID against the [AWS Bedrock model names](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html) for the runner's region. ## Verify an existing integration 1. Create a new environment with the configured runner. 2. Open [Ona Agent](/docs/ona/agents/overview) and start a session. 3. Test the integration with a code generation request. ## Supported models Existing integrations support Claude model presets including **Claude Opus 4.8** and **Claude Sonnet 5** on AWS Bedrock. ### Identifying available models There are two ways to identify models: **foundation models** and **inference profiles**. Inference profiles are resources that define a model and one or more regions for routing requests, enabling cross-region inference, usage tracking, and cost monitoring. Availability varies by region. Some regions only support foundation models, while others support both foundation models and inference profiles. Check model availability per region in the [AWS documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html). You can check availability using AWS CLI commands from your environment, assuming you have proper authentication and region environment variables set: ```bash theme={null} # List available inference profiles aws bedrock list-inference-profiles # List available foundation models aws bedrock list-foundation-models ``` ### Testing model connectivity To run a simple smoke test and verify a model works: ```bash theme={null} # Set your foundation model or inference profile ID export MODEL_ID="global.anthropic.claude-sonnet-5" # Test the model with a simple request aws bedrock-runtime invoke-model \ --model-id "$MODEL_ID" \ --body '{ "messages": [ { "role": "user", "content": "Hi there!" } ], "max_tokens": 50, "anthropic_version": "bedrock-2023-05-31" }' \ --cli-binary-format raw-in-base64-out ``` If the smoke test succeeds, the model should work with Ona Agent. ## Get help with an existing integration If you encounter issues: 1. Check Ona Agent logs for detailed error messages. 2. Verify AWS quotas and Bedrock model access. 3. Contact your account manager for additional support. ## Troubleshooting Use a model ID that is available in your runner's region. For regionalized models, use the correct prefix, such as `us.anthropic.*`. Ensure the runner role has `bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream`. Confirm model access is approved in the Bedrock console. Use `bedrock://` and include the full version, such as `...-v1:0`. Lower the maximum tokens with `gitpod runner config llm-integration set-max-tokens ...`. Review Bedrock service quotas and request increases if needed. # AWS Bedrock Mantle Source: https://ona.com/docs/ona/agents/llm-providers/bedrock-mantle Set up AWS Bedrock Mantle for OpenAI model routing on an AWS EC2 runner Available for Enterprise organizations where OpenAI model routing is enabled. [Contact sales](https://ona.com/contact/sales) to learn more. This feature is only supported in **AWS EC2 Runners**. Use AWS Bedrock Mantle when your AWS EC2 runner should route OpenAI model requests through a Bedrock Mantle endpoint. This page covers the OpenAI setup exposed in Ona. To track spend on your BYOK model usage, see the [AI cost usage API](/docs/ona/billing/cost-usage-api). ## Prerequisites * Your organization has OpenAI model routing enabled. * You have an AWS EC2 runner configured in Ona. * You have a Bedrock Mantle endpoint and token. * The runner can reach the Bedrock Mantle endpoint over HTTPS. ## Configure the endpoint Use the Bedrock Mantle endpoint for your AWS region: ```bash theme={null} https://bedrock-mantle..api.aws/openai/v1/responses ``` The Ona UI defaults to: ```bash theme={null} https://bedrock-mantle.us-east-1.api.aws/openai/v1/responses ``` ## Add the integration with the UI 1. Go to the [Runners settings page](https://app.ona.com/settings/runners). 2. Select the AWS EC2 runner where you want to configure Bedrock Mantle. 3. Scroll to **LLM Providers**. 4. Click **Configure**. 5. Select **AWS Bedrock Mantle**. 6. Enter your Bedrock Mantle endpoint. 7. Paste the Bedrock Mantle token into **API Key**. 8. Click **Create Integration**. AWS Bedrock Mantle LLM integration form showing endpoint URL and API key fields ## Add the integration with the CLI ```bash theme={null} gitpod runner config llm-integration create SUPPORTED_MODEL_OPENAI_AUTO https://bedrock-mantle..api.aws/openai/v1/responses ``` To verify the integration: ```bash theme={null} gitpod runner config llm-integration list ``` ## Verify the integration 1. Create a new environment with the configured AWS EC2 runner. 2. Start an agent that uses OpenAI model routing. 3. Confirm that the agent can answer a simple code question. ## Troubleshooting AWS Bedrock Mantle is available only on AWS EC2 runners when OpenAI model routing is enabled for your organization. It is not shown on GCP runners. Use an endpoint on the `bedrock-mantle..api.aws` domain. For OpenAI model routing, include the `/openai/v1/responses` path. Confirm that the value in **API Key** is a Bedrock Mantle token. AWS Bedrock Mantle does not use the IAM-based credential flow from the AWS Bedrock Runtime integration. # Google Vertex AI (deprecated) Source: https://ona.com/docs/ona/agents/llm-providers/google-vertex Maintain an existing Google Vertex AI integration in Ona. **Google Vertex AI integrations are deprecated and maintenance-only.** New integrations cannot be created. Existing Enterprise integrations keep working and remain editable. You can update the region, model version, or service account. You can also enable, disable, or remove the integration. ## Prerequisites for existing integrations * Your runner must be able to reach `aiplatform.googleapis.com` over HTTPS. For runners that egress through a private VPC, this means either Private Google Access on the runner's subnet or a NAT gateway with outbound internet access. Without this, agent calls fail with connection errors. * The Claude models you use must stay enabled in [Vertex AI Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) for your project. ## Endpoint format Existing integrations use endpoints of the form: ```bash theme={null} vertex://${region}/${model-version} ``` Use the [global](https://cloud.google.com/blog/products/ai-machine-learning/global-endpoint-for-claude-models-generally-available-on-vertex-ai) region for dynamic routing across available infrastructure. ## Manage an existing integration 1. Go to the [Runners settings page](https://app.ona.com/settings/runners) 2. Select the runner with the Vertex integration 3. Scroll down to the "LLM Providers" section 4. Click **Edit** on the Vertex integration. You can update: * **Region**: we recommend the global region for dynamic routing across available infrastructure. * **Model Version**: for example `claude-sonnet-5`. See [Anthropic's model availability](https://docs.anthropic.com/en/api/claude-on-vertex-ai#model-availability). * **Service Account JSON**: drag a new service account file here to replace the stored one. You can also disable or remove the integration from here. ## Troubleshooting **Authentication errors** * Verify your service account has the correct IAM roles (`Vertex AI User`) * Ensure the JSON key file is valid and properly formatted * Check that the Vertex AI API is enabled for your project **Endpoint not found** * Verify your project ID, region, and model name in the endpoint URL * Ensure the model is available in your selected region **Permission denied** * Check that your service account has `Vertex AI User` role * Verify your project has billing enabled * Ensure Vertex AI API is enabled If you encounter issues: 1. Check the Ona Agent logs for detailed error messages 2. Verify your Google Cloud quotas and limits 3. Contact your account manager for additional support # OpenAI direct API Source: https://ona.com/docs/ona/agents/llm-providers/openai Set up a runner LLM integration that connects directly to the OpenAI API Available for Enterprise organizations where OpenAI model routing is enabled. [Contact sales](https://ona.com/contact/sales) to learn more. Use the OpenAI direct API integration when your organization wants OpenAI model requests to use its own OpenAI API key. You can also configure an OpenAI-compatible endpoint. This page covers organization-level runner configuration. To connect a user's ChatGPT plan for Codex, see [Connect Codex to ChatGPT](/docs/ona/integrations/configure-codex). To track spend on your OpenAI direct API usage, see the [AI cost usage API](/docs/ona/billing/cost-usage-api). ## Prerequisites * Your organization has OpenAI model routing enabled. * You have an enterprise runner configured in Ona. * The runner can reach your OpenAI or OpenAI-compatible endpoint over HTTPS. * You have an OpenAI API key or the credentials required by your OpenAI-compatible endpoint. ## Add the integration with the UI 1. Go to the [Runners settings page](https://app.ona.com/settings/runners). 2. Select the runner where you want to configure the OpenAI direct API. 3. Scroll to **LLM Providers**. 4. Click **Configure**. 5. Select **OpenAI**. 6. Use `https://api.openai.com/v1` for direct OpenAI, or enter your OpenAI-compatible endpoint. 7. Paste the API key into **API Key**. 8. Click **Create Integration**. OpenAI LLM integration form showing endpoint URL and API key fields ## Add the integration with the CLI ```bash theme={null} gitpod runner config llm-integration create SUPPORTED_MODEL_OPENAI_AUTO https://api.openai.com/v1 ``` For an OpenAI-compatible endpoint, replace `https://api.openai.com/v1` with your endpoint URL. The URL may include a provider-specific path prefix and may end in `/v1`, `/v1/responses`, or `/v1/chat/completions`. Ona preserves the prefix and completes requests to the required OpenAI API route. To verify the integration: ```bash theme={null} gitpod runner config llm-integration list ``` ## Add custom request headers Add custom request headers when your OpenAI-compatible gateway needs a routing value or details about the person who started the environment. For example, you can send a tenant name, email address, or employee ID with each model request. Choose the header type based on the value you need: * **Fixed value**: Sends the same value for every request. * **User-specific value**: Builds the value from signed details about the environment creator when a Codex conversation starts. ### Send a fixed value To add a literal header: ```bash theme={null} gitpod runner config llm-integration set-header \ \ X-Gateway-Tenant \ tenant-a \ --type literal ``` `literal` is the default type, so `--type literal` is optional. ### Send a user-specific value The following example reads an employee ID supplied by your identity provider: ```bash theme={null} gitpod runner config llm-integration set-header \ \ X-Employee-ID \ 'env_id_claims.creator_idp_claims["employee_id"]' \ --type cel-expression ``` User-specific values use Common Expression Language (CEL). Ona makes the signed environment token details available as `env_id_claims`. Common fields include `creator_id`, `creator_email`, and `creator_idp_claims`. See [environment token claims](/docs/ona/configuration/oidc#environment-tokens) for the full list. User-specific values apply to Codex Agent conversations. Other agents send fixed headers but do not evaluate CEL expressions. ### Review or remove headers List the configured names and effective types: ```bash theme={null} gitpod runner config llm-integration list-headers ``` The command never prints literal values or CEL expressions. To remove a header: ```bash theme={null} gitpod runner config llm-integration remove-header X-Employee-ID ``` If Ona cannot read the signed environment details or resolve an expression, the model request continues without the affected header. Other configured headers remain attached, and the conversation shows a configuration warning without exposing header values. ## Verify the integration 1. Create a new environment with the configured runner. 2. Start an agent that uses OpenAI model routing. 3. Confirm that the agent can answer a simple code question. ## Troubleshooting The OpenAI direct API integration is available only when OpenAI model routing is enabled for your organization. Contact your account manager if you expect this option to be available. Verify that the API key is active and has access to the OpenAI endpoint you configured. If you use an OpenAI-compatible endpoint, confirm that the endpoint expects the same bearer-token authentication format. Confirm that the runner can reach the endpoint over HTTPS. If the runner is in a private network, check outbound routing, firewall rules, and any proxy configuration required by your network. # Model access Source: https://ona.com/docs/ona/agents/llm-providers/overview Understand default model access, Codex Agent ChatGPT plan support, and custom token providers. On Ona Cloud, Ona provides OpenAI model access for Codex Agent by default, with no configuration required. Customer-managed runners require OpenAI model access through Ona Intelligence or an approved OpenAI-compatible provider. Ona Agent and Ona-managed Anthropic model access are no longer available on Ona Cloud. Use Codex Agent with OpenAI model access for new sessions and automations. Use Ona-managed model access unless your Enterprise organization has an approved requirement to bring its own provider credentials. To see how much your organization uses, query the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api) for Ona-managed models, or the [AI cost usage API](/docs/ona/billing/cost-usage-api) if you bring your own provider keys (BYOK). ## Codex Agent model access Codex Agent is available on Ona Cloud and supported customer-managed runners. On Ona Cloud, Codex Agent can run using the model access available to the organization. Core users can also connect their ChatGPT account so Codex model requests use their ChatGPT plan. On a customer-managed runner, Codex Agent uses OpenAI model access provided by Ona Intelligence or an OpenAI-compatible LLM integration configured for that runner. See [OpenAI direct API](/docs/ona/agents/llm-providers/openai) for setup. See [Codex Agent](/docs/ona/agents/codex) for how Codex works in Ona. To use your ChatGPT plan for Codex model requests, see [Connect Codex to ChatGPT](/docs/ona/integrations/configure-codex). ## Custom token providers Custom token providers are available by exception for Enterprise customers. If you have a requirement to use your own token provider, [contact sales](https://ona.com/contact/sales) to discuss. For approved custom provider setups, see the provider-specific guides for [OpenAI direct API](/docs/ona/agents/llm-providers/openai) and [AWS Bedrock Mantle](/docs/ona/agents/llm-providers/bedrock-mantle). The [AWS Bedrock Runtime](/docs/ona/agents/llm-providers/bedrock), [Google Vertex AI](/docs/ona/agents/llm-providers/google-vertex), and [direct Anthropic API](/docs/ona/agents/llm-providers/anthropic) integrations are deprecated and maintenance-only. # Mermaid diagrams Source: https://ona.com/docs/ona/agents/mermaid-diagrams Visualize architecture, dependencies, and workflows with agent-generated diagrams Agents in Ona can generate Mermaid diagrams to visualize system architecture, dependencies, workflows, and data relationships. Ask in natural language and the agent produces a rendered diagram. **Example prompts:** * "Draw an architecture diagram showing how our microservices communicate" * "Create a sequence diagram for the authentication flow" * "Show me a dependency graph for the frontend components" * "Visualize the relationships between our database tables" An agent generating a Mermaid diagram of a distributed system architecture with code and preview tabs ## When Mermaid is useful Mermaid diagrams help compress code or process detail into something you can scan quickly. Common use cases: * Architecture overviews for onboarding * Sequence diagrams for request or authentication flows * Dependency maps for refactors * Entity diagrams for schema discussions * Workflow diagrams for automations and pipelines ## Supported diagram types * **Flowcharts**: decision trees and process flows * **Sequence diagrams**: interaction between components over time * **Class diagrams**: object-oriented relationships * **Entity-relationship diagrams**: database schema visualization * **State diagrams**: state machines and transitions * **Gantt charts**: project timelines See the [Mermaid documentation](https://mermaid.js.org/) for syntax reference. ## Viewing diagrams Diagrams render with **Code** and **Preview** tabs. The preview includes zoom controls (25% to 450%), fullscreen mode, and copy-to-clipboard. Use the **Code** tab when you want to review or tweak the Mermaid syntax, copy the diagram into another document, or ask the agent to fix a rendering problem. ## Refining a diagram The first diagram is often a draft. Good follow-up prompts include: * "Simplify this to the five most important components" * "Turn this into a sequence diagram" * "Group frontend, backend, and infrastructure separately" * "Remove low-level implementation detail and focus on data flow" ## Troubleshooting The Mermaid syntax is invalid. Ask the agent to fix it or check the code tab for syntax issues. Ask for fewer nodes, clearer grouping, or a different diagram type. # Ona Agent (deprecated) Source: https://ona.com/docs/ona/agents/overview Reference documentation for Enterprise organizations that still use Ona Agent. **Ona Agent is deprecated.** Use [Codex Agent](/docs/ona/agents/codex) for all new environments and automations. Ona Agent and Ona-managed Anthropic model access are no longer available on Ona Cloud. Existing Ona Cloud automations use Codex Agent automatically. No action is required. Enterprise organizations with customer-managed Anthropic model access can continue using Ona Agent for now, but should plan to move their workloads to Codex Agent. Customer-managed Claude Code running inside an Ona environment is not affected. Ona Agent is Ona's custom Anthropic agent harness. It writes code, runs tests, and opens pull requests in isolated environments while respecting your organization's security policies and guardrails. This page documents Ona Agent for Enterprise organizations that still use customer-managed Anthropic model access. ## What Ona Agent can do * **Write and modify code**: features, bug fixes, refactors, tests, documentation * **Run your toolchain**: commands, formatters, linters, test suites in isolated environments * **Manage pull requests**: open branches, create PRs, respond to review feedback * **Execute long-running work**: migrations, large refactors, multi-repo changes (see [Automations](/docs/ona/automations/overview)) * **Follow your policies**: command allow/deny lists, SSO, audit logging ## How Ona Agent works Give Ona Agent a task through chat, a Linear issue, or an automation trigger. It spins up an isolated environment using your Dev Container configuration, works through the task on its own, and opens a pull request when it's done. Each environment is isolated from your machine and other environments. If something goes wrong, discard it and start fresh. For how agents fit into the broader platform, see [Core Components](/docs/ona/understanding/core-components#agents). ## Prerequisites * An Enterprise plan. * Customer-managed Anthropic model access on a supported [AWS](/docs/ona/runners/aws/overview) or [GCP](/docs/ona/runners/gcp/overview) runner. ## Configure Ona Agent * **Teach agents your codebase**: create an [AGENTS.md](/docs/ona/agents-md) with your conventions, or add [Skills](/docs/ona/agents-md#skills-for-multi-step-workflows) for repo-specific workflows * **Organization-level skills**: codify your team's workflows with [skills](/docs/ona/skills) that agents discover proactively * **Connect integrations**: enable [Linear](/docs/ona/integrations/configure-linear) or other [integrations](/docs/ona/integrations/overview) for richer context * **Set guardrails**: configure [command deny lists](/docs/ona/command-deny-list), [executable deny lists](/docs/ona/organizations/policies/executable-deny-list), and [policies](/docs/ona/organizations/policies/scm-tools) for safe execution ## Best practices * Start with smaller tasks and expand scope as you build confidence * Keep environments reproducible with Dev Containers and Tasks * Use guardrails for safe, auditable execution * Test workflows in non-production repositories before broad rollout ## Next steps * [Codex Agent](/docs/ona/agents/codex): move workloads to the open-source Codex harness * [AGENTS.md](/docs/ona/agents-md): teach agents your conventions * [Skills](/docs/ona/skills): create reusable prompts agents discover proactively * [MCP servers](/docs/ona/mcp): extend agent capabilities * [Command deny list](/docs/ona/command-deny-list): restrict dangerous commands * [Executable deny list](/docs/ona/organizations/policies/executable-deny-list): block specific binaries at the kernel level # GitHub, GitLab & Bitbucket tools Source: https://ona.com/docs/ona/agents/scm-tools Built-in tools for managing pull requests, issues, and code reviews Agents in Ona include built-in tools for GitHub, GitLab, and Bitbucket Cloud. They can create pull requests, manage issues, add code review comments, and search repositories without additional configuration beyond connecting your source control provider. **Supported providers:** GitHub (including Enterprise), GitLab (including self-hosted), Bitbucket Cloud Azure DevOps supports [repository access](/docs/ona/source-control/overview) but agent tools are not yet available. Bitbucket Server / Data Center is not yet supported. Only Bitbucket Cloud (bitbucket.org) is supported. ## Capabilities * Create, update, read, and merge pull requests and merge requests * Add, update, and delete general and inline code review comments * Create, update, and manage issues and issue comments * Search issues and pull requests * Read workflow runs (GitHub Actions) and pipeline status (GitLab) **Example prompts:** * "Create a pull request for my changes titled 'Add input validation'" * "Review PR #42 and add inline comments for issues you find" * "Create an issue for refactoring the authentication module" * "Search for open issues related to 'timeout errors'" ## Organization controls SCM tools settings showing options to enable for all members, specific groups, or disabled SCM tools are enabled by default. Administrators can configure access in [Settings > Agents > Policies](https://app.ona.com/settings/agent-policies): * **Enabled for all members** (default) * **Enabled for specific group**: gradual rollout or team restrictions * **Disabled**: agents use git commands only, no PR/issue tools When disabled, agents can still clone, commit, and push but cannot interact with the GitHub/GitLab/Bitbucket API. ## Provider differences | Feature | GitHub | GitLab | Bitbucket Cloud | | --------------- | --------------- | ------------------ | ------------------- | | Inline comments | Direct comments | Discussion threads | Inline comments | | Draft PRs/MRs | Supported | Supported | Supported | | Assignees | Username-based | Requires user IDs | Not supported | | Issues | Full support | Full support | Not supported | | CI status | GitHub Actions | Pipelines | Bitbucket Pipelines | ## Prerequisites 1. [Configure source control](/docs/ona/source-control/overview) on your runner. 2. Authorize via OAuth or PAT when creating your first environment. **Required scopes:** * GitHub: `repo`, `read:user`, `workflow` (if editing Actions files) * GitLab: `api`, `read_repository`, `read_user` * Bitbucket Cloud: `account`, `pullrequest:write`, `pipeline` (`pullrequest:write` implicitly grants `pullrequest`, `repository:write`, and `repository`) ## Limitations * Cannot sync PR branches with base branch * Cannot approve or request changes on PRs * Bitbucket Cloud: no issue tracking tools (Bitbucket issues API is limited) ## Troubleshooting Verify source control is configured and you have authorized access. Restart your environment to reload tools. Check token scopes and repository permissions. For GitHub organizations, ensure [OAuth app access is granted](/docs/ona/source-control/github#granting-access-to-additional-github-organizations). # Skills Source: https://ona.com/docs/ona/agents/skills Teach agents to follow your workflows automatically. Skills are `SKILL.md` files containing step-by-step workflow instructions. They teach agents to follow specific workflows, such as creating PRs, deploying to staging, or writing tests in a particular style. When a task matches a skill's description, the agent reads and follows those instructions. Skills come from three places, plus `AGENTS.md` for general codebase context: | Feature | Repository skills | Organization skills | Built-in skills | AGENTS.md | | ------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | --------------------------------------- | | **Where they live** | `.ona/skills//SKILL.md` (also `.claude/skills/` and `.agents/skills/`) in the repo | Configured in [Settings → Agents → Skills](https://app.ona.com/settings/agent-skills) | Shipped with the agent | `AGENTS.md` in the repo | | **Scope** | Repository | Whole organization | All users | Repository | | **Discovery** | Automatic by description | Automatic by agent, or user invokes with `/` | Automatic by description | Always loaded | | **Best for** | Codebase-specific workflows | Team-wide reusable prompts and slash commands | Common workflows like `browse-web`, `ona-docs`, `devcontainer-setup`, `skill-creator` | Project conventions and general context | When two sources publish a skill with the same name, **repository skills win over organization skills, which win over built-in skills**. This lets a repo customize a team-wide workflow, or a team override a built-in one. ## Skill structure ```markdown theme={null} --- name: skill-name description: What this skill does and when to use it --- # Skill Title ## Steps 1. **Step one** - Clear instruction 2. **Step two** - Include commands where helpful ## Anti-patterns - What NOT to do ``` Here are some skills the Ona engineering team uses: ```markdown theme={null} --- name: create-pr description: Create pull requests following repository conventions. Use when asked to create a PR, open a PR, or land changes. --- # Create PR ## Steps 1. **Clean up code** - remove obvious comments from new/changed code 2. **Format** - run `gofmt` (Go) or `prettier` (JS/TS) 3. **Lint** - run `golangci-lint run ./...` (Go) or `eslint` (JS/TS) 4. **Create branch** - `/` (max 24 chars) 5. **Commit** - use Conventional Commits 6. **Push** - `git push -u origin ` 7. **Open draft PR** - use `.github/pull_request_template.md` ## Anti-patterns - Don't use superlatives in commits or PR descriptions - Don't commit unrelated changes - Don't push to main directly ``` ```markdown theme={null} --- name: go-tests description: Generates Go unit tests using the Expectation pattern with cmp.Diff. Use when writing or fixing Go tests. --- # Go Tests Table-driven tests using the Expectation pattern with `cmp.Diff`. ## Rules 1. **Always use `t.Parallel()`** at test function and subtest level 2. **Never use `t.Parallel()` with `t.Setenv()`** - they panic together 3. **Single `cmp.Diff` assertion** comparing entire Expectation struct 4. **Capture errors as strings** in `Expectation.Err`, not with `t.Fatal` 5. **Never use testify** - use `cmp.Diff` only ## Anti-Patterns - `t.Fatal` for action errors → use `Expectation.Err` - `context.Background()` → use `t.Context()` - `testify/assert` → use `cmp.Diff` ``` Requires [Linear integration](/docs/ona/integrations/configure-linear). ```markdown theme={null} --- name: linear-ticket description: Create Linear tickets from code analysis. Use when asked to create a ticket, file an issue, or track work in Linear. --- # Create Linear Ticket Create a well-structured Linear ticket from the current context. ## Steps 1. **Gather context** - Understand what needs to be tracked (bug, feature, task) 2. **Check for duplicates** - Search Linear for existing tickets on the same topic 3. **Create ticket** - Use appropriate team, labels, and priority 4. **Link resources** - Attach relevant PRs, files, or documentation ## Ticket format - **Title**: Clear, actionable (`Fix auth timeout on slow connections`) - **Description**: Include reproduction steps for bugs, acceptance criteria for features - **Labels**: Add relevant labels (bug, feature, tech-debt) ## Anti-patterns - Don't create duplicate tickets - Don't leave description empty - Don't assign without checking availability ``` ```markdown theme={null} --- name: sentry-triage description: Find and triage Sentry errors. Creates a Linear ticket with analysis. --- # Sentry Triage Find the highest-impact untriaged Sentry error and create ONE Linear ticket. ## Steps 1. **Find first untriaged issue** - Query Sentry for unresolved errors in last 24 hours, sorted by event count 2. **Skip if tracked** - Search Linear for existing ticket with Sentry ID 3. **Check if already fixed** - Look for recent commits that address the error 4. **Analyze** - Get stacktrace, identify root cause, classify as bug/false-positive/noise 5. **Create Linear issue** - Title includes Sentry ID, description has stacktrace and fix assessment ## What this skill does NOT do - Does NOT implement fixes (use `sentry-fix` skill) - Does NOT process multiple issues per run ``` ```markdown theme={null} --- name: sentry-fix description: Implement a fix for a triaged Sentry issue and create a PR. Use when given a Linear issue ID to fix. --- # Sentry Fix Implement a fix for a triaged Sentry issue and create a PR. **Input**: Linear issue ID (e.g., `AGENT-1646`) **Output**: PR URL, or explanation why fix was not attempted ## Steps 1. **Get issue context** - Fetch Linear issue, extract Sentry link and fix assessment 2. **Validate** - Confirm root cause documented, fix location identified, change is mechanical 3. **Implement** - Read target file, apply fix following codebase patterns 4. **Create PR** - Use `create-pr` skill, include Sentry issue ID for auto-resolution ## Anti-patterns - Never hide bugs by changing log levels for genuinely unexpected conditions - Stop if uncertain — let humans decide ``` ## Create a skill Skills live in your repository. 1. Create a directory in `.ona/skills/`: ```bash theme={null} mkdir -p .ona/skills/create-pr ``` 2. Create a `SKILL.md` file: ```markdown theme={null} --- name: create-pr description: Create pull requests following repository conventions --- # Create Pull Request ## Steps 1. **Run checks**: `npm test && npm run lint` 2. **Create branch**: `initials/short-description` 3. **Create PR**: Use template, link issues ## Anti-patterns - PRs with failing tests - Skipping the PR template ``` 3. Commit to your repository: ```bash theme={null} git add .ona/skills/create-pr/ git commit -m "Add create-pr skill" ``` ### Directory structure ``` .ona/skills/ ├── create-pr/ │ └── SKILL.md ├── deploy-staging/ │ └── SKILL.md └── debug-performance/ └── SKILL.md ``` ### SKILL.md format **Required fields**: * `name`: Unique identifier. If omitted, defaults to the directory name * `description`: When to use this skill. Be specific and include trigger words **Naming conventions**: * Lowercase letters, numbers, and hyphens * Maximum 64 characters * Avoid vague names: `helper`, `utils`, `tools` ## How agents discover skills At session start, the agent collects skills from three sources: 1. **Repository skills** in `.ona/skills/`, `.claude/skills/`, or `.agents/skills/` of the current repo 2. **Organization skills** configured for your Ona organization 3. **Built-in skills** that ship with the agent Each source contributes a list of skills (name + description). Full skill content is loaded on demand via `read_skill` when a task matches a skill's description. When two sources publish a skill with the same name, repository skills win over organization skills, and organization skills win over built-in skills. ## Best practices ### Write specific descriptions The description determines when the agent uses the skill: * ✅ "Create pull requests following repository conventions. Use when asked to create a PR, open a PR, or land changes." * ❌ "PR stuff" ### Design for stability * Use concepts that remain valid despite refactoring * Let the agent rediscover current code state rather than hardcoding paths * If tools can't do something, drop it ### Keep skills focused One skill per workflow. Keep `SKILL.md` under 500 lines. Move reference material to separate files. ### Include anti-patterns Tell the agent what not to do. This prevents common mistakes. ### Reference, don't duplicate ```markdown theme={null} ## Database migrations See [migrations guide](./docs/migrations.md) for the full process. ``` ## Next steps * [AGENTS.md](/docs/ona/agents-md): general codebase context * [Organization skills](/docs/ona/skills): team-wide reusable prompts with optional slash commands * [Automations](/docs/ona/automations/overview): run workflows automatically ## Troubleshooting **Check the description**: Be specific about when to use it and include trigger words. **Check the path**: Skills must be in `.ona/skills//SKILL.md` (or `.claude/skills/` or `.agents/skills/`) **Check path**: Ensure the file is at `.ona/skills//SKILL.md` (or `.claude/skills/` or `.agents/skills/`) **Check frontmatter**: Ensure YAML is valid with required `name` and `description` fields # Automations as Code Source: https://ona.com/docs/ona/automations/automations-as-code Define, version, and share Automations using YAML files and the Ona CLI. Define Automations as YAML files and manage them with the Ona CLI. ## Why define Automations as code * **Version control.** Track changes in Git. Review diffs, revert mistakes, use branches. * **Reproducibility.** The YAML file is the source of truth. No UI clicks to reconstruct a lost Automation. * **Distribution.** Commit Automation files to any repository. Team members run `ona ai automation create` to instantiate them. ## Prerequisites * [Ona CLI](/docs/ona/integrations/cli) installed and authenticated (`ona login`) ## Discover the YAML syntax Generate a reference file covering the full syntax: ```bash theme={null} ona ai automation create --example > automation.yaml ``` ## Create an Automation from a file ```bash theme={null} ona ai automation create automation.yaml ``` On success, the CLI prints the new Automation ID: ``` Successfully created ai automation a1b2c3d4-5e6f-7890-abcd-ef1234567890 ``` Stdin is also supported: ```bash theme={null} cat automation.yaml | ona ai automation create - ``` ## Update an existing Automation Find the Automation ID: ```bash theme={null} ona ai automation list ``` Apply the updated file: ```bash theme={null} ona ai automation update automation.yaml ``` Provided fields replace existing values. Fields not in the YAML remain unchanged. Complex fields like `triggers` and `action` are replaced entirely, not merged. ## Real-world example [ona-samples/github-security](https://github.com/ona-samples/github-security) contains two Automation files that pick the highest-severity open security alert, fix it, run tests, and open a PR: * [`.ona/fix-dependabot-alert.yaml`](https://github.com/ona-samples/github-security/blob/main/.ona/fix-dependabot-alert.yaml) — upgrades vulnerable dependencies flagged by Dependabot * [`.ona/fix-codescan-alert.yaml`](https://github.com/ona-samples/github-security/blob/main/.ona/fix-codescan-alert.yaml) — fixes code scanning findings from CodeQL, Trivy, or OSV-Scanner ```bash theme={null} ona ai automation create .ona/fix-dependabot-alert.yaml ona ai automation create .ona/fix-codescan-alert.yaml ``` ## Next steps * [Creating Automations](/docs/ona/automations/configure-automations) — UI-based setup * [Automations in practice](/docs/ona/automations/automations-in-practice) — real-world templates * [Report step](/docs/ona/automations/report-step) — structured data extraction * [CLI reference](/docs/ona/reference/cli) — full command reference # Automations in practice Source: https://ona.com/docs/ona/automations/automations-in-practice Set up five real-world Automations: Sentry triage, autonomous backlog picker, Knip cleanup, CVE remediation, and migrations at scale. Your Sentry dashboard has 40 unresolved errors. Your Linear backlog has 30 issues in the current sprint, and realistically you will get to maybe five of them today. You could spend the morning triaging each one, reading stack traces, and context-switching between tools. Or you could set up Automations that triage errors, trace them to source code, and open fix PRs while you focus on design decisions and code review. This guide walks through five Automations that cover the most common use cases: **Sentry error triage and fix**, **Autonomous backlog picker (10x engineer)**, **Codebase cleanup with Knip**, **CVE remediation with Snyk or Aikido**, and **Migrations at scale**. Automations work best with [projects](/docs/ona/projects/overview). A project provides the Dev Container configuration, dependencies, and environment settings that your Automation runs against. All templates in this guide assume you have a project set up for your repository. See [Create your first project](/docs/ona/create-first-project). ## Sentry error triage and fix This template queries Sentry for unresolved errors, traces the highest-impact one to source code, applies a fix, and opens a pull request. ### What it does The Automation runs four steps in sequence: 1. **Triage.** Queries Sentry for unresolved issues from the past 24 hours, sorted by event count. Selects the top unassigned issue and extracts the title, error message, stack trace, event count, and affected users. 2. **Root cause analysis.** Locates the exact file and line in your repository using the stack trace. Identifies the error category (null reference, type error, unhandled exception, race condition, etc.) and explains the root cause. 3. **Fix.** Applies the minimal change needed to resolve the root cause. Adds or updates tests to cover the error scenario. Runs the test suite and iterates until tests pass. 4. **Pull request.** Opens a PR with the fix, linking back to the Sentry issue. ### Prerequisites * Ona account with Automations enabled * [Sentry integration](/docs/ona/integrations/overview) configured for your organization * A project with a connected repository that reports errors to Sentry ### Set up the Automation 1. Navigate to **Automations** in the left panel and click **New**. Automations page with templates 2. Select the **Sentry error triage and fix** template. If the [Sentry integration](/docs/ona/integrations/configure-sentry) is not configured, a **Required Integrations** dialog appears. Follow the links to enable the integration in **Organization settings > Integrations** and connect it with your personal account in **User settings > Integrations**. The **Create** button is disabled until all required integrations are configured. 3. Under **Trigger**, the default is [**Manual**](/docs/ona/automations/triggers/manual). Keep this for your first run. Switch to a daily schedule later. 4. Under **Projects**, select the project whose repository reports to Sentry. 5. Click **Save**. ### Run it 1. Open the Automation and click **Run**. 2. The execution view shows each step as it progresses: * Step 1 queries Sentry and selects an error * Step 2 traces the stack trace to your codebase * Step 3 applies the fix and runs tests * Step 4 opens the pull request Execution summary showing Automation steps Expand any step to see the agent's reasoning and the commands it ran: Action logs showing agent output ### Review the result The Automation opens a pull request with: * The fix applied to the affected file(s) * New or updated tests covering the error scenario * A description linking to the Sentry issue and explaining the root cause Review the PR as you would any other. Check the fix, verify the tests, and merge when satisfied. ### Tips * **Start manual.** Run the Automation a few times manually to build confidence in the results before scheduling it. * **Schedule regularly.** Once you trust the output, switch the trigger to scheduled. Use **Every day** for daily runs, or **Every weekday** for weekday mornings at 9 AM UTC. * **Pair with Sentry to Linear issues.** The "Sentry to Linear issues" template creates Linear tickets from Sentry errors. Combined with this template, you get a full pipeline: detect, ticket, fix, PR. ## Autonomous backlog picker (10x engineer) This template runs every weekday morning, picks your highest-priority Linear issue, implements it, runs tests, and opens a draft PR. ### What it does The Automation runs five steps: 1. **Fetch candidates.** Queries Linear for issues assigned to you in the current sprint. Sorts by priority (urgent first), then due date. Excludes issues already in progress, in review, or done. Returns the top 5 candidates. 2. **Evaluate feasibility.** For each candidate, analyzes the repository to determine if the issue can be implemented end-to-end: clear requirements, contained scope, testable, no external infrastructure changes needed. Picks the first feasible issue. 3. **Code.** Updates the Linear issue status to "In Progress," then writes the changes following existing code patterns. Adds tests for new functionality and handles edge cases from the acceptance criteria. 4. **Test.** Runs the project's test suite (`npm test`, `go test ./...`, or equivalent). 5. **Pull request.** Opens a draft PR linking to the Linear issue. Updates the issue status to "In Review." ### Prerequisites * Ona account with Automations enabled * [Linear integration](/docs/ona/integrations/overview) configured for your organization and your user account * A [project](/docs/ona/projects/overview) with a connected repository * Issues assigned to you in the current sprint/cycle with clear acceptance criteria ### Set up the Automation 1. Navigate to **Automations** and select the **10x engineer** template. If the [Linear integration](/docs/ona/integrations/configure-linear) is not configured, a **Required Integrations** dialog appears — follow the links to enable and connect it before proceeding. 2. Under **Trigger**, the default is [**Scheduled**](/docs/ona/automations/triggers/timebased): every weekday at 9 AM UTC. Adjust the time to match your morning routine. 3. Under **Projects**, select the project you want the Automation to work on. 4. Click **Save**. ### Run it The Automation fires on schedule. Each morning: 1. It picks your top issue from Linear. 2. Implements the change in your repository. 3. Runs tests. 4. Opens a draft PR. Automation details showing execution history and run controls You review the draft PR over coffee. If the implementation looks good, mark it ready for review and merge. If it needs changes, leave comments. The next run will pick a different issue. If none of the top 5 candidates are feasible (too large, unclear requirements, requires infrastructure changes), the Automation stops early and reports why. This is expected. Not every issue is automatable. ### Tips * **Keep your backlog prioritized.** The Automation picks the highest-priority issue. If your backlog is unsorted, it may pick something low-value. * **Use labels to curate candidates.** Add a label like `good-for-ona` to issues that are well-scoped and automatable, then adjust the prompt to filter by that label. This gives you explicit control over what the Automation picks up. * **Start with well-scoped issues.** Bug fixes, small features, and refactors with clear acceptance criteria work best. Exclude epics and large issues. * **Review the draft PRs.** These are drafts for a reason. Treat them as a starting point, not a finished product. ## Codebase cleanup with Knip This Automation combines a deterministic command ([Knip](https://knip.dev/)) with the agent to find and remove unused code. It keeps the codebase clean and context windows tight for other agents. ### What it does The Automation runs three steps: 1. **Scan.** Runs Knip against the repository to detect unused JS/TS dependencies, exports, types, and files. 2. **Clean up.** The agent removes the unused code identified by Knip. Creates small, focused changes that are quick to review. 3. **Pull request.** Opens a PR with automerge enabled. Each PR addresses one category of unused code (dependencies, exports, or files) to keep reviews manageable. ### Prerequisites * Ona account with Automations enabled * A [project](/docs/ona/projects/overview) with a connected JS/TS repository * Knip installed as a dev dependency or available in your Dev Container ### Set up the Automation 1. Navigate to **Automations** and click **New**. 2. Select **Start from scratch**. 3. Add a **Command** step that runs Knip and captures the output: ```bash theme={null} npx knip --reporter json > knip-report.json ``` 4. Add a **Prompt** step: ``` Read knip-report.json. For each category of unused code (dependencies, exports, files), remove the unused items. Run the test suite after each change to verify nothing breaks. ``` 5. Add a **Pull Request** step with automerge enabled. 6. Under **Trigger**, select **Scheduled** with a weekly schedule (e.g., `0 8 * * 1` for Monday mornings). 7. Under **Projects**, select the target project. 8. Click **Save**. ### Run it Run the Automation manually first to verify the results. Knip may flag items that are used dynamically or through non-standard imports. Review the first few PRs carefully and adjust the Knip configuration if needed. Once confident, let the weekly schedule handle it. Each Monday morning, you get a small PR removing dead code. ### Tips * **Configure Knip first.** Add a `knip.json` or `knip.ts` config to exclude known dynamic imports and entry points. This reduces false positives. * **Enable automerge.** Knip cleanup PRs are low-risk if your test suite is solid. Automerge keeps the process hands-off. * **Pair with CI.** Add Knip to your CI pipeline so new unused code is caught at PR time, not only during weekly cleanup. ## CVE remediation with Snyk or Aikido This Automation runs security scanning CLIs against your projects, resolves all found CVEs, and creates standardized PRs. Schedule it for off-hours and review clean PRs the next morning. ### What it does The Automation runs four steps: 1. **Scan.** Runs the security CLI (Snyk, Aikido, or similar) against the repository to identify CVEs. 2. **Remediate.** The agent resolves each CVE: upgrades dependencies, applies patches, or migrates breaking API changes. 3. **Verify.** Reruns the security scan to confirm all CVEs are resolved. Runs the test suite to verify nothing breaks. Iterates until both pass. 4. **Pull request.** Opens a PR with a summary of resolved CVEs, linking to advisory details. ### Prerequisites * Ona account with Automations enabled * A [project](/docs/ona/projects/overview) with a connected repository * Snyk CLI, Aikido CLI, or equivalent installed in your Dev Container * API token for the security tool stored as a [secret](/docs/ona/configuration/secrets/overview) ### Set up the Automation 1. Navigate to **Automations** and click **New**. 2. Select **Start from scratch**. 3. Add a **Command** step that runs the security scan: ```bash theme={null} snyk test --json > snyk-report.json ``` 4. Add a **Prompt** step: ``` Read snyk-report.json. Resolve every CVE found: upgrade dependencies, apply patches, or migrate breaking changes. After each fix, rerun "snyk test" to verify the CVE is resolved. Run the test suite to confirm nothing breaks. Iterate until "snyk test" reports zero vulnerabilities. ``` 5. Add a **Pull Request** step. 6. Under **Trigger**, select **Scheduled** with an off-hours schedule (e.g., `0 20 * * 0` for Sunday at 8 PM UTC). 7. Under **Projects**, select the target projects. 8. Click **Save**. ### Run it Run manually first against a single repository. Review the PR to verify the fixes are correct and tests pass. Once confident, enable the schedule. Every execution gets the exact same tooling. The environment is reproducible, so results are consistent across runs. ### Tips * **Schedule for off-hours.** Sunday evening is ideal. Review clean PRs Monday morning. * **Run across multiple repos.** Select multiple projects to scan your entire organization in parallel. * **Combine with compliance reporting.** The Automation's execution log provides an audit trail of what was scanned, what was found, and what was fixed. ## Migrations at scale This Automation handles large-scale migrations by batching repositories on a schedule and creating incremental, reviewable PRs. Examples: CI pipeline migration (GitLab CI to GitHub Actions), Java 8 to 17 upgrades, JavaScript to TypeScript conversion. ### What it does The Automation runs three steps per repository: 1. **Analyze.** The agent reads the repository to understand the current state and determine what needs to change for the migration. 2. **Migrate.** Applies the migration changes incrementally. Runs the test suite after each change to verify correctness. 3. **Pull request.** Opens a PR with the migration changes and a description of what was changed and why. ### Prerequisites * Ona account with Automations enabled * [Projects](/docs/ona/projects/overview) set up for each repository in the migration batch * A clear migration specification (what to change, what the target state looks like) ### Set up the Automation 1. Navigate to **Automations** and click **New**. 2. Select **Start from scratch**. 3. Add a **Prompt** step with your migration specification. Be specific about the target state: ``` Migrate this repository from GitLab CI (.gitlab-ci.yml) to GitHub Actions (.github/workflows/). Convert each CI job to an equivalent GitHub Actions workflow. Preserve all environment variables, secrets references, and deployment targets. Run the test suite to verify the migration. Delete the .gitlab-ci.yml file after all workflows are verified. ``` 4. Add a **Pull Request** step. 5. Under **Trigger**, select **Scheduled** with a batched schedule (e.g., `0 22 * * 0` for Sunday at 10 PM UTC). 6. Under **Projects**, select a batch of repositories (e.g., 10 at a time). 7. Set **Guardrails**: max parallel 10, max total 10. 8. Click **Save**. ### Run it Start with a small batch (2-3 repos) to validate the migration logic. Review the PRs carefully. Once the pattern is proven, increase the batch size. Each Sunday night, the Automation migrates the next batch. Engineers review the PRs Monday morning. Over a few weeks, the entire organization is migrated. ### Tips * **Batch deliberately.** Start with simple repositories (few CI jobs, standard configurations) and progress to complex ones. * **Write a detailed migration spec.** The more specific the prompt, the more consistent the results across repositories. * **Track progress externally.** Use a spreadsheet or Linear project to track which repositories have been migrated, which are in progress, and which remain. * **Combine with a PR trigger.** After the migration PR is merged, use a PR-triggered Automation to verify the new CI pipeline runs successfully. ## How they connect These five Automations address different parts of the development cycle but complement each other naturally. The Sentry template finds and fixes production errors. If you also use the **Sentry to Linear issues** template, those errors become Linear tickets. The Autonomous backlog picker then picks those tickets up automatically in the next morning run. Knip cleanup keeps the codebase lean, which improves the accuracy and speed of every other Automation. CVE remediation handles security debt on a schedule. Migrations at scale tackles the large projects that slip every quarter. Together, they create a loop: **detect, triage, fix, clean, ship**. ## Scaling across repositories The templates above work on a single project and repository. As your usage grows, run the same Automation across multiple repositories in parallel. For example, scanning and fixing Sentry errors across dozens of repos simultaneously. The number of parallel actions depends on your plan. See [Plans and limits](/docs/ona/automations/plans-and-limits) for details. ## Next steps * [Creating Automations](/docs/ona/automations/configure-automations): customize templates or build from scratch * [Manual triggers](/docs/ona/automations/triggers/manual), [pull request triggers](/docs/ona/automations/triggers/pullrequest), and [scheduled triggers](/docs/ona/automations/triggers/timebased): configure when Automations run * [Plans and limits](/docs/ona/automations/plans-and-limits): per-plan caps on Automations and actions * [Guardrails](/docs/ona/automations/guardrails): control execution limits and blocked commands * [Service accounts](/docs/ona/organizations/service-accounts): run Automations as a team identity # Configure Automations Source: https://ona.com/docs/ona/automations/configure-automations Configure triggers, steps, guardrails, and workflows This guide covers Automation configuration in detail. For a quick walkthrough, see [Create your first Automation](/docs/ona/create-first-automation). Automations work best with [projects](/docs/ona/projects/overview). A project provides the Dev Container configuration, dependencies, and environment settings that your Automation runs against. We recommend setting up a project before creating Automations. ## Create an Automation 1. Navigate to **Automations** in the left panel. 2. Click **New**. 3. Choose **Start from scratch** or select a pre-configured template. Automations page ## Name and description To set or change the name and description, open the **⋯** menu on the Automation and select **Rename**. A dialog opens where you can edit both fields. ## Trigger type * **[Manual](/docs/ona/automations/triggers/manual)**: run on demand * **[Pull request](/docs/ona/automations/triggers/pullrequest)**: trigger on PR events * **[Scheduled](/docs/ona/automations/triggers/timebased)**: run on a schedule Click the trigger node and then **Edit** to open the trigger configuration dialog. ## Runs on Each trigger includes a **Runs on** setting that determines where the Automation runs: | Scope | Description | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | **Projects** (recommended) | Run on specific [projects](/docs/ona/projects/overview). The Automation uses each project's Dev Container configuration and environment settings. | | **Repositories** | Run on repositories matched by explicit URLs or a search query. Use for large-scale migrations across many repos. | See [Manual triggers](/docs/ona/automations/triggers/manual) and [Pull request triggers](/docs/ona/automations/triggers/pullrequest) for scope configuration details per trigger type. ## Guardrails Control execution limits to prevent Automations from running excessively: * **Max concurrent actions**: simultaneous runs * **Max total actions**: total allowed per run Maximum values depend on your plan. See [Plans and limits](/docs/ona/automations/plans-and-limits) for per-plan caps and [Guardrails](/docs/ona/automations/guardrails) for details. ## Run Automation as The **Run Automation as** selector is at the bottom of the trigger configuration dialog. | Option | When to use | | ---------------------------------------------------------- | -------------------------------------- | | **Your user** | Manual workflows, personal Automations | | **[Service account](/docs/ona/organizations/service-accounts)** | Scheduled or shared Automations | Every user can run an Automation as themselves. Organization Admins and Automations Admins can also choose active service accounts. Automations cannot be configured to run as another human user. ## Steps Steps execute in sequence within the same environment. Each step can access files, environment variables, and context from previous steps. ### Step types | Type | Use when | | ------------------------------------------ | ------------------------------------------------------------------------------------------- | | **Prompt** | Flexible tasks requiring agent judgment: "analyze and improve", "update based on context" | | **Command** | Deterministic operations: `npm test`, `docker build` | | **Pull request** | Submit changes for review after making modifications | | **[Report](/docs/ona/automations/report-step)** | Extract structured data from the execution: test coverage, dependency counts, build metrics | ### Example workflow ``` Step 1 (Prompt): "Upgrade all dependencies to their latest versions" Step 2 (Command): npm test Step 3 (PR): Create pull request with summary ``` **Guidance:** * Use prompts for context-aware tasks that vary by repository. * Use commands for predictable, repeatable operations. * Combine both: commands for validation, prompts for intelligent changes. Steps configuration ## Add parameters to manual runs Use Go template syntax in a **Prompt**, **Command**, or pull request title, description, or branch to request a value when someone starts the Automation manually. For example, add `{{ .Parameters.ticket_id }}` to a prompt: ```text theme={null} Investigate {{ .Parameters.ticket_id }}, implement a fix, and run the relevant tests. ``` The same syntax works in a shell command: ```bash theme={null} ./scripts/release.sh {{ .Parameters.release_channel }} ``` Parameter names must start with a letter or underscore and contain only letters, numbers, and underscores. An Automation can reference up to 10 unique parameters. When a user clicks **Run**, Ona detects the referenced names and opens **Run with options**. Every value is required. See [Run an Automation with parameters](/docs/ona/automations/running-automations#run-with-parameters) for the execution flow. Run parameters are entered interactively for manual executions. Scheduled and pull request triggers cannot prompt for parameter values, so use fixed values or trigger context for those runs. Do not use run parameters for credentials or other sensitive values. Configure [service account secrets](/docs/ona/organizations/service-accounts#secrets) instead. ## Save and edit Click **Save** to create the Automation. All settings can be modified after creation. Pull request triggers require an event source: [GitHub](/docs/ona/integrations/configure-github) (for GitHub.com) or a [webhook](/docs/ona/automations/webhooks). See [Pull request triggers](/docs/ona/automations/triggers/pullrequest) for details. ## Enable and disable Disable an Automation to stop it from running without deleting it. Disabled Automations keep their configuration, execution history, and triggers, but no new runs can start (manually or via triggers). To toggle an Automation: * **From the list**: open the three-dot menu on any Automation and select **Disable** or **Enable**. * **From the details page**: use the toggle switch next to the Automation name. Disabled Automations appear with muted styling in the list and show a "Disabled" status label. Use the **Enabled** / **Disabled** filter in the status dropdown to find them. Disabling is useful when you want to pause a scheduled or event-driven Automation temporarily, for example during a code freeze or while debugging a failing workflow, without losing its configuration. ## Next steps * [Run an Automation](/docs/ona/automations/running-automations) * [Troubleshooting](/docs/ona/automations/troubleshooting) # Automation guardrails Source: https://ona.com/docs/ona/automations/guardrails Safety controls and policies for Automations Guardrails keep Automations running securely and within defined boundaries. For general Ona guardrails (policies, SSO, audit logs), see [Ona Guardrails](/docs/ona/guardrails/overview). ## Environment isolation Each Automation runs in an isolated environment with dedicated resources. No access to other Automations or user environments. See [Environments](/docs/ona/environments/overview). ## Command deny lists Prevent Automations from executing dangerous commands (`sudo`, `rm -rf /`, cloud CLIs). Blocked commands fail immediately. Configure at the organization level. See [Command deny lists](/docs/ona/command-deny-list). ## Executable deny list Block specific binaries from running inside Automation environments using kernel-level enforcement. Unlike command deny lists, executables are identified by content hash and cannot be bypassed by renaming. See [Executable deny list](/docs/ona/organizations/policies/executable-deny-list). ## Audit logging Every execution is logged: commands, file changes, PRs created, errors. Use for debugging and compliance. See [Audit logs](/docs/ona/audit-logs/overview). ## Organization policy limits Automation organization policy controls are in preview and available only to selected Enterprise organizations. Organization administrators can configure Automation limits in **Settings → Agents → Policies → Automations**: * **Automations per member** limits how many active Automations each member can own. The default is 5. Disabled Automations and Automations pending deletion do not count. * **Projects per Automation** limits how many projects a member can select explicitly in one Automation. * **Concurrent actions** limits how many actions an Automation can run at once. The policy page shows the configured values and the Enterprise maximums: 50 Automations per member, 100 projects per Automation, and 25 concurrent actions. Organization Admins and Automations Admins are exempt from organization-configured Automation limits. Plan and API maximums still apply. Lowering the ownership limit does not modify existing Automations, but members at the limit cannot create or reactivate another Automation. ### Action limits Control parallel execution to manage costs and prevent Automations from running excessively. Maximum values depend on your [plan](/docs/ona/automations/plans-and-limits). | Limit | Core | Enterprise | | -------------- | ---- | ---------- | | Max concurrent | 10 | 25 | | Max total | 50 | 100 | Core plans enforce the caps listed above. Enterprise organizations can configure the concurrent-action policy up to the current system-wide ceiling of 25. The total-action limit remains subject to the system-wide ceiling of 100 actions per Automation. [Contact sales](https://ona.com/contact/sales) if you need higher limits. Creating or updating an Automation with a concurrent-action value above the effective organization, plan, or API limit returns an error. Lowering the organization policy preserves existing Automation configuration, but the next action edit must comply with the current limit. Until then, new executions use the lower current limit. The same execution-time protection applies if a plan or API limit is reduced. ### Project limits Enterprise organization admins can limit how many projects a member may select explicitly in one Automation, up to 100 projects. This limit applies to project contexts, not repository URL or repository search contexts. Creating or updating an Automation with too many unique project IDs returns an error. Lowering the organization policy preserves existing Automation configuration, but the next project-context edit must comply with the current limit. An existing Automation that exceeds the current limit cannot start a new project-context execution until its project selection is updated. ### Per-execution time limit Each execution action can have an optional maximum duration. When set, actions that exceed this time are stopped automatically. Configure this in the Automation's action limits. ### Queue behavior When the concurrent limit is reached, additional actions queue and start as others complete. When the total limit is reached, the Automation stops. Increase limits and re-run to process remaining targets. ## Next steps * [Command deny lists](/docs/ona/command-deny-list) * [Executable deny list](/docs/ona/organizations/policies/executable-deny-list) * [Audit logs](/docs/ona/audit-logs/overview) * [Service accounts](/docs/ona/organizations/service-accounts) # Background automations Source: https://ona.com/docs/ona/automations/overview Proactive background agents that combine AI prompts with deterministic commands in trigger-based, closed-loop workflows. Automations are background agents that run in the cloud. They combine AI prompts with deterministic commands to deliver merge-ready pull requests triggered manually, on a schedule, on pull request events, or via webhooks. Automations page Automations work best with [projects](/docs/ona/projects/overview). A project provides the Dev Container configuration, pre-installed dependencies, and environment settings that every Automation run uses. Set up a [project](/docs/ona/create-first-project) first, then build Automations on top of it. ## How Automations work Every Automation follows a closed-loop workflow: 1. **Trigger**: run manually, on PR events, on a schedule, or via webhook. 2. **Execute**: Ona clones, branches, installs, builds, tests, iterates, commits, pushes, and opens a PR. The same loop a human engineer runs, except Automations can do it across hundreds of repos in parallel. 3. **Review**: inspect outputs, logs, and linked PRs. Approve and merge when satisfied. Every Automation runs in a fully configured environment defined by `devcontainer.json` and `.ona/config.yaml`. Dependencies install, services start, tools are available. Not a minimal CI runner, but a full development environment. Automation execution dashboard For how Automations fit into the broader platform, see [Core Components](/docs/ona/understanding/core-components#automations). ## Runs in the cloud Automations run in the background. Your laptop does not need to be on. Review results from your phone or iPad. On Ona Cloud, execution happens in Ona's infrastructure. Enterprise customers can run Ona in their own network (AWS, GCP), giving Automations the same connectivity and context your engineers have: query databases, hit internal APIs, run the full test suite against staging without tunnels or exported secrets. ## Integrations Ona has native integrations with [Linear](/docs/ona/integrations/configure-linear), [Sentry](/docs/ona/integrations/configure-sentry), [Notion](/docs/ona/integrations/configure-notion), [Granola](/docs/ona/integrations/configure-granola), [GitHub, GitLab, and Atlassian](/docs/ona/integrations/configure-atlassian), giving Automations the same context and permissions your engineers have to read backlogs, triage issues, and open PRs. Any [MCP server](/docs/ona/mcp) can be added as config-in-code via `.ona/mcp-config.json` in your repository. ## Use cases Get started with a template or [build your own from scratch](/docs/ona/automations/configure-automations). See [Automations in practice](/docs/ona/automations/automations-in-practice) for detailed setup guides for each use case. ## Access Automations are available on Core and Enterprise plans with [plan-based limits](/docs/ona/automations/plans-and-limits) on the number of Automations, concurrent actions, and features like webhooks. Enterprise organizations require [Ona Intelligence](https://ona.com/contact/sales); you can query its usage with the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api). Organization admins can [share Automations with individual users and groups](/docs/ona/automations/sharing-automations), allowing team members to run pre-built Automations without admin privileges. ## Related: Tasks and Services Automations run across repositories at scale. For per-environment automation (database seeding, server startup, test commands), see [Tasks and Services](/docs/ona/configuration/tasks-and-services/overview). Tasks and Services are configured in `.ona/config.yaml` and run within individual environments. ## FAQ No. Automation environments are isolated execution contexts, not interactive environments. Test on one or a few repositories first. Review results, adjust steps, then scale up gradually. **Projects**: repetitive tasks on known repositories, pull request triggers. **Repositories**: large-scale migrations across thousands of repos, fine-grained selection. Always in your Dev Container configuration. Packages are then available for all steps, pre-installed for faster runs. Configure [MCP integrations](/docs/ona/mcp) in Settings > Integrations. These are then available to your Automations. Yes. Disable it from the three-dot menu in the list or the toggle on the details page. Disabled Automations retain their configuration and history but won't start new runs. See [Enable and disable](/docs/ona/automations/configure-automations#enable-and-disable). # Plans and limits Source: https://ona.com/docs/ona/automations/plans-and-limits Automation limits by organization plan Automations are available on Core and Enterprise plans. Enterprise organizations must have [Ona Intelligence](https://ona.com/contact/sales) enabled to access Automations. To query Ona Intelligence usage programmatically, see the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api). Each plan has limits on the number of Automations, concurrent actions, and available features. ## Limits by plan | Feature | Core | Enterprise | | ---------------------------- | --------------------- | --------------------- | | Total Automations | 50 | Unlimited | | Max parallel actions | 10 | 25 | | Max total actions | 50 | 100 | | GitHub pull request triggers | | | | Webhook event sources | - | | | General Access sharing | | | | Share with individual users | - | | | Share with groups | - | | Enterprise action limits are the current system-wide ceiling, not a plan cap. [Contact sales](https://ona.com/contact/sales) if you need higher limits. ## Automation count Each organization can create up to the limit for its plan. Automations marked for deletion do not count toward the limit. When you reach the limit, creating a new Automation returns an error. Delete unused Automations or [upgrade your plan](#upgrading) to increase the limit. ## Action limits Action limits control how many repositories an Automation processes per run: * **Max parallel**: simultaneous actions running at once * **Max total**: total actions per Automation run Both values must be positive integers (1 or greater). These limits are set per Automation in the [guardrails configuration](/docs/ona/automations/guardrails). On Core plans, the values cannot exceed the caps listed above. Enterprise plans can use any value up to the current system-wide ceiling (25 parallel, 100 total). [Contact sales](https://ona.com/contact/sales) for higher limits. ## Webhooks Webhook-based [pull request triggers](/docs/ona/automations/triggers/pullrequest) are available on the Enterprise plan. Core organizations can use GitHub.com pull request triggers through the [GitHub integration](/docs/ona/integrations/configure-github). ## Sharing Both plans support sharing Automations with everyone in the organization via [General Access](/docs/ona/automations/sharing-automations). Sharing with individual users and [groups](/docs/ona/organizations/groups) requires the Enterprise plan. ## Subscription management To manage your Core subscription, visit **Settings > Billing**. For Enterprise features, [contact sales](https://ona.com/contact/sales). # Report step Source: https://ona.com/docs/ona/automations/report-step Extract structured data from Automation executions Report steps extract structured data from an Automation execution. Define the outputs you want (test coverage, dependency counts, build status), and the agent extracts them using prompts or shell commands. Results appear in a table with CSV export. Use Report steps when you need to compare metrics across repositories or track values over time. Report results and the performance chart only appear for executions with more than one action. Single-action executions skip the report view. ## How it works 1. Earlier steps in the Automation do the work (run tests, scan dependencies, build). 2. The Report step defines **outputs** with typed schemas. 3. For each output, the agent extracts the value using a prompt or command. 4. Results display in a table on the execution summary page. ## Add a Report step In the Automation editor, click **+** at the bottom of the step list and select **Report**. Automation workflow with a Report step showing three outputs ## Configure outputs Each output defines one value to extract. A Report step requires at least one output. Report step editor with output configuration ### Output fields | Field | Required | Description | | ----------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- | | **Title** | Yes | Display name shown in the results table (max 200 characters) | | **Key** | Yes | Identifier in `snake_case` format, used for CSV export and the `add_agent_execution_result` tool (max 50 characters) | | **Value type** | Yes | Data type for the output value | | **Extraction method** | Yes | How to extract the value: prompt or command | | **Acceptance criteria** | No | CEL expression that validates the extracted value | ### Value types | Type | Constraints | Results display | | ----------- | ----------------------- | ------------------------------------------------------------------- | | **String** | Optional regex pattern | Plain text | | **Integer** | Optional min/max bounds | Number, or progress bar when min and max are set | | **Float** | Optional min/max bounds | Number (2 decimal places), or progress bar when min and max are set | | **Boolean** | None | Green check or red cross badge | When you set both min and max on a numeric type, the results table shows a color-coded progress bar: green above 80%, orange 50-80%, red below 50%. ### Extraction methods **Prompt**: the agent reads the execution context and extracts the value based on your instructions. Use for values that require interpretation. ``` Extract the overall test coverage percentage from the test output ``` **Command**: a shell command that outputs the raw value. Use for values you can parse deterministically. ```bash theme={null} grep -oP '\d+ passed' test-results.txt | grep -oP '\d+' ``` ### Acceptance criteria Optional [CEL expressions](https://github.com/google/cel-spec) that validate extracted values. The expression receives one variable (`value`) and must return a boolean. Examples: | Expression | Validates | | ------------------------------------- | ------------------------------------- | | `value >= 80` | Coverage is at least 80% | | `value > 0` | At least one test passed | | `value == true` | Build succeeded | | `value.matches("^v[0-9]+\\.[0-9]+$")` | Version string matches semver pattern | ## View results After execution, the results table appears on the execution summary page. Each row is one action (repository), and columns are the output keys you defined. The report table and performance chart only appear for executions with multiple actions. If your Automation targets a single project or repository, the report step runs but results are not displayed in the summary view. Click **Export CSV** to download the results as a spreadsheet for further analysis or reporting. ## Example: test coverage across repositories This Automation runs tests across multiple repositories and reports coverage metrics. **Step 1 (Prompt):** ``` Run the test suite with coverage enabled. Use the project's existing test command. Save the output to test-results.txt. ``` **Step 2 (Report):** | Output | Type | Extraction | Acceptance criteria | | ------------- | ---------------- | --------------------------------------------------------------------------- | ------------------- | | Test Coverage | Float (0-100) | Prompt: "Extract the overall test coverage percentage from the test output" | `value >= 80` | | Tests Passed | Integer (min: 0) | Command: `grep -oP '\d+ passed' test-results.txt \| grep -oP '\d+'` | `value > 0` | | Build Success | Boolean | Prompt: "Did the build complete successfully? Answer true or false." | None | Schedule this on a weekly trigger to track coverage trends. Export CSV results to build dashboards or feed into other tools. ## Next steps * [Create an Automation](/docs/ona/automations/configure-automations) * [Run an Automation](/docs/ona/automations/running-automations) * [Automations in practice](/docs/ona/automations/automations-in-practice) # Running an Automation Source: https://ona.com/docs/ona/automations/running-automations Execute and monitor Automations Running an Automation creates a run and one or more actions underneath it. Each action represents work on a specific target, such as a repository or project selected by the trigger configuration. Use this page when you want to start an Automation manually, monitor progress, inspect failures, or review what the agent actually did. ## What a run contains * **Run**: the top-level execution record * **Actions**: per-target executions created under that run * **Execution details**: action status, step progress, failures, and, when available, the full agent session for an action ## Start an Automation Disabled Automations cannot be started. The **Run** button is hidden and triggers are ignored while an Automation is disabled. [Re-enable it](/docs/ona/automations/configure-automations#enable-and-disable) first. 1. Open the Automation (or use the three-dot menu from the list). 2. Click **Run** to start immediately with the Automation's configured targets when it has no parameters. To change the targets for one execution, click the arrow next to **Run**, then select **Run with options**. Clicking **Run** opens the same dialog automatically when the Automation has no usable configured targets, uses an event-derived context, or references run parameters. The dialog prevents the run from starting until it has at least one accessible project or a complete repository target. Projects you cannot access are removed from the execution target list. ## Run with parameters When an Automation references parameters, **Run with options** lists every detected parameter. Enter a non-empty value for each one before clicking **Run**. Ona also validates required parameters on the server, so a manual run cannot start with unresolved templates through another client. A parameter named `ticket_id`, for example, replaces `{{ .Parameters.ticket_id }}` in templated commands, prompts, and pull request fields. An Automation can reference up to 10 parameters. ```text theme={null} Fix {{ .Parameters.ticket_id }} in {{ .Parameters.repository }}. ``` For this example, the dialog requires values for both `ticket_id` and `repository`. Spaces alone do not count as a value. To define parameters in the Automation editor, see [Add parameters to manual runs](/docs/ona/automations/configure-automations#add-parameters-to-manual-runs). Do not use parameters for sensitive values. Configure [service account secrets](/docs/ona/organizations/service-accounts#secrets) instead. ## Run with parameters through the API Call `WorkflowService/StartWorkflow` with a [personal access token](/docs/ona/integrations/personal-access-token) or [service account token](/docs/ona/organizations/service-accounts). Put each template parameter in the `parameters` object. ```bash theme={null} export ONA_API_URL="https://app.gitpod.io" export GITPOD_API_KEY="" curl "$ONA_API_URL/api/gitpod.v1.WorkflowService/StartWorkflow" \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "workflowId": "", "parameters": { "ticket_id": "ONA-123", "repository": "gitpod-io/gitpod-next" } }' ``` This request uses the Automation's configured manual context. If the Automation has no manual trigger, Ona uses its scheduled trigger context. To choose targets for one run, add `contextOverride`: ```json theme={null} { "workflowId": "", "contextOverride": { "projects": { "projectIds": [""] } }, "parameters": { "ticket_id": "ONA-123" } } ``` The API applies the same rules as the UI: * Every parameter referenced by a manual run must have a non-empty value. Spaces alone do not count. * Parameter names must match `^[a-zA-Z_][a-zA-Z0-9_]*$`. * A request can contain up to 10 parameters. * `contextOverride` supports project, repository, and agent contexts. An event-derived `fromTrigger` context is not valid for a manual run. * The caller must have access to every target in `contextOverride`. If your organization uses a custom domain, set `ONA_API_URL` to that management-plane origin and use a token created on the same domain. ## Monitor progress The run details page shows real-time execution status. **Action statuses:** * **Pending**: queued, waiting to start * **Running**: currently executing * **Done**: finished successfully * **Failed**: finished with errors * **Stopped**: canceled before completion Click any action to inspect its steps, current state, and, when available, the full agent session. Action logs ## What to look for while monitoring When a run is active, focus on: * whether actions are starting as expected * which step a failed action stopped on * whether failures are isolated to one target or systemic across many targets If many actions fail in the same place, the problem is usually in the Automation configuration, repository setup, or shared credentials. If only one action fails, the issue is usually specific to that target. ## Cancel execution * **Single action**: three-dot menu > **Cancel** * **Entire run**: click **Cancel** on the run details page Running actions stop immediately. Pending actions are skipped. ## Review results After completion: * View execution summary (completed/failed/canceled actions, time) * Click individual actions to review execution details * Check your SCM for pull requests created by the Automation ## Execution history View past runs from the Automation's **Execution History** section. Each run retains action status and execution details for later inspection. For Enterprise organizations, agent details are available to anyone who can view the run. Codex runs show the effective model and reasoning effort; legacy Ona Agent runs show **Ona Agent**. * **Organization admins** and **Automation admins** also see intelligence usage for each run. * **Billing Viewers** see intelligence usage only for automation runs they already have permission to view. * Other scoped organization roles do not see intelligence usage unless another assigned role grants one of these permissions. After a run finishes and its final usage has been calculated, managed usage is shown in credits and bring-your-own-key usage is shown in your organization's billing currency. If any bring-your-own-key prices are missing, the run shows its token usage instead of a partial cost. An organization admin can add model pricing under **Cost & Budgets**. Use history to compare configuration changes over time or to confirm whether a failure started after a workflow, secret, or trigger change. ## Common follow-ups After reviewing a run, the next step is usually one of: * update the Automation configuration and run it again * fix repository setup or secrets for the failing target * tighten [guardrails](/docs/ona/automations/guardrails) or switch to a [service account](/docs/ona/organizations/service-accounts) * move from manual testing to a [time-based](/docs/ona/automations/triggers/timebased) or [pull request](/docs/ona/automations/triggers/pullrequest) trigger ## Next steps * [Guardrails](/docs/ona/automations/guardrails) * [Service accounts](/docs/ona/organizations/service-accounts) * [Troubleshooting](/docs/ona/automations/troubleshooting) # Sharing Automations Source: https://ona.com/docs/ona/automations/sharing-automations Share Automations with individual users, groups, or your entire organization Share Automations so team members can run pre-built Automations without needing to create their own. Only **organization admins** can share Automations. Having the Admin role on a single Automation is not enough. To give a team admin access to **all** Automations in the organization, assign the [Automations Admin](/docs/ona/organizations/organization-roles) role to their group instead of sharing Automations individually. Sharing capabilities depend on your plan: | Sharing method | Core | Enterprise | | -------------------------------- | --------------------- | --------------------- | | General Access (everyone in org) | | | | Individual users | - | | | Groups | - | | ## Roles When sharing an Automation, you assign a role that controls what the recipient can do: | Role | Permissions | | ------------ | --------------------------------------------------------------- | | **Admin** | Full control: edit, delete, share, run, and view all executions | | **Executor** | Run the Automation and view their own executions | | **Viewer** | View the Automation and execution history (read-only) | ## Share with everyone (General Access) Available on Core and Enterprise plans. Use the **General Access** toggle to share an Automation with all members of your organization: 1. Open the Automation and click **Share**. 2. In the **General Access** section, select **Everyone in **. All organization members receive Executor access. Toggle back to **Only groups and users with access** to revoke org-wide access. ## Share with individual users Available on the [Enterprise plan](/docs/ona/automations/plans-and-limits). 1. Open the Automation and click **Share**. 2. Search for and select users to add. 3. Choose a role for each user. Share Automation dialog with user and group selection ## Share with groups Available on the [Enterprise plan](/docs/ona/automations/plans-and-limits). [Custom groups](/docs/ona/organizations/groups) must be configured first. 1. Open the Automation and click **Share**. 2. Select groups to add. 3. Choose a role for the group. ## Remove access 1. Click **Share**, find the user or group, click the role dropdown, and select **Remove access**. Role dropdown showing Remove access option Removed users and groups immediately lose access. Past executions remain visible to admins. ## For Automations shared with users Automations that are shared with a user appear in their **Automations** list. Depending on their role, they can run or view them on any project or repository you have access to. Shared Automation with Run button Automations run under **your identity**. Commits and PRs are attributed to your account, using your SCM permissions. ## Next steps * [Create Automations](/docs/ona/automations/configure-automations) * [Manage groups](/docs/ona/organizations/groups) * [Plans and limits](/docs/ona/automations/plans-and-limits) * [Troubleshooting](/docs/ona/automations/troubleshooting) # Manual triggers Source: https://ona.com/docs/ona/automations/triggers/manual Run Automations on demand Manual triggers run when you explicitly start them. Use them for one-time migrations, testing Automations before scheduling, or changes that need human judgment on timing. They are the safest way to develop a new Automation because you control exactly when it starts and can review the results before making it recurring or event-driven. ## When to use manual triggers Manual triggers are a good fit for: * trying a new Automation on a small set of targets * maintenance work you want to supervise closely * one-off repository sweeps * workflows that should only run after a human decision ## Configuration Manual trigger configuration ### Runs on #### Projects (recommended) Select one or more [projects](/docs/ona/projects/overview). The Automation runs on all repositories within them. Best for repetitive tasks on known repositories. #### Repositories Use a search query to filter repositories. Best for large-scale migrations across many targets. | Query | Matches | | ----------- | ------------------------------------------- | | `backend` | Repositories with "backend" in name | | `frontend-` | Repositories starting with "frontend-" | | `myorg/` | All repositories under "myorg" organization | Partial matches work across owner and repository names. **Search syntax:** [GitHub](https://docs.github.com/en/search-github/searching-on-github/searching-for-repositories) | [GitLab](https://docs.gitlab.com/ee/user/search/) ## Choosing projects vs repository queries * **Projects** are best when you already know the exact repositories and want them to use project-level configuration. * **Repository queries** are best when you want to sweep a broader set of repositories without manually listing them. If the workflow depends on project-specific configuration and access, prefer projects. ## Running 1. Navigate to **Automations** 2. Click your Automation 3. Click **Run** to use its configured targets, or use the arrow next to **Run** and select **Run with options** to change targets or enter parameter values. If the Automation references parameters or has no usable configured targets, clicking **Run** opens **Run with options** automatically. You must provide every parameter and at least one valid target before the execution can start. The Automation creates actions for the selected targets, which you can then monitor from the execution view. See [Running an Automation](/docs/ona/automations/running-automations) for parameter syntax and target validation behavior. ## Review after the run After a manual run, check: * which targets were selected * whether the right repositories were included * whether the actions produced the expected pull requests, comments, or reports If the run looks good, the next step is often to convert the same workflow into a [time-based trigger](/docs/ona/automations/triggers/timebased) or a [pull request trigger](/docs/ona/automations/triggers/pullrequest). ## Next steps * [Run an Automation](/docs/ona/automations/running-automations) * [Pull request triggers](/docs/ona/automations/triggers/pullrequest) * [Time-based triggers](/docs/ona/automations/triggers/timebased) # Pull request triggers Source: https://ona.com/docs/ona/automations/triggers/pullrequest Trigger Automations from pull request events Pull request triggers run Automations when PR events occur: code changes, reviews, merges. Use them for automated code review, security scanning, documentation updates, and compliance checks. They support **GitHub.com** through the GitHub App, and **GitLab** and **Bitbucket Cloud** through webhooks. Use a [service account](/docs/ona/organizations/service-accounts) to separate Automation activity from human work. ## Configuration Pull request trigger configuration ### Event source Pull request triggers need an event source that delivers PR events from your Git provider to Ona. There are two options: | Source | When to use | | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **[GitHub](/docs/ona/integrations/configure-github)** | You use GitHub.com and have the [GitHub integration](/docs/ona/integrations/configure-github) enabled. No extra setup is required. Ona receives PR events through the App. | | **[Webhook](/docs/ona/automations/webhooks)** | You use GitLab or Bitbucket Cloud, or you prefer not to enable the GitHub integration. You create a webhook in Ona and register it in your Git provider. | #### GitHub If your organization has the [GitHub integration](/docs/ona/integrations/configure-github) enabled, select **GitHub** as the event source. Ona receives PR events directly through the App. When your Ona organization connects more than one GitHub organization, each event source includes the GitHub organization name, such as `github.com/acme`. Select the organization that owns the repositories this Automation should monitor. #### Webhook If your organization has [webhooks](/docs/ona/automations/webhooks) configured, a dropdown appears instead, letting you select an existing webhook or configure a new one. ### Runs on * **Projects** (recommended): select projects. The Automation monitors all repositories within them. * **Repositories**: use a search query to filter specific repositories. ### Triggers on PR | Event | When it fires | | ---------------- | ---------------------------- | | Opened | New PR created | | Updated | New commits pushed | | Ready for review | Draft marked ready | | Review requested | Reviewer assigned for review | | Approved | Reviewer approves | | Merged | PR merged | | Closed | PR closed without merge | **Common combinations:** Opened + Updated (check every change), Ready for review (analysis before human review), Approved (final validation) ## Next steps * [GitHub](/docs/ona/integrations/configure-github): enable the GitHub integration for webhook-free PR triggers * [Webhooks](/docs/ona/automations/webhooks): create and manage webhook endpoints * [Run an Automation](/docs/ona/automations/running-automations) * [Manual triggers](/docs/ona/automations/triggers/manual) * [Time-based triggers](/docs/ona/automations/triggers/timebased) # Time-based triggers Source: https://ona.com/docs/ona/automations/triggers/timebased Schedule Automations on a recurring basis Time-based triggers run Automations on a schedule: dependency updates, security scans, compliance checks, nightly builds. Use them when the work should happen predictably without someone clicking **Run** each time. ## Good fits for scheduled runs * nightly validation and cleanup * weekly dependency maintenance * regular backlog triage * periodic reporting or compliance checks ## Configuration Scheduled trigger configuration ### Runs on * **Projects** (recommended): select projects. Runs on all repositories within them. * **Repositories**: use a search query (see [manual triggers](/docs/ona/automations/triggers/manual#repositories) for examples). ### Schedule | Frequency | Options | | --------- | ----------------------------------------- | | Hourly | Minute (0-59) | | Daily | Hour, minute. Runs every day. | | Weekdays | Hour, minute. Runs Monday through Friday. | | Weekly | Day of week, hour, minute | | Monthly | Day of month, hour, minute | **Examples:** * Weekly dependency updates: every Monday at 2 AM UTC * Weekday backlog triage: every weekday at 9 AM UTC * Nightly security scans: every day at 1 AM UTC * Monthly compliance: first day of the month at midnight UTC ## Timezone Schedules are evaluated in UTC. Weekday schedules run Monday through Friday in UTC, so keep timezone differences in mind when choosing times for teams that work in other timezones. ## Scheduling tips * Run outside peak working hours when the workflow is resource-intensive. * Leave enough time for one run to finish before the next one begins. * Start with a narrower target set before scheduling the Automation broadly. * Pair scheduled runs with [service accounts](/docs/ona/organizations/service-accounts) when you want stable credentials independent of an individual user. ## After you enable the trigger Once saved, the Automation waits for the next matching schedule window. Review the first few runs in [Execution History](/docs/ona/automations/running-automations#execution-history) to confirm the cadence and targets are correct. ## Next steps * [Run an Automation](/docs/ona/automations/running-automations) * [Manual triggers](/docs/ona/automations/triggers/manual) * [Pull request triggers](/docs/ona/automations/triggers/pullrequest) # Troubleshooting automations Source: https://ona.com/docs/ona/automations/troubleshooting Common Automation issues and solutions ## Debugging failed executions 1. Open the failed execution from the Automation details page. 2. Review the **Action session** for error messages. 3. Check which step failed and review output. ## Trigger issues ### Manual triggers not starting * Verify account has access to target repositories/projects. * Check repositories match your search query. * Verify permissions to run Automations. ### Pull request triggers not firing * Verify webhook configured correctly in GitHub/GitLab. * Check webhook secret matches Automation settings. * Confirm PR events are selected in webhook config. See [Pull request triggers](/docs/ona/automations/triggers/pullrequest). ### Time-based triggers not running * Verify schedule is correct (schedules run on UTC). * Check the Automation is not paused or disabled. * Confirm service account has repository access. See [Time-based triggers](/docs/ona/automations/triggers/timebased). ## Repository access errors "Repository not found" or "access denied": | Account type | Check | | --------------- | ------------------------------------------------ | | User | SCM access? PAT scopes? Repo still exists? | | Service account | Git auth configured? PAT valid? Required scopes? | See [Service accounts](/docs/ona/organizations/service-accounts). ## Permission errors "Permission denied" or "Insufficient permissions": * Projects must be shared with "all members" for Automations to access them. * Verify service account is organization member with SCM permissions. See [Project sharing](/docs/ona/projects/project-sharing). ## Sharing issues ### Cannot see the Automations page Core and Enterprise organization members can open Automations even when no Automation has been shared with them. Members who cannot create Automations and do not have shared access see the education screen, where they can find an Organization Admin. If the Automations link is missing, check the organization's [plan](/docs/ona/automations/plans-and-limits). ### "Project not found" on shared Automation The Automation targets a project you do not have access to. Ask admin to share the project, or select a different target. ### Git auth errors on shared Automations Shared Automations run under your identity. Re-authenticate at [app.ona.com](https://app.ona.com) > **Settings** > **Git Providers**. ### Cannot see other users' executions Expected. Executors only see their own executions. Admins see all. ## Plan limits ### "Your plan allows a maximum of N automations" Your organization has reached the maximum number of Automations for its plan. Delete unused Automations or upgrade your plan. See [Plans and limits](/docs/ona/automations/plans-and-limits). ### "The maximum concurrent actions limit cannot exceed N on your current plan" The max parallel value you set exceeds your plan's cap. Reduce the value or upgrade your plan. See [Guardrails](/docs/ona/automations/guardrails) for per-plan limits. ### "The maximum total actions limit cannot exceed N on your current plan" The max total value you set exceeds your plan's cap. Reduce the value or upgrade your plan. See [Guardrails](/docs/ona/automations/guardrails) for per-plan limits. ### "Organizations on the ... tier cannot create webhooks" Webhook creation is restricted to the Enterprise plan. Non-enterprise organizations can use manual and time-based triggers. See [Pull request triggers](/docs/ona/automations/triggers/pullrequest). ## Getting help Contact your Ona account manager with: * Automation name/ID and execution ID. * Error messages from Action session. * Steps to reproduce. # Webhooks Source: https://ona.com/docs/ona/automations/webhooks Receive SCM events to trigger Automations Webhooks are standalone endpoints that receive events from your Git provider (GitHub, GitLab, or Bitbucket Cloud). Once created, a webhook can be shared across multiple Automations. You configure the connection to your SCM once and reuse it wherever you need pull request triggers. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. ## How webhooks work 1. You create a webhook in Ona, choosing a provider (GitHub, GitLab, or Bitbucket Cloud) and a scope (repository or organization). The scope can be configured later, but the webhook won't process events until one is set. 2. Ona generates a **payload URL** and a **secret token**. 3. You register the payload URL and secret in your Git provider's webhook settings. 4. When PR events occur, the Git provider sends a signed payload to Ona. 5. Ona verifies the signature, matches the event to bound Automations, and triggers them. A single webhook can be bound to multiple Automations. ## Scope types | Type | Description | | ---------------- | ------------------------------------------------------------------------------------------------------------ | | **Repository** | Scoped to one or more specific repositories. Events from other repositories are ignored. | | **Organization** | Scoped to an entire SCM organization or group. Events from any repository in that organization are accepted. | Repository-scoped webhooks support up to 100 repositories per webhook. ## Required permissions Only **organization admins** can create, update, and delete webhooks. The Automations Admin role does not currently grant webhook management permissions. Organization members can view webhooks but cannot modify them. ## Creating a webhook ### Dashboard 1. Go to **Automations** and click **Webhooks** in the top bar. Webhooks side panel 2. Click **+ Webhook** to open the creation dialog. 3. Select the **location** (GitHub, GitLab, or Bitbucket Cloud). 4. Choose the **type** (Organization or Repository). 5. Enter a **name** for the webhook. 6. Click **Create Webhook**. Configure new webhook dialog After creation, Ona shows the **webhook configuration** dialog with the **payload URL** and **secret token**. Select the scope: the specific repositories or organization this webhook should accept events from. Webhook setup with payload URL, secret, and scope Scope configuration is optional during creation. Set it later from the webhook details panel. The webhook shows a "Setup incomplete" badge until a scope is configured. ### CLI ```bash theme={null} # Repository webhook for a single repo ona webhook create \ --name "My Webhook" \ --type repository \ --scope "owner/repo" \ --provider github # Repository webhook for multiple repos ona webhook create \ --name "Multi Webhook" \ --type repository \ --scope "owner/repo1" \ --scope "owner/repo2" \ --provider github # Organization webhook ona webhook create \ --name "Org Webhook" \ --type organization \ --organization-scope "my-org" \ --provider gitlab ``` The CLI returns the webhook ID and payload URL but not the secret. To retrieve the secret token, run: ```bash theme={null} ona webhook secret get ``` Once you have both values, register them in your Git provider as described in the next section. ## Registering the webhook in your Git provider After creating the webhook in Ona, register it in your Git provider so events are delivered. ### GitHub 1. Go to `https://github.com///settings/hooks` and click **Add webhook**. 2. Enter the **Payload URL** from Ona. 3. Enter the **Secret** from Ona. 4. Set **Content type** to `application/json`. 5. Select **Let me select individual events** and check **Pull requests**. 6. Click **Add webhook**. 1. Go to `https://github.com/organizations//settings/hooks` and click **Add webhook**. 2. Enter the **Payload URL** from Ona. 3. Enter the **Secret** from Ona. 4. Set **Content type** to `application/json`. 5. Select **Let me select individual events** and check **Pull requests**. 6. Click **Add webhook**. [GitHub webhook documentation](https://docs.github.com/en/webhooks/using-webhooks/creating-webhooks) ### GitLab 1. Go to `https://gitlab.com///-/hooks` and click **Add new webhook**. 2. Enter the **URL** (payload URL from Ona). 3. Enter the **Secret token** from Ona. 4. Check **Merge request events**. 5. Click **Add webhook**. 1. Go to `https://gitlab.com/groups//-/hooks` and click **Add new webhook**. 2. Enter the **URL** (payload URL from Ona). 3. Enter the **Secret token** from Ona. 4. Check **Merge request events**. 5. Click **Add webhook**. [GitLab webhook documentation](https://docs.gitlab.com/ee/user/project/integrations/webhooks.html) ### Bitbucket Cloud 1. Go to `https://bitbucket.org///admin/webhooks` and click **Add webhook**. 2. Enter the **URL** (payload URL from Ona). 3. Enter the **Secret** from Ona. 4. Under **Triggers**, select **Choose from a full list of triggers** and check **Pull Request: Created**, **Updated**, **Approved**, **Merged**, **Declined**. 5. Click **Save**. 1. Go to `https://bitbucket.org//workspace/settings/webhooks` and click **Add webhook**. 2. Enter the **URL** (payload URL from Ona). 3. Enter the **Secret** from Ona. 4. Under **Triggers**, select **Choose from a full list of triggers** and check **Pull Request: Created**, **Updated**, **Approved**, **Merged**, **Declined**. 5. Click **Save**. [Bitbucket webhook documentation](https://support.atlassian.com/bitbucket-cloud/docs/manage-webhooks/) ## Managing webhooks ### Viewing webhook details Click any webhook in the list to open its details panel. The panel shows: * Webhook name * Payload URL and secret token (copyable) * Provider and scope configuration Webhook details panel ### Updating scope Change the repositories or organization a webhook is scoped to at any time from the details panel. The provider and type cannot be changed after creation. Create a new webhook instead. ### Rotating the secret If a webhook secret is compromised, rotate it from the details panel. After rotation: 1. Copy the new secret from Ona. 2. Update the secret in your Git provider's webhook settings. The old secret is immediately invalidated. ### Deleting a webhook When you delete a webhook: * Any Automations bound to it have their pull request triggers converted to **manual** triggers. They stop receiving PR events but can still be run manually. * Running executions continue until they complete. * The webhook is removed from Ona but **not** from your Git provider. Remove it from your provider's settings separately to stop sending events. ## Binding webhooks to Automations When configuring a [pull request trigger](/docs/ona/automations/triggers/pullrequest) on an Automation, select a webhook from the dropdown or create a new one inline from the trigger configuration. Multiple Automations can share the same webhook. Each Automation independently defines which PR events it responds to (opened, updated, merged, etc.). ## Security Webhooks authenticate using HMAC signature verification. When your Git provider sends an event, it signs the payload using the shared secret. Ona verifies the signature before processing the event. Events with invalid signatures are rejected. Keep your webhook secret secure. If compromised, [rotate it](#rotating-the-secret) immediately. ## Next steps * [Pull request triggers](/docs/ona/automations/triggers/pullrequest): configure which PR events trigger your Automations * [Creating Automations](/docs/ona/automations/configure-automations): set up Automations that use webhooks * [Plans and limits](/docs/ona/automations/plans-and-limits): webhook availability by plan # Bash commands Source: https://ona.com/docs/ona/bash-commands Run bash commands in sessions using the ! prefix Prefix any command with `!` to run it immediately and share the output with the agent. The output becomes part of the session context, so the agent can reference it in responses. ``` !git status !npm test !cat src/config.js ``` Terminal showing bash commands executed with the ! prefix, displaying command output inline in the session ## What happens when you use `!` `!` is the fastest way to bring shell output into the conversation without asking the agent to decide which command to run. When you run a command this way: * the output becomes part of the chat context for the current session * the command result is shown directly in the session * you can immediately ask follow-up questions about the result ## When to use ! commands Use `!` when you want to share specific output with the agent: * **Share errors for debugging**: `!npm test` then ask "why is this failing?" * **Provide context**: `!cat package.json` before asking about dependencies * **Verify state**: `!git branch` before asking about branching strategy For complex multi-step operations, code changes, or open-ended analysis, ask the agent directly and let it run commands as needed. ## Good fits vs bad fits Good fits: * a single diagnostic command * a one-off log or file dump * a test run whose output you want the agent to interpret Less good fits: * long investigative workflows * commands that mutate the repo in ways you want the agent to manage * repeated shell sequences better handled by the agent itself or by an Automation ## Tips * Use short, targeted commands so the output stays readable in chat. * Prefer `!git status` or `!pytest -q` over huge recursive dumps. * If the output is noisy, run a narrower command and ask a more specific follow-up question. # Set up your first environment Source: https://ona.com/docs/ona/configuration/devcontainer/getting-started Create a Dev Container so your environments and agents have everything they need. Add a Dev Container to your repository so every environment, whether started by a teammate or an agent, launches with the right runtimes, tools, and services already running. * **Agents** get a reproducible environment to execute commands, run tests, and iterate * **New team members** start an environment and immediately have everything they need * **Everyone** works in the same setup, no more "it works on my machine" A Dev Container can include language runtimes, databases, tools, editor extensions, environment variables, and startup tasks. ## Create your first Dev Container Create a `.devcontainer/devcontainer.json` file in your repository: ```json theme={null} { "name": "My Project", "image": "mcr.microsoft.com/devcontainers/javascript-node:20", "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { "moby": false } }, "customizations": { "vscode": { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode" ] } }, "postCreateCommand": "npm install" } ``` This gives you: * Node.js 20 with npm * Docker available inside the environment * ESLint and Prettier extensions * Dependencies installed automatically Start an environment from your repository. Ona builds the container and you're ready to code. ## Run tasks on startup For more control over startup behavior, use [Tasks & Services](/docs/ona/configuration/tasks-and-services/overview): ```yaml theme={null} # .ona/config.yaml tasks: install: name: Install dependencies command: npm install triggeredBy: - postDevcontainerStart services: database: name: PostgreSQL commands: start: docker run --rm -t --name database -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:15 ready: docker exec database pg_isready stop: docker stop database triggeredBy: - postEnvironmentStart ``` Now every environment starts with dependencies installed and a database running. ## Verify it works Once your environment starts, verify the setup. These examples assume a Node.js project. Substitute your own project's commands: ```bash theme={null} # Check your runtime node --version # Run your tests (if your project has a test script) npm test # Start your dev server (if your project has a dev script) npm run dev ``` If your project's commands work inside the environment, your Dev Container is ready. Agents will be able to run the same commands reliably. ## Next steps * [Optimize startup times](/docs/ona/configuration/devcontainer/optimizing-startup-times) with prebuilds and image caching * [Dev Container reference](/docs/ona/configuration/devcontainer/overview) for advanced configuration: multi-container setups, private images, elevated privileges * [Teach agents your codebase](/docs/ona/agents-md) so they understand your conventions # Optimize startup times Source: https://ona.com/docs/ona/configuration/devcontainer/optimizing-startup-times Fast startup times enable humans and agents to work effectively and autonomously across multiple tasks in parallel. Optimized environments start in 1-3 minutes. Without optimization, startup can take 10+ minutes. This page covers the strategies that close that gap. ## Optimization strategies ### Use prebuilds [Prebuilds](/docs/ona/projects/prebuilds) run your environment setup ahead of time: container builds, dependency installation, and startup tasks. When an environment starts, it loads from a prebuild snapshot instead of running setup from scratch. This is the single biggest optimization. Configure prebuilds to run on a daily schedule before your team or agents start work. You can also run a prebuild manually after important dependency or setup changes. ### Enable Dev Container image caching For runners in your VPC, enable image caching to avoid rebuilding containers: * **[AWS runners](/docs/ona/runners/devcontainer-image-cache#aws-runners)**: Caches built Dev Container images automatically * **[GCP runners](/docs/ona/runners/devcontainer-image-cache#gcp-runners)**: Supports image caching through Artifact Registry [Ona Cloud](/docs/ona/runners/ona-cloud) includes image caching by default. ### Let Ona maintain base snapshots on AWS runners For eligible Enterprise AWS runners, Ona automatically maintains [base snapshots](/docs/ona/runners/aws/base-snapshots) from the organization default image. Base snapshots preload container image layers and shared startup assets before an environment starts. No project or developer configuration is required. Base snapshots complement prebuilds and the Dev Container image cache. A project prebuild takes precedence when one is available. ### Optimize your Dockerfile Structure your Dockerfile for caching efficiency: * **Put stable dependencies first**: System packages, build tools, and runtimes that rarely change should be early in the Dockerfile. * **Put volatile dependencies last**: Application dependencies that change frequently go at the end. * **Use prebuilt base images**: Push your base image to a registry and reference it in `devcontainer.json`. ### Use tasks for dynamic setup For setup that must happen at runtime (database seeding, environment-specific config), use [Tasks](/docs/ona/configuration/tasks-and-services/overview) rather than baking everything into the image. ## Use one environment per task Create a fresh environment for each piece of work rather than reusing environments across tasks. This matches how agents operate: 1. Agent receives a task 2. Agent starts a clean environment 3. Agent completes the work and creates a PR 4. Environment is discarded This isolation gives you: * **No state conflicts**: Each task gets a clean slate * **Parallel execution**: Multiple agents work simultaneously without interference * **Mistakes are free**: If something goes wrong, discard the environment and start fresh With the optimizations above, startup stays under a few minutes. ## Measure startup time Track these metrics to identify bottlenecks: * **Container build time**: How long does the Dev Container image take to build? * **Dependency installation**: How long do startup tasks take to run? * **Prebuild freshness**: Are prebuilds running often enough to stay current? If environments take more than 3 minutes to start, check your prebuild configuration first. # Container configuration Source: https://ona.com/docs/ona/configuration/devcontainer/overview Standardize development environments across your team with Dev Container configuration. Ona fully supports [Development Containers](https://containers.dev/). Define your setup in a `devcontainer.json` file to get standardized, version-controlled environments with consistent tooling across your team, whether single-container or multi-container, with VS Code and JetBrains support. For how environments and Dev Containers fit into the broader platform, see [Core Components](/docs/ona/understanding/core-components#environments). ## Configuration ### File Location Place your `devcontainer.json` file in one of these standard locations: * `.devcontainer/devcontainer.json` * `.devcontainer.json` ### Basic Configuration Example ```json theme={null} { "name": "My Project", "image": "mcr.microsoft.com/devcontainers/universal:4.0.1-noble", "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { "moby": false } }, "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"], "settings": { "editor.formatOnSave": true } }, "jetbrains": { "plugins": ["com.wix.eslint", "intellij.prettierJS"] } }, "forwardPorts": [3000, 8080] } ``` This configuration: * Uses the Universal image with common languages and tools pre-installed (Node.js, Python, Go, Java, and more) * Adds Docker-in-Docker support * Includes ESLint and Prettier VS Code extensions * Installs the ESLint & PrettierJS plugin for JetBrains IDEs * Configures auto-formatting on save * Declares ports 3000 and 8080 for [IDE-managed forwarding](#forward-ports) ### Forward ports Use `forwardPorts` in `devcontainer.json` to tell supported IDEs which ports to forward from the Dev Container to `localhost` on your local machine. As the port-forwarding is performed by your IDE the ports are not accessible to anyone else. If you need a shareable URL or want to access a port in the environment without using an IDE, use Ona [Port sharing](https://ona.com/docs/ona/integrations/ports#port-sharing). See the official [Dev Container JSON reference](https://containers.dev/implementors/json_reference/#general-properties) for more details about port-related properties. ## Multiple Dev Container configurations You can manage multiple Dev Container configurations using Ona projects. This allows you to define different environments for: * Different branches or repositories * Various development scenarios * Specialized tasks requiring specific tools ## Known limitations When using Dev Containers with Ona, be aware of these limitations: * Conflicting features can cause build failures (Ona will display an error message) * Some Dev Container commands might behave differently in Ona's environment * When build or startup errors occur, [recovery mode](#recovery-mode) is engaged, requiring manual intervention ## Recommended images Microsoft provides well-maintained Dev Container base images for popular development stacks: * `mcr.microsoft.com/devcontainers/universal:4.0.1-noble` - Full-featured image with common languages and tools * `mcr.microsoft.com/devcontainers/javascript-node` - Node.js development * `mcr.microsoft.com/devcontainers/python` - Python development * `mcr.microsoft.com/devcontainers/dotnet` - .NET development * `mcr.microsoft.com/devcontainers/java` - Java development * `mcr.microsoft.com/devcontainers/go` - Go development * `mcr.microsoft.com/devcontainers/base:2.0.4-noble` - Minimal image ## Advanced configuration ### Using secrets during builds [Organization](/docs/ona/organizations/organization-secrets) and [project](/docs/ona/projects/project-secrets) secrets can be used during Dev Container image builds via [secret mounts](https://docs.docker.com/build/building/secrets/#secret-mounts). This is useful when your Dockerfile needs to authenticate with private package registries, pull licensed dependencies, or access credentials that should not be baked into the final image. Secrets are not exposed by default. Each `RUN` instruction in your Dockerfile must explicitly request the secrets it needs using the `--mount=type=secret` flag. The mounted secret itself is only available for the duration of that `RUN` step and is not included in the image layer. The secret mount is ephemeral, but commands within the `RUN` step can still write secret values to files or configuration stores that **are** persisted in the image. If you don't want a credential to be available in the resulting image, avoid commands like `npm config set` that write credentials to disk. Use the `env=` mount pattern or clean up any written files before the `RUN` step ends. User secrets are not available during builds. Built images are cached and shared across the project when the [Dev Container image cache](/docs/ona/runners/devcontainer-image-cache) is enabled, so personal credentials in a build could be exposed to other team members. Build-time secret mounts require a Dockerfile-based Dev Container (`build.dockerfile` or `dockerFile` in `devcontainer.json`). Docker Compose-based Dev Containers are not yet supported. #### How to reference a secret The `id` in `--mount=type=secret,id=...` must match how the secret is configured in Ona. For file secrets, the `id` is the full file path. For environment variable secrets, the `id` is the variable name. Use `target=` to control where the secret is mounted during the `RUN` step. The `target` path can be any location your build step needs. It does not have to match the `id`. #### Example: private npm registry (file mount) Given a file secret configured in Ona at `/usr/local/secrets/npm-token`: ```dockerfile theme={null} FROM node:20 COPY package.json package-lock.json ./ RUN --mount=type=secret,id=/usr/local/secrets/npm-token,target=/tmp/npm-token \ echo "//registry.npmjs.org/:_authToken=$(cat /tmp/npm-token)" > .npmrc && \ npm ci && \ rm -f .npmrc ``` The `.npmrc` file is written, used for `npm ci`, and removed within the same `RUN` step so the token is not persisted in the image layer. #### Example: private npm registry (env mount) The `env=` option mounts the secret directly as an environment variable, avoiding the need to read from a file. This requires Dockerfile syntax v1.10.0+, so you must add `# syntax=docker/dockerfile:1` as the very first line of your Dockerfile (before any other instructions or comments): ```dockerfile theme={null} # syntax=docker/dockerfile:1 FROM node:20 COPY package.json package-lock.json ./ RUN --mount=type=secret,id=NPM_TOKEN,env=NPM_TOKEN \ echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc && \ npm ci && \ rm -f .npmrc ``` The `# syntax=docker/dockerfile:1` directive pulls the `docker/dockerfile:1` image from Docker Hub to use as the build frontend. If your environment restricts access to Docker Hub, you can mirror the image to a private registry and reference it instead: ```dockerfile theme={null} # syntax=my-registry.example.com/docker/dockerfile:1 ``` No changes to `devcontainer.json` are needed. Ona passes the secrets to the build process, and your Dockerfile controls which `RUN` steps can access them. ### Multi-Container Development For more complex setups, you can define multiple containers using Docker Compose. **devcontainer.json:** ```json theme={null} { "name": "Multi-container App", "dockerComposeFile": "docker-compose.yml", "service": "app", "workspaceFolder": "/workspace", "customizations": { "vscode": { "extensions": ["ms-azuretools.vscode-docker"] } } } ``` **docker-compose.yml:** ```yaml theme={null} version: "3.8" services: app: build: context: . dockerfile: Dockerfile volumes: - ..:/workspace:cached network_mode: host command: sleep infinity db: image: postgres:16-alpine restart: unless-stopped network_mode: host environment: POSTGRES_PASSWORD: postgres POSTGRES_DB: app_dev ``` **Required:** Set `network_mode: host` on all services. Without this, services attempt to bridge networks, which can lock you out of your dev container with no way to recover except deleting the environment. ### Adding Custom Features [Dev Container Features](https://containers.dev/features) are self-contained, shareable units of installation code and configuration that let you quickly add tooling, runtimes, or libraries to your development container. You can add features to your Dev Container by adding them to the `features` section of your `devcontainer.json` file: ```json theme={null} { "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { "moby": false }, "ghcr.io/devcontainers/features/github-cli:1": {} } } ``` Ona works well with many Dev Container Features, especially [official ones](https://containers.dev/features) designed for cloud-based environments. Linux-based runners generally provide best compatibility with most Dev Container Features. Here's what you should know: * Community-supported features might require additional testing, as they may have been developed without specific consideration for compatibility. * Feature behavior can vary depending on base images, other installed features, and specific configurations in your setup. ## Recovery mode Recovery mode keeps the environment accessible when the configured Dev Container fails to build or start. Ona starts a temporary recovery container, mounts your workspace, and exposes it through the normal connection path so you can inspect logs, edit the Dev Container configuration, and rebuild. Recovery mode does not apply your failed Dev Container image, features, lifecycle commands, or editor customizations. Use it only to repair the configuration. After a successful rebuild, Ona removes the temporary recovery container and reconnects to the rebuilt Dev Container. When you enter recovery mode: 1. View the build logs: ```bash theme={null} ona environment devcontainer logs ``` 2. Fix the relevant Dev Container files, such as `.devcontainer/devcontainer.json`, `.devcontainer/Dockerfile`, or `.devcontainer/docker-compose.yml`. 3. Rebuild the Dev Container: ```bash theme={null} ona environment devcontainer rebuild ``` ## Next steps * Explore the full [Dev Container specification](https://containers.dev/implementors/spec/) for advanced configurations * Check out the [Dev Container Feature catalog](https://containers.dev/features) for additional tools and utilities * Learn about [Ona projects](/docs/ona/projects/overview) to manage multiple environments ## Troubleshooting 1. Use the "Ask Ona" button in the startup accordion to get help diagnosing the failure. Ona analyzes the error logs and suggests fixes for common issues such as privileged operations, sudo commands, or image pull failures. This feature is available when Ona AI is enabled and your runner supports LLM capabilities. 2. Check the Ona console for specific error messages. 3. Ensure image versions are correctly specified. 4. If the environment enters [recovery mode](#recovery-mode), fix the configuration and rebuild the Dev Container. If a lifecycle command like `postCreateCommand` appears to run inconsistently, view lifecycle command output in the environment logs under "Running dev container background commands". Alternatively, you can also add logging to your script: ```bash theme={null} exec >> /workspaces/post-create.log exec 2>&1 set -x ``` Check `/workspaces/post-create.log` to see exactly what ran. As an alternative to `postCreateCommand`, consider using [Tasks and Services](/docs/ona/configuration/tasks-and-services/overview) which provide UI visibility, CLI access, and structured triggers. # Dotfiles Source: https://ona.com/docs/ona/configuration/dotfiles/overview Apply your shell, editor, and tool configurations to every Ona environment automatically. Dotfiles apply your personal configurations (shell settings, aliases, editor preferences, tools) to every Ona environment on startup. Your customizations layer on top of the team's standardized Dev Container, so you get a consistent base with your own workflow. ## Configure your dotfiles repository Point Ona at a Git repository containing your dotfiles. Every new environment will clone it and run your install script automatically. **Via CLI:** ```bash theme={null} ona user dotfiles set --repository https://github.com//dotfiles ``` **Via Web UI:** Navigate to [Settings > Preferences](https://app.ona.com/settings/preferences) and enter the repository URL. If you do not have a dotfiles repository yet, see [GitHub's dotfiles guide](https://dotfiles.github.io) or [awesome-dotfiles](https://github.com/webpro/awesome-dotfiles) for examples. ## How dotfiles are installed When an environment starts, Ona: 1. Clones your dotfiles repository to `~/dotfiles` 2. Runs the **first** matching script it finds: * `install.sh` or `install` * `bootstrap.sh` or `bootstrap` * `setup.sh` or `setup` If none of these files exist, the repository is cloned but no script runs. You are limited to one dotfiles repository per user. ## Update dotfiles in a running environment Changes pushed to your dotfiles repository apply to **new** environments only. To update a running environment: ```bash theme={null} cd ~/dotfiles && git pull && ./install.sh ``` Replace `install.sh` with whichever script your repository uses. ## Iterate on your dotfiles To test changes without creating new environments each time: 1. Start an environment from your dotfiles repository 2. Edit files and re-run your install script to validate 3. Run `ona environment devcontainer rebuild` to reset the environment state if needed ## Change the default shell Add this to your install script to switch to `zsh` (or any other shell): ```bash theme={null} sudo chsh "$(id -un)" --shell "/usr/bin/zsh" ``` This modifies `/etc/passwd`, which persists across terminal sessions within the same environment. ## Best practices * **Keep install scripts fast.** Every second adds to environment startup time. * **Run non-interactively.** The install script runs without a TTY. Commands that prompt for input (e.g., `read`, interactive installers) will hang the environment. * **Make scripts self-contained.** Check for dependencies before installing them, since Dev Container images vary across projects: ```bash theme={null} FZF_VERSION="0.60.3" if ! command -v fzf >/dev/null 2>&1; then curl -L "https://github.com/junegunn/fzf/releases/download/v${FZF_VERSION}/fzf-${FZF_VERSION}-linux_amd64.tar.gz" | tar xzf - sudo mv fzf /usr/local/bin fi echo "source <(fzf --zsh)" >> "$HOME/.zshrc" ``` * **Do not store secrets in dotfiles.** Use [Ona secrets](/docs/ona/configuration/secrets/overview) instead. ## Troubleshooting Check the environment logs under "Creating Dev Container" for errors. A common cause: ``` fatal: repository 'https://github.com/user/dotfiles-does-not-exist/' not found ``` Verify the repository URL in [Settings > Preferences](https://app.ona.com/settings/preferences) points to an existing, accessible repository. Clone errors appear in the environment logs, but install script failures may not. Reproduce the error manually: ```bash theme={null} cd ~/dotfiles ./install.sh ``` If the script works in some projects but not others, the failing project's Dev Container image is likely missing a dependency your script needs. Make your script self-contained by checking for and installing missing dependencies (see the fzf example above). The install script runs in a non-interactive shell without a TTY. Commands that expect terminal input will block indefinitely. To diagnose: 1. Remove your dotfiles repository from [Settings > Preferences](https://app.ona.com/settings/preferences) 2. Start a fresh environment 3. Clone your dotfiles and run the install script manually to find the blocking command 4. Fix the script, push, and re-add the repository URL # Multi-repository environments Source: https://ona.com/docs/ona/configuration/multi-repository Work with multiple repositories in a single environment for microservices and monorepo workflows. Some projects span multiple repositories - microservices architectures, shared libraries, or related services that need to run together. Ona lets you clone additional repositories into your environment automatically. This is valuable for agents too. When an agent needs to make coordinated changes across repositories, having them in one environment enables atomic commits and easier testing. ## Using Dev Container Configuration The Dev Container `onCreateCommand` allows you to clone additional repositories when your environment starts. This method is particularly useful when you want to maintain the repository setup as part of your Dev Container configuration. Add an `onCreateCommand` entry to your `.devcontainer/devcontainer.json` file: ```json theme={null} { "name": "One extra repository", "image": "mcr.microsoft.com/devcontainers/universal:4.0.1-noble", "onCreateCommand": "git clone https://github.com/organization/second-repo.git /workspaces/second-repo" } ``` For multiple repositories: ```json theme={null} { "name": "Multiple repositories", "image": "mcr.microsoft.com/devcontainers/universal:4.0.1-noble", "onCreateCommand": "git clone https://github.com/organization/second-repo.git /workspaces/second-repo && git clone https://github.com/organization/third-repo.git /workspaces/third-repo" } ``` ## Using Ona Tasks and Services Alternatively, you can use Ona's [Tasks and Services](/docs/ona/configuration/tasks-and-services/overview) to clone additional repositories. This approach offers more flexibility and can be combined with other environment tasks. Add a task to your `.ona/config.yaml` file: ```yaml theme={null} tasks: build: name: Clone additional repositories command: | git clone https://github.com/organization/second-repo.git /workspaces/second-repo git clone https://github.com/organization/third-repo.git /workspaces/third-repo triggeredBy: ['postDevcontainerStart'] ``` ## Best Practices When working with multiple repositories, consider the following best practices: * Clone repositories to `/workspaces`: Always clone additional repositories to `/workspaces/repo-name` (where `repo-name` in that example is the name of your repo). Do this to avoid git tracking issues within your main repository * Use SSH keys or personal access tokens for authentication with private repositories * Organize repositories in a consistent directory structure under `/workspaces` * Configure Git identity globally to ensure consistent commits across repositories ## Working with Multiple Repositories Once your environment is set up: 1. Navigate between repositories using the file explorer or terminal 2. Make changes in each repository independently 3. Commit and push changes to each repository separately Example workflow: ```bash theme={null} cd /workspaces/second-repo # Make changes git add . git commit -m "Update feature X" git push cd /workspaces/third-repo # Make changes git add . git commit -m "Fix bug Y" git push ``` ## Troubleshooting Ensure you have the correct permissions and authentication method. Use absolute paths when necessary. Verify repository URLs and access permissions. # Container registry Source: https://ona.com/docs/ona/configuration/secrets/container-registry-secret Authenticate with private container registries for Dev Container images. Container registry secrets let you pull private Docker images for your Dev Containers. Credentials are also available inside your environment if your Dev Container includes the `docker` CLI. This is how agents access custom tooling images your organization maintains in private registries. ## Create a container registry secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **New Secret**, then choose **Container registry** from the **Secret type** dropdown 3. Configure: * **Name**: Identifier for the secret * **Registry hostname**: Your registry URL (see examples below) * **Registry username**: Registry username * **Registry password**: Registry password or access token New secret dialog with Container Registry type showing hostname, username, and password fields ### Common registry hostnames | Registry | Hostname | | ------------------------- | --------------------------------------------- | | Docker Hub | `https://index.docker.io/v1/` | | GitHub Container Registry | `ghcr.io` | | GitLab Container Registry | `registry.gitlab.com` | | Azure Container Registry | `[name].azurecr.io` | | Google Artifact Registry | `[region]-docker.pkg.dev` | | AWS ECR | `[account-id].dkr.ecr.[region].amazonaws.com` | ## Cloud provider native authentication For AWS and GCP, you can use runner-native authentication instead of managing credentials manually: * **AWS ECR** (EC2 runners): See [AWS ECR with IAM authentication](#using-aws-ecr-with-iam-authentication) below * **Google Artifact Registry** (GCP runners): See [Using Private GAR Images](/docs/ona/runners/gcp/private-gar-images) ## How it works Container registry secrets serve two purposes: 1. **Pull Dev Container images**: Authenticate during environment creation to pull your private base image 2. **Access inside environments**: If your Dev Container includes `docker` CLI, Ona automatically runs `docker login` For AWS ECR and Google Artifact Registry with runner-native auth, you won't be automatically logged in from within the environment. Use [AWS native auth](https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html), [gcloud auth](https://cloud.google.com/artifact-registry/docs/docker/authentication), or [Ona OIDC](/docs/ona/configuration/oidc) for additional access. ## Update a secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **Edit**, update username/password, click **Update** Updated credentials are automatically propagated to running environments (within 2 minutes). *** ## Using AWS ECR with IAM authentication For AWS EC2 runners, you can use IAM-based authentication instead of managing ECR credentials manually. ### Prerequisites * AWS EC2 runners for your Ona environments * ECR registry in the same AWS account (or cross-account access configured) ### Setup 1. Navigate to **Project → Secrets → New Secret** 2. Choose **Container registry** from the **Secret type** dropdown 3. Enter your ECR hostname: `[account-id].dkr.ecr.[region].amazonaws.com` 4. Username and password auto-fill with `runner-native` 5. Click **Add** ### Configure IAM permissions Add this policy to your environment instance role (find `EnvironmentRoleArn` in your CloudFormation stack outputs): ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ecr:GetAuthorizationToken"], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ], "Resource": "arn:aws:ecr:[region]:[account-id]:repository/[repository-name]" } ] } ``` Configure your ECR repository policy to allow the environment role: ```json theme={null} { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowOnaEnvironmentPull", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::[account-id]:role/[environment-role-name]" }, "Action": [ "ecr:BatchGetImage", "ecr:GetDownloadUrlForLayer", "ecr:BatchCheckLayerAvailability" ] } ] } ``` ### Limitations * ECR runner-native support is only available for AWS EC2 runners * Existing environments must be recreated to apply permission changes *** ## Troubleshooting After creating or updating a container registry secret, you must create a new environment for the changes to take effect. Restarting an existing environment may not apply the new authentication settings. # Environment variables Source: https://ona.com/docs/ona/configuration/secrets/environment-variables Environment variable secrets are injected as standard environment variables when your environment starts. The secret name becomes the variable name. ```bash theme={null} echo $APP_ENV ``` ## When to use environment variables Use environment variables for **non-sensitive configuration**: * **Application modes** - `APP_ENV=development`, `DEBUG=true` * **Feature flags** - `ENABLE_NEW_UI=true` * **Endpoints** - `API_BASE_URL=https://api.example.com` **Security tradeoff**: Environment variables can leak through process listings (`ps auxe`), logs, and crash dumps. [File secrets](/docs/ona/configuration/secrets/files) are more secure - they're not visible in process listings and won't appear in logs. However, many tools (including MCP servers) expect credentials as environment variables. For API keys that can be rotated, this tradeoff is often acceptable. For passwords and private keys, prefer file secrets. ## Create an environment variable secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **New Secret**, then choose **Environment variable** from the **Secret type** dropdown 3. Configure: * **Name**: Variable name (e.g., `LINEAR_API_KEY`) * **Secret**: The secret value (max 10KB) New secret dialog with Environment Variable type selected showing name and value fields ## Access the variable Available immediately in your environment: ```bash theme={null} # In shell echo $APP_ENV # In Node.js process.env.APP_ENV # In Python os.environ['APP_ENV'] ``` ## Update a secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **Edit**, update the value, click **Update** Edit secret dialog showing the value field ready to be updated Updated values are automatically propagated to running environments (within 2 minutes). Running processes won't see the new value until the environment is restarted or the Dev Container is rebuilt. # File secrets Source: https://ona.com/docs/ona/configuration/secrets/files File secrets mount sensitive data as files in your environment. They're created automatically when your environment starts, so applications (and agents) can read them like any other file. ## When to use file secrets Use file secrets for: * **Certificates and keys** - TLS certificates, SSH keys, service account credentials * **Config files** - JSON configurations, kubeconfig, cloud provider configs * **Multi-line content** - Anything that doesn't fit in an environment variable Agents often need file secrets for SSH keys (Git operations), service account JSON files (cloud access), or config files that MCP servers expect at specific paths. ## Create a file secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **New Secret**, then choose **File** from the **Secret type** dropdown 3. Configure: * **Name**: Identifier for the secret * **Secret**: File contents (max 10KB) * **File Location**: Where the file appears in your environment (e.g., `/home/gitpod/.ssh/id_rsa`) New secret dialog with File type showing name, secret, and file location fields The file location cannot be changed after creation. ## Access the file The file is automatically available at your specified path: ```bash theme={null} cat /home/gitpod/.config/gcloud/application_default_credentials.json ``` No special code needed. Read it like any file. ## Update a file secret 1. Navigate to **Project → Secrets** or **Settings → Secrets** 2. Click **Edit**, update the value, click **Update** Updated content is automatically propagated to running environments (within 2 minutes). The file at the mount path is updated in place. # How secrets work Source: https://ona.com/docs/ona/configuration/secrets/overview Securely store API keys, tokens, and credentials for your environments and agents. Secrets securely store and inject sensitive data into your environments - API keys, access tokens, credentials, and certificates that shouldn't be in source code. Both humans and agents need secrets. When an agent connects to Linear, authenticates with AWS, or uses MCP servers, it pulls credentials from secrets you've configured. Secrets are configured at three levels: organization, project, or user. They are automatically made available to any environment launched from that project. [Service accounts](/docs/ona/organizations/service-accounts#secrets) can also have secrets attached for use in automations. This ensures consistent and secure access to sensitive data across your development workflow. ## Secret Precedence When secrets with the same name exist at different levels, they follow a strict precedence order: 1. **User Secrets** - Highest precedence 2. **Project Secrets** - Middle precedence 3. **Organization Secrets** - Lowest precedence This means: * User secrets override both project and organization secrets with the same name and mount * Project secrets override organization secrets with the same name * Organization secrets have the lowest priority Learn more about managing [organization secrets](/docs/ona/organizations/organization-secrets), [project secrets](/docs/ona/projects/project-secrets), or [user secrets](/docs/ona/configuration/secrets/user-secrets). ## Encryption of Secrets All secrets you create are protected with industry-standard encryption. Secrets can only be retrieved by environments created from your projects (for Project secrets) or your user (for User secrets). We use `AES256-GCM` to encrypt all secrets at rest in the database, with an additional layer of protection through AWS RDS encryption. This dual-layer approach ensures your sensitive data remains secure both at the application level and infrastructure level. In transit, all secrets are encrypted using TLS. **Ona employees do not have access to the encryption keys and cannot decrypt your secrets.** ## Secrets and environment lifecycle When you create or update a secret, the change is automatically propagated to all running environments within the secret's scope (organization, project, or user). Propagation can take up to 2 minutes. * **File secrets** are updated in place at their mount path. * **Environment variable secrets** are updated on disk, but running processes won't see the new value until the environment is restarted or the Dev Container is rebuilt. * **Container registry secrets** are updated, and new values are used the next time an image is pulled. ## Using secrets during builds Organization and project secrets are automatically available during Dev Container image builds via [BuildKit secret mounts](https://docs.docker.com/build/building/secrets/#secret-mounts). No changes to `devcontainer.json` are needed. Your Dockerfile controls which `RUN` steps can access them using `--mount=type=secret`. For setup instructions and examples, see [Using secrets during builds](/docs/ona/configuration/devcontainer/overview#using-secrets-during-builds). ## Types of secrets * **[Environment Variables](/docs/ona/configuration/secrets/environment-variables)** - Key-value pairs injected into your environment * **[Files](/docs/ona/configuration/secrets/files)** - Entire files (certificates, config files) injected into your environment * **[Container Registry Secrets](/docs/ona/configuration/secrets/container-registry-secret)** - Authentication for private container registries # User secrets Source: https://ona.com/docs/ona/configuration/secrets/user-secrets Personal secrets available across all your projects and environments. User secrets are personal to you - your API keys, tokens, and credentials available in every environment you create. They're ideal for personal access tokens that shouldn't be shared with the team. **User secrets have the highest precedence.** They override project and organization secrets with the same name, letting you customize without affecting teammates. ## When to use user secrets Use user secrets when the credential belongs to an individual rather than to the team. Common examples: * your personal GitHub or GitLab token * your personal Linear or Notion token * credentials for tools only you should use * temporary tokens you are testing before standardizing them at project or organization scope ## Manage user secrets Navigate to **Settings → My Account → Secrets**. User secrets settings page showing list of personal secrets with type and name columns From here you can create, edit, and delete secrets. Each secret can be an [environment variable](/docs/ona/configuration/secrets/environment-variables), [file](/docs/ona/configuration/secrets/files), or [container registry credential](/docs/ona/configuration/secrets/container-registry-secret). ## Common user secrets | Secret | Purpose | | ---------------- | --------------------------- | | `LINEAR_API_KEY` | Personal Linear access | | `GITHUB_TOKEN` | Personal GitHub token | | `NPM_TOKEN` | Private npm registry access | ## When to use user vs project secrets * **User secrets**: Personal tokens, credentials you don't want to share * **Project secrets**: Shared team credentials, service accounts, project-specific config ## How user secrets interact with other scopes If the same secret name exists at multiple levels: 1. user secret wins 2. project secret is used next 3. organization secret is the fallback This is useful when the team defines a default token or endpoint but an individual needs to override it for debugging or personal access. ## Related * [How secrets work](/docs/ona/configuration/secrets/overview) * [Project secrets](/docs/ona/projects/project-secrets) * [Organization secrets](/docs/ona/organizations/organization-secrets) # Task & service examples Source: https://ona.com/docs/ona/configuration/tasks-and-services/examples Common patterns for database setup, preview servers, cloud auth, and more. Copy and adapt these examples for your projects. These patterns work for both humans and agents. When an agent sees these tasks, it can use them as part of its run loop. ## Database provisioning Start PostgreSQL and seed it with development data: ```yaml theme={null} services: postgresql: name: PostgreSQL description: Development database triggeredBy: - postDevcontainerStart commands: start: docker run --rm --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:15 ready: docker exec postgres pg_isready -U postgres stop: docker stop postgres tasks: seed: name: Seed database triggeredBy: - manual command: ./scripts/seed-dev-db.sh ``` ## Containerized services Run services in Docker containers using `docker run` directly. This gives you full control over ports, volumes, environment variables, and container entrypoints. Do **not** use `docker run -d` (detached mode) in a service `start` command. The `-d` flag makes `docker run` exit immediately, which causes the service to transition to Stopped. Run containers in the foreground so the process stays alive. ```yaml theme={null} services: redis: name: Redis description: In-memory cache triggeredBy: - postDevcontainerStart commands: start: | if docker inspect redis >/dev/null 2>&1; then docker start -a redis else docker run --name redis -p 6379:6379 \ -e REDIS_MAXMEMORY=256mb \ -e REDIS_MAXMEMORY_POLICY=allkeys-lru \ redis:7-alpine fi ready: docker exec redis redis-cli ping | grep -q PONG stop: docker stop redis elasticsearch: name: Elasticsearch description: Search engine triggeredBy: - manual commands: start: | if docker inspect elasticsearch >/dev/null 2>&1; then docker start -a elasticsearch else docker run --name elasticsearch -p 9200:9200 \ -e discovery.type=single-node \ -e xpack.security.enabled=false \ -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \ elasticsearch:8.11.0 fi ready: curl -sf http://localhost:9200/_cluster/health stop: docker stop elasticsearch ``` The `if docker inspect` pattern handles environment restarts — it reuses the existing container instead of failing on a name conflict. ## Prebuild optimization Speed up environment starts by running tasks during prebuild: ```yaml theme={null} tasks: install-deps: name: Install dependencies description: Install and cache all dependencies triggeredBy: - prebuild command: | npm ci go mod download pip install -r requirements.txt build-assets: name: Build static assets description: Compile CSS and bundle JavaScript triggeredBy: - prebuild dependsOn: - install-deps command: npm run build:assets warm-cache: name: Warm build cache description: Pre-compile common modules triggeredBy: - prebuild dependsOn: - install-deps command: go build -v ./... ``` Tasks with the `prebuild` trigger run during [prebuild execution](/docs/ona/projects/prebuilds). Organization and project secrets are available, but user secrets are not. ## Build and test pipeline Chain tasks with dependencies: ```yaml theme={null} tasks: build: name: Build command: yarn && yarn build test: name: Run tests dependsOn: - build command: yarn test setup: name: Full setup dependsOn: - build - test triggeredBy: - postDevcontainerStart command: echo "Ready to develop" ``` Agents can run `test` knowing it will build first. ## Cloud authentication Authenticate with AWS using Ona's identity provider: ```yaml theme={null} tasks: aws-auth: name: AWS Auth triggeredBy: - postEnvironmentStart command: ona idp login aws --role arn:aws:iam::123456789:role/dev-role ``` ## Preview server Serve your application for testing: ```yaml theme={null} services: preview: name: Preview server triggeredBy: - postDevcontainerStart commands: start: | npm install npm run build npx serve -p 3000 ./build ready: curl -sf http://localhost:3000 > /dev/null ``` Agents can share this preview URL when demonstrating changes. ## Jupyter notebook Start Jupyter for data science work: ```yaml theme={null} services: jupyter: name: Jupyter Notebook triggeredBy: - manual commands: start: | pip install jupyter pandas numpy matplotlib jupyter notebook --ip=0.0.0.0 --no-browser ready: curl -sf http://localhost:8888 > /dev/null ``` ## Storybook Component development with hot reload: ```yaml theme={null} services: storybook: name: Storybook triggeredBy: - manual commands: start: yarn storybook ready: curl -sf http://localhost:6006 > /dev/null ``` ## Parallel database testing Test against multiple database versions: ```yaml theme={null} services: pg14: name: Postgres 14 commands: start: docker run --rm --name pg14 -p 5432:5432 postgres:14 ready: docker exec pg14 pg_isready stop: docker stop pg14 pg15: name: Postgres 15 commands: start: docker run --rm --name pg15 -p 5433:5432 postgres:15 ready: docker exec pg15 pg_isready stop: docker stop pg15 tasks: test-compat: name: Compatibility tests triggeredBy: - manual command: | DATABASE_URL=postgres://localhost:5432 npm test DATABASE_URL=postgres://localhost:5433 npm test ``` ## Troubleshooting environment Manual task for debugging production issues: ```yaml theme={null} tasks: troubleshoot: name: Setup troubleshooting triggeredBy: - manual command: | sudo apt-get update && sudo apt-get install -y htop iftop ./scripts/setup-vpn.sh ``` # Dynamic configuration Source: https://ona.com/docs/ona/configuration/tasks-and-services/generating-tasks-and-services Generate tasks and services programmatically based on what agents discover in your codebase. Create and update tasks and services at runtime using the CLI. When Ona explores a new repository, it can: * Discover `package.json` scripts and expose them as tasks * Find services in a monorepo and create start commands for each * Generate test tasks for different modules it finds * Adapt the environment to match the project structure ## Creating tasks and services dynamically Use the CLI to pipe configuration directly: ```bash theme={null} echo '{"tasks": {"update_deps": {"name": "Update dependencies", "command": "npm update"}}}' | ona environment config apply - ``` The `-` signals reading from stdin. Task and service IDs can only contain alphanumeric characters, underscores, and hyphens (1-128 characters). ## Example uses **Expose package.json scripts as tasks:** ```bash theme={null} jq -r '.scripts | to_entries[] | {(.key | gsub("[^a-zA-Z0-9_-]"; "_")): {"name": .key, "command": .value}}' package.json | jq -s 'add | {"tasks": .}' | ona environment config apply - ``` **Create services for monorepo components:** ```bash theme={null} find ./components -type d -maxdepth 1 -mindepth 1 | jq -R '{(. | gsub("[^a-zA-Z0-9_-]"; "_")): {"name": "Start " + ., "commands": {"start": "cd " + . + " && go run ."}}}' | jq -s 'add | {"services": .}' | ona environment config apply - ``` **Load configuration from a remote source:** ```bash theme={null} curl https://example.com/tasks-and-services.json | ona environment config apply - ``` Only download configuration from sources you trust. Verify integrity before applying. ## Control from outside environments Manage tasks and services from outside an environment using the CLI on your local machine or in external pipelines. ### Example: create, run task, clean up ```bash theme={null} # Create environment ENV_ID=$(ona environment create https://github.com/your-repo/project --dont-wait --class-id ) # Run a task TASK_ID=$(ona environment task start build-and-test --environment-id $ENV_ID) # Stream logs ona environment task logs $TASK_ID --environment-id $ENV_ID # Check result and clean up TASK_STATUS=$(ona environment task get $TASK_ID --environment-id $ENV_ID -o json | jq -r .status) if [ "$TASK_STATUS" = "succeeded" ]; then ona environment delete $ENV_ID else echo "Task failed. Environment left for inspection." fi ``` # Startup tasks & services Source: https://ona.com/docs/ona/configuration/tasks-and-services/overview Automate environment setup and define repeatable actions for humans and agents. Tasks and services automate the repetitive work of setting up and operating development environments: seeding databases, starting servers, running tests, authenticating with cloud providers. Define it once and it runs automatically or on-demand. For agents, tasks and services are essential. When Ona can run `npm test` or `docker compose up` reliably, it can iterate autonomously without human intervention. Tasks and services in the session sidebar ## Tasks vs Services In the session sidebar, long-running processes live under **Ports & Services** and one-off actions live under **Tasks**. **Services** are long-running processes that stay active throughout your session. They appear in the **Ports & Services** tab alongside the ports they expose. Services in the Ports & Services tab * Databases (PostgreSQL, MySQL) * Backend and frontend servers * Caching systems (Redis) A service's `start` command must **stay running** (block) for the service to remain active. If the command exits, the service transitions to Stopped (exit code 0) or Failed (non-zero). For example, `npm start` or `docker run postgres` block and keep the service alive, while `docker run -d postgres` returns immediately and the service stops. **Tasks** are one-off actions that run and complete. They appear in the **Tasks** tab and can run automatically during startup or manually on demand. Tasks in the Tasks tab * Installing dependencies * Running tests * Seeding databases * Authenticating with cloud providers ## Quick example ```yaml theme={null} # .ona/config.yaml services: database: name: PostgreSQL commands: start: docker compose up postgres ready: docker compose exec postgres pg_isready triggeredBy: - postDevcontainerStart tasks: seed: name: Seed database command: npm run db:seed triggeredBy: - postDevcontainerStart test: name: Run tests command: npm test triggeredBy: - manual ``` This configuration: 1. Starts PostgreSQL when the environment starts 2. Waits until the database service is ready 3. Seeds the database with test data 4. Makes "Run tests" available as a manual action ## Apply configuration changes An environment keeps using the tasks and services configuration that it applied when it was created. Editing, moving, or deleting the configuration file does not change the running environment, including after the environment restarts. When Ona detects a valid change, the environment start details show that an update is available. Select **Apply** to update that environment. Applying a change uses the latest configuration resolved from the repository; it does not change the Project setting. If the Project's **Tasks and services configuration path** changed after the environment was created, select **Apply Project configuration** to adopt the new Project setting for that environment. This does not update other existing environments. If the source file is missing or invalid, Ona keeps the last applied tasks and services running. Restore or fix the file before applying it. A missing or invalid explicitly configured file still prevents a new environment from loading tasks and services. ## Triggers Control when tasks and services run: | Trigger | Services | Tasks | When it runs | | ----------------------- | -------- | ----- | ------------------------------------------------------------------------------------------------------------------ | | `manual` | ✓ | ✓ | On-demand via the CLI or UI | | `postDevcontainerStart` | ✓ | ✓ | After the Dev Container starts in a user environment (first start or rebuild). Does **not** fire during prebuilds. | | `postEnvironmentStart` | ✓ | ✓ | Every time the environment starts or resumes | | `prebuild` | ✓ | ✓ | During prebuild execution only (no user secrets available). Does **not** fire in user environments. | See the [.ona/config.yaml schema](/docs/ona/reference/ona-config-schema#triggers) for complete trigger documentation, including [how triggers interact with prebuilds](/docs/ona/reference/ona-config-schema#prebuilds-and-triggers). ## Run automations across repositories Tasks and services run within individual environments. For cross-repository automation at scale (migrations, security scanning, bulk updates), see [Automations](/docs/ona/automations/overview). ## Next steps * [.ona/config.yaml schema](/docs/ona/reference/ona-config-schema) - field reference for all fields, commands, triggers, and execution environments * [Examples](/docs/ona/configuration/tasks-and-services/examples) - common patterns for databases, servers, and CI * [Dynamic configuration](/docs/ona/configuration/tasks-and-services/generating-tasks-and-services) - create tasks and services programmatically # Create your first Automation Source: https://ona.com/docs/ona/create-first-automation Go from zero to a scheduled Automation: set up a project, make your repository AI-ready, and run your first closed-loop workflow. This guide walks you from "I have an Ona account" to "I have a scheduled Automation running." By the end, you will have a project, a reproducible environment, and an Automation that runs on a schedule and delivers merge-ready pull requests. ## Prerequisites Before you start: * An Ona account on a **Core** or **Enterprise** plan * At least one [runner](/docs/ona/runners/overview) in your organization * A repository with code you want to automate against ## Step 1: Create a project A project connects your repository to a runner. It is the blueprint for every environment and every Automation run. If you already have a project for your repository, skip to Step 2. Follow the [Create your first project](/docs/ona/create-first-project) guide to set one up. You need a repository URL, a project name, and at least one environment class. ## Step 2: Make your repository AI-ready For Automations to work reliably, the environment must be reproducible. Every Automation run starts a fresh environment from your configuration. If the environment does not have your tools, dependencies, and services, the Automation cannot reliably clone, build, test, and iterate. Two files make your repository AI-ready: ### devcontainer.json Defines the base image, language runtimes, tools, and VS Code extensions. Place it at `.devcontainer/devcontainer.json` in your repository. Minimal example: ```json theme={null} { "image": "mcr.microsoft.com/devcontainers/base:2.0.4-noble", "features": { "ghcr.io/devcontainers/features/node:1": {} } } ``` See [Set up your first environment](/docs/ona/configuration/devcontainer/getting-started) for the full configuration reference. ### .ona/config.yaml Defines startup tasks (install dependencies, seed databases) and long-running services (databases, servers). Place it at `.ona/config.yaml` in your repository. Minimal example: ```yaml theme={null} tasks: install: name: Install dependencies command: npm ci triggeredBy: - postDevcontainerStart ``` See [Tasks and Services](/docs/ona/configuration/tasks-and-services/overview) for the full configuration reference. ### Shortcut: use an Automation to generate your environment config Bootstrap both files by creating an Automation with a single Prompt step. Create a new Automation, add one Prompt step with the following text, select your project, and run it. The Automation analyzes your repository and generates `devcontainer.json` and `.ona/config.yaml`. ```text theme={null} Create a high-quality, fully working "development environment as code" configuration for the current environment. The setup must work for: - Ona development environments, which use DevContainer configurations. - All Git repositories mounted under the DevContainer workspace. Terminology - apps: Source code intended to be built and shipped. - dev tool: Any tool used for compiling, building, publishing, testing, profiling, debugging, or accessing an app's infrastructure. Required Process 1. Read the documentation (see Allowed Sources) to fully understand: - Ona tasks and services, secrets, environment variables, CLI, and prebuilds. - DevContainer fundamentals and how they integrate with Ona and VS Code. 2. Analyze the source code and identify: - Documentation on dev setup or contribution guidelines. - Configuration files for containers, IDEs, build tools, environment variables, etc. 3. Update all necessary files, including: - devcontainer.json - Ona tasks and services - Any other files required to meet the Success Criteria. 4. Run the Acceptance Tests for all code you have created and iterate until the last run of every Acceptance Test has been successful. 5. Do not create any documentation files. Success Criteria - The DevContainer includes all tools needed to work with any file in any repo in this environment. - Ona services exist for every service required or recommended to run any app in this environment. - Ona services exist for every app, for the standard or documented configurations. - Ona tasks exist for all standard or documented development workflows for this repo. - If an app exposes a TCP port, the DevContainer must forward it. - If an app exposes an HTTP/HTTPS port, the corresponding Ona service must expose it by running "ona env port open" before starting the app. - The DevContainer must install all VS Code extensions necessary to work effectively with the files and services in this environment. Acceptance Tests - The command "ona auto update " succeeds - The command "ona env devcontainer validate" succeeds - The DevContainer rebuilds successfully. - All installed tools launch successfully and are available in the correct version - Ona tasks start and finish successfully. - Ona services successfully reach the state "ready". - Apps exposed via Ona port respond successfully when curl'ing the port. Allowed Sources - Ona documentation: automations, secrets, environment variables, CLI, prebuilds, DevContainers https://ona.com/docs/llms.txt - DevContainer documentation: https://containers.dev/ - DevContainers in VS Code: https://code.visualstudio.com/docs/devcontainers/containers - DevContainer base images: https://hub.docker.com/r/microsoft/devcontainers - VS Code extensions: - https://marketplace.visualstudio.com/vscode - https://open-vsx.org/ - Any publicly available DevContainer features - Anything installable within a Dockerfile ``` ### Verify your environment Start an environment from your project. Run your test suite. If everything passes interactively, it will work for Automations. ## Step 3: (Optional) Configure integrations Integrations give Automations context from external tools. For example, the Sentry integration lets Automations read error data, and the Linear integration lets them read and update issues. Configure integrations in **Settings > Integrations**. See the setup guides for [Sentry](/docs/ona/integrations/configure-sentry), [Linear](/docs/ona/integrations/configure-linear), [Notion](/docs/ona/integrations/configure-notion), [Granola](/docs/ona/integrations/configure-granola), and [Atlassian](/docs/ona/integrations/configure-atlassian). ## Step 4: (Optional, Enterprise) Create a service account If you plan to run Automations on a schedule or share them with your team, create a [service account](/docs/ona/organizations/service-accounts). Commits, PRs, and comments will appear under the service account identity instead of your personal account. Service account executors require an Enterprise plan. ## Step 5: Create your first Automation 1. Go to **Automations** in Ona. 2. Click **New** and choose **Start from scratch** or pick a template from the suggestions panel. Automations page with suggested templates ### Name and description To set or change the name and description, open the **⋯** menu and select **Rename**. A dialog opens where you can edit both fields. ### Set the executor The **Run Automation as** field is in the trigger configuration panel. Click the trigger node to open the side panel — the executor selector is at the bottom. * **Your user**: Automations run under your identity. Commits and PRs appear as you. * **Service account** (Enterprise only): Automations run under a shared [service account](/docs/ona/organizations/service-accounts) identity. Service account executors are an [Enterprise](/docs/ona/automations/plans-and-limits) feature. On Core plans, Automations run as your user. ### Add steps Steps run in sequence. Example for a dependency update Automation: **Step 1: Prompt** ``` Update all dependencies to their latest compatible versions. Run the test suite and fix any breaking changes. ``` **Step 2: Command** ```bash theme={null} npm test ``` **Step 3: Pull Request** Create a PR with the changes for review. Steps configuration ### Set guardrails [Guardrails](/docs/ona/automations/guardrails) prevent runaway executions: * **Max concurrent**: 5 (for testing) * **Max total**: 20 Increase these once you are confident the Automation works. ### Choose a trigger For your first run, select **Manual** to test immediately. | Trigger | Best for | | ---------------- | ----------------------------------------- | | **Manual** | One-time migrations, testing Automations | | **Pull Request** | Code review, security checks, test runs | | **Scheduled** | Recurring maintenance, dependency updates | Click **Save** to create the Automation. ## Step 6: Run manually and verify 1. Open the Automation. 2. Select target repositories. 3. Click **Run**. Watch the Automation execute. It starts an environment, runs your steps, and creates pull requests. Review the output and the PRs it created. Start manual. Run the Automation a few times, review the results, and adjust steps as needed. Build confidence before scheduling. ## Step 7: Schedule it Once you trust the output, switch the trigger to **Scheduled**: 1. Open the Automation settings. 2. Change the trigger to **Scheduled**. 3. Select **Every weekday** and set the time, for example 9:00 AM UTC for weekday mornings. Choose **Every day** instead if the Automation should also run on weekends. 4. Save. The Automation now runs on schedule. You review merge-ready PRs instead of doing the work yourself. ## What's next * [Automations in practice](/docs/ona/automations/automations-in-practice) for real-world examples * [Configure Automations](/docs/ona/automations/configure-automations) for the full settings reference * [Pull request triggers](/docs/ona/automations/triggers/pullrequest) for Automations that run on PR events * [Time-based triggers](/docs/ona/automations/triggers/timebased) for scheduling options * [Guardrails](/docs/ona/automations/guardrails) for safety controls * [Service accounts](/docs/ona/organizations/service-accounts) for team-wide Automations # Create your first project Source: https://ona.com/docs/ona/create-first-project Connect a repository to Ona so you can launch environments, configure Dev Containers, and run Automations against it. A project connects a repository to Ona. It defines which runner provisions your environments, which environment classes are available, and what configuration files to use. Every environment and every Automation starts from a project. ## Prerequisites * An Ona account on any plan * At least one runner in your organization. Ona Cloud includes a runner by default. If you're self-hosting, [deploy a runner](/docs/ona/runners/overview) on [AWS](/docs/ona/runners/aws/overview) or [GCP](/docs/ona/runners/gcp/overview) first. * A repository URL (GitHub or GitLab) ## Create the project 1. From the Ona dashboard, click **Projects** in the sidebar. 2. Click **New Project**. Create a project dialog with repository selector, project name, and environment classes 3. Search for or browse to your repository. 4. Enter a project name. 5. Select at least one environment class. You can add up to 30 classes per project. 6. Click **Create**. ## Configure your environment Every project reads two configuration files from your repository root. If a `devcontainer.json` doesn't exist yet, Ona generates a default one. Adding your own makes the environment match your project's needs. * **`devcontainer.json`**: defines the base image, language runtimes, tools, and VS Code extensions. This is the [Dev Container](https://containers.dev/) standard, so the same file works in VS Code, GitHub Codespaces, and Ona. See [configure your Dev Container](/docs/ona/configuration/devcontainer/getting-started) for a walkthrough. * **`.ona/config.yaml`**: defines startup tasks (install dependencies, seed databases) and long-running services (dev servers, databases). These run automatically when an environment starts. See [tasks and services](/docs/ona/configuration/tasks-and-services/overview) for examples. By default, Ona looks for `.ona/config.yaml`. To use a different path, set the **Tasks and services configuration path** in your project settings. Every environment and every Automation launched from this project uses the same configuration. ## Verify it works 1. Open the project from your dashboard. 2. Click **Create Environment**. 3. Wait for the environment to build and start. 4. Confirm your tools, dependencies, and services are available. If the environment builds and your test suite passes, the project is ready for Automations. ## What's next * [Create your first Automation](/docs/ona/create-first-automation) to run workflows against this project * [Set up your first environment](/docs/ona/configuration/devcontainer/getting-started) to configure `devcontainer.json` * [Share the project](/docs/ona/projects/project-sharing) with your team * [Projects reference](/docs/ona/projects/overview) for environment classes, recommended editors, and advanced configuration # Cursor Source: https://ona.com/docs/ona/editors/cursor Connect to Ona environments using Cursor editor. [Cursor](https://www.cursor.com/) connects to Ona environments using the same [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) as VS Code. All [VS Code features](/docs/ona/editors/vscode) (rebuild, port forwarding, automations) work in Cursor. When reaching out to support, specify that you are using Cursor as your editor. ## Prerequisites 1. [Cursor](https://www.cursor.com/) installed on your machine. 2. The [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) installed in Cursor. 3. The [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) extension installed in Cursor. ## Opening an environment Select **Cursor** from the editor dropdown by clicking the dropdown arrow next to the Open button on the action bar. Cursor opens via the `cursor://` URI handler. On first use, Cursor prompts you to install the Ona extension and authenticate. This is the same flow as [VS Code setup](/docs/ona/editors/vscode#first-time-setup). ## Cursor AI works over SSH Cursor's AI features work in Ona environments as they do locally: * **Tab**: inline code completions * **Agent**: multi-file AI edits * **Chat** (⌘L / Ctrl+L): context-aware code chat * **⌘K / Ctrl+K**: inline code generation and editing Cursor AI communicates with Cursor's cloud services directly over the SSH connection. No Ona-specific configuration is needed. ## Extension and settings Extensions configured via `customizations.vscode.extensions` in your `devcontainer.json` apply to Cursor. See [VS Code and forks](/docs/ona/editors/overview#vs-code-and-forks) for details. ## Troubleshooting The `cursor://` URI handler is not registered on your system, or Cursor is not installed. * **Linux**: Verify a Cursor desktop entry exists in `~/.local/share/applications` or `/usr/share/applications`. If missing, reinstall Cursor. * **All platforms**: Refresh the browser page, or test in a different browser to rule out browser-specific issues. The [VS Code troubleshooting guide](/docs/ona/editors/vscode#troubleshooting) applies to Cursor, including log export (`Ona: Export all logs`) and authentication issues. 1. Check the `Ona` output view for errors. 2. Check your network settings. VPN or firewall can interfere. 3. When sharing reports with support: * Set log level to Trace via `Developer: Set Log Level...` * Use `Ona: Export all logs` from the problematic window. # JetBrains Source: https://ona.com/docs/ona/editors/jetbrains Integrate JetBrains IDEs with Ona Ona integrates with JetBrains IDEs through [JetBrains Toolbox](https://www.jetbrains.com/toolbox-app/) and the [Ona plugin](https://plugins.jetbrains.com/plugin/26960-ona). Supported IDEs: IntelliJ IDEA Ultimate, GoLand, PyCharm Professional, PhpStorm, RubyMine, WebStorm, Rider, CLion, and RustRover. ## Prerequisites 1. [JetBrains Toolbox](https://www.jetbrains.com/toolbox-app/) installed on your system. Keep JetBrains Toolbox updated for the best experience. ## Opening an environment 1. Start an environment in Ona. 2. Click the **dropdown arrow** next to the Open button on the action bar and select your preferred JetBrains IDE (e.g., IntelliJ IDEA Ultimate). ## First-time setup On first use, JetBrains Toolbox will: 1. **Install the Ona plugin**. Click **Install** when prompted. 2. **Authenticate**. A browser window opens to sign in to your Ona account. 3. **Download the IDE backend**. Toolbox provisions the IDE backend in your environment. 4. **Launch the IDE client**. The local thin client opens and connects automatically. If the Ona plugin does not appear as available in JetBrains Toolbox, your organization's enterprise settings may be blocking access to the JetBrains Marketplace. Check the Toolbox logs (Settings → About → "Show log files") for details, and work with your IT administrators to allow marketplace access. ## Faster startup with prebuilds Enable [JetBrains warmup](/docs/ona/projects/prebuilds#jetbrains-warmup) in your project's prebuild configuration to reduce startup time. Warmup pre-installs the IDE backend and builds project indexes during prebuilds, so users skip those steps when opening the editor. ## Plugin customization Add plugins to your `devcontainer.json` using the `customizations.jetbrains.plugins` property: ```json theme={null} { "customizations": { "jetbrains": { "plugins": [ "org.intellij.plugins.hcl", "com.intellij.kubernetes" ] } } } ``` ### Finding plugin IDs 1. Visit the [JetBrains Marketplace](https://plugins.jetbrains.com/) 2. Search for your desired plugin 3. Copy the plugin ID from **Additional Information** at the bottom of the plugin details page JetBrains Marketplace plugin page showing Plugin ID in Additional Information section ## Limitations * JetBrains IDE settings (keymaps, themes, inspections) cannot be pre-configured via `devcontainer.json`. Configure them manually after connecting. * Port forwarding configurations from `devcontainer.json` are not automatically applied. Expose ports manually through the IDE or CLI. ## Managing authentication To change your Ona account or sign out: 1. Open JetBrains Toolbox 2. Go to Settings → Providers → Ona 3. Click "Sign Out" 4. Click "Sign In" to authenticate with a different account ## Rebuilding Dev Containers 1. Close your current IDE window 2. Wait for the rebuild to complete 3. Return to Ona and select the IDE in the action bar to reconnect ## Additional resources * [JetBrains system requirements](https://www.jetbrains.com/help/ide-services/system-requirements.html) * [JetBrains network requirements](https://www.jetbrains.com/help/ide-services/system-requirements.html#network-access-requirements) * [IP allowlist for IntelliJ IDE](https://youtrack.jetbrains.com/articles/SUPPORT-A-288/Whats-the-IP-allowlist-of-IntelliJ-IDE-in-case-of-firewall-policy-or-restricted-network) ## Troubleshooting 1. Verify JetBrains Toolbox is running. 2. Ensure your environment is running in Ona. 3. Try closing the IDE and reopening from Ona. **Toolbox logs**: Open JetBrains Toolbox → Settings → About → "Show log files" → send `toolbox.log` to [support@ona.com](mailto:support@ona.com). **IDE logs**: Open JetBrains Toolbox → click the three dots next to the IDE entry → "Show log files" → send to [support@ona.com](mailto:support@ona.com). Do **NOT** share logs publicly as they may contain sensitive information. # Supported editors Source: https://ona.com/docs/ona/editors/overview IDEs & Editors supported by Ona Ona environments connect to your editor over SSH. Most editors support **one-click open** from the dashboard. Click the Open button and you're connected. Editors like Zed require manual SSH configuration. ## Supported editors | Editor | Connection | One-click open | Browser mode | Ona extension | devcontainer customizations | Prebuild warmup | Policy support | | ---------------------------------------------- | ----------------- | --------------------- | --------------------- | ------------------------------- | -------------------------------------- | --------------------- | --------------------- | | [VS Code](/docs/ona/editors/vscode) | SSH via extension | | - | | `vscode.extensions`, `vscode.settings` | - | | | [VS Code Browser](/docs/ona/editors/vscode-browser) | Browser | | | | `vscode.extensions`, `vscode.settings` | - | | | [Cursor](/docs/ona/editors/cursor) | SSH via extension | | - | | `vscode.extensions`, `vscode.settings` | - | | | [Windsurf](/docs/ona/editors/windsurf) | SSH via extension | | - | | `vscode.extensions`, `vscode.settings` | - | | | [JetBrains](/docs/ona/editors/jetbrains) | Toolbox plugin | | - | (Toolbox) | `jetbrains.plugins` | | | | [Zed](/docs/ona/editors/zed) | SSH (manual) | - | - | - | - | - | - | ## VS Code and forks [VS Code](/docs/ona/editors/vscode), [Cursor](/docs/ona/editors/cursor), and [Windsurf](/docs/ona/editors/windsurf) all use the same [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex). The extension connects to your environment over SSH and provides: * **One-click rebuild**: apply devcontainer changes without leaving the editor * **Port forwarding**: access services running in your environment * **Automations management**: start/stop services and tasks * **Browser handling**: URLs opened in the environment automatically open in your local browser Cursor and Windsurf are AI-native editors built on VS Code. Their AI features work in Ona environments as they do locally, operating over the SSH connection independently of the Ona extension. See the [Cursor](/docs/ona/editors/cursor#cursor-ai-works-over-ssh) and [Windsurf](/docs/ona/editors/windsurf#windsurf-ai-works-over-ssh) pages for specifics. Extensions configured via `customizations.vscode.extensions` in your `devcontainer.json` are installed in all VS Code-based editors, including Cursor and Windsurf. ## JetBrains [JetBrains IDEs](/docs/ona/editors/jetbrains) connect through JetBrains Toolbox with the [Ona plugin](https://plugins.jetbrains.com/plugin/26960-ona). Supported IDEs: IntelliJ IDEA Ultimate, GoLand, PyCharm Professional, PhpStorm, WebStorm, RubyMine, CLion, RustRover, and Rider. JetBrains is the only editor family that supports [prebuild warmup](/docs/ona/projects/prebuilds#jetbrains-warmup). Warmup pre-installs the IDE backend and builds project indexes during prebuilds, reducing startup time. Plugins are configured via `customizations.jetbrains.plugins` in your `devcontainer.json`. ## SSH-based editors [Zed](/docs/ona/editors/zed) and any other SSH-capable editor can connect to Ona environments using the [CLI](/docs/ona/integrations/cli). Run `ona env ssh-config` to set up your local SSH configuration, then connect using the environment's SSH host (`.ona.environment`). SSH-based editors do not appear in the Ona dashboard editor selector and are not covered by [organization editor policies](/docs/ona/organizations/overview). ## Browser handling VS Code, VS Code forks (Cursor, Windsurf), and JetBrains have built-in browser handlers that automatically open URLs in your local browser when triggered by scripts or commands. See [opening a port and previewing in the browser](/docs/ona/integrations/ports#opening-a-port-and-previewing-in-the-browser) for details. # Visual Studio Code Source: https://ona.com/docs/ona/editors/vscode Connect to Ona environments using Visual Studio Code with the Ona extension. Ona integrates with VS Code over SSH. The [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) handles connection setup, environment management, and port forwarding. ## Prerequisites 1. [VS Code](https://code.visualstudio.com/download) installed. 2. The [Ona](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) extension installed. 3. The [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) extension installed. Keep your VS Code and extensions updated for the best experience. ## Opening an environment 1. Start an environment in Ona. 2. Click the **Open** button on the action bar. This opens the environment in your default editor. The button is available at any stage, even when the environment is not fully running yet. 3. To choose a different editor, click the **dropdown arrow** next to the Open button and select from the list. ## First-time setup On first use, VS Code will prompt you to: 1. **Install the Ona extension**. Click **Allow** when prompted. The extension configures your local SSH settings automatically. 2. **Install Remote - SSH**. Click **Install** if prompted. This extension is required for the SSH connection. 3. **Authenticate**. A browser window opens to sign in to your Ona account. After signing in, you are redirected back to VS Code. If authentication fails, close the browser tab and try opening the environment again. ## Workspace Trust VS Code may prompt you to trust the workspace when connecting to a new environment. Ona environments run in isolated VMs, so you can safely click **Trust Folder & Continue** if you're familiar with the repository. See the [VS Code documentation](https://code.visualstudio.com/editor/workspace-trust) for details. ## Managing your environment ### Commands Open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) and type `Ona` to see all available commands. You can also click the **remote indicator** in the bottom-left corner for a quick menu. VS Code command palette showing available Ona commands ### Rebuild Rebuild the container to apply changes to `.devcontainer.json`, `Dockerfile`, or `docker-compose.yml`: 1. **Command Palette**: `Ona: Rebuild Container` 2. **Prompt**: VS Code detects configuration changes and offers to rebuild automatically. You will be disconnected during the rebuild and reconnected when it finishes. Check the `Ona` output channel for rebuild logs. ## Uninstalling Run `Ona: Uninstall Extension` to remove the extension and clean up SSH configuration. Removing the extension through VS Code's extension panel does not clean up SSH settings. If you already removed the extension without using the command, reinstall it and run the uninstall command. ## Troubleshooting * Port forwarding does not work for hosts other than `localhost` (e.g., other services in a docker-compose.yml). * **Workaround**: Use `network_mode: host` in your docker-compose.yml for services you want to port forward. * `remoteEnv` environment variable values are not applied unless the Dev Container is rebuilt. If a build fails, you enter [recovery mode](/docs/ona/configuration/devcontainer/overview#recovery-mode): 1. Check the error messages in the `Ona` output channel. 2. Inspect the build logs in the Output panel. 3. Fix the `.devcontainer.json` configuration. 4. Rebuild using `Ona: Rebuild Container`. [Recovery mode](/docs/ona/configuration/devcontainer/overview#recovery-mode) is not stable for development. Fix the configuration and rebuild. 1. Use `Ona: Sign Out` to sign out. 2. Sign in again with the same or a different account. Allow VS Code's "Code Helper.app" in your firewall settings, then restart VS Code and rebuild. 1. Check the `Ona` output view for errors. 2. Check your network settings. VPN or firewall can interfere. 3. When sharing reports with support: * Set log level to Trace via `Developer: Set Log Level...` * Set `remote.SSH.logLevel` to `trace` in VS Code settings. * Use `Ona: Export all logs` from the problematic window. Be cautious when sharing logs, as they may contain sensitive information. # VS Code browser Source: https://ona.com/docs/ona/editors/vscode-browser Connect to Ona environments using VS Code in the browser with zero installation. VS Code Browser runs in the browser with no local installation. No extensions or SSH configuration required. ## Opening an environment 1. Start an environment in Ona. 2. Click the **Code** tab in the environment details page. VS Code Browser loads inline alongside the Ona session. 3. To open VS Code Browser in a dedicated browser tab, select **VS Code Browser** from the editor dropdown next to the Open button on the action bar. 4. On first use, click **Allow** when prompted to authenticate with your Ona account. If authentication fails, close the browser tab and try opening the environment again. ## Managing your environment ### Commands Open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) and type `Ona` to see all available commands. VS Code command palette showing available Ona commands ### Rebuild Rebuild the container to apply changes to `.devcontainer.json`, `Dockerfile`, or `docker-compose.yml`: 1. **Command Palette**: `Ona: Rebuild Container` 2. **Prompt**: VS Code detects configuration changes and offers to rebuild automatically. You will be disconnected during the rebuild and reconnected when it finishes. Check the `Ona` output channel for rebuild logs. ### Full-screen editing Use the **Expand** button in the top-right corner of the Code tab for a larger view, or select **VS Code Browser** from the editor dropdown to open in a dedicated browser tab. ### Settings Sync Enable Settings Sync to sync your extensions and preferences from VS Code Desktop. See the [official Settings Sync documentation](https://code.visualstudio.com/docs/configure/settings-sync#_turning-on-settings-sync). ## Troubleshooting The following limitations apply in addition to the [VS Code Desktop limitations](/docs/ona/editors/vscode#limitations): * Docker Compose environments require `network_mode: "host"` on the main service for VS Code Browser to connect. * VS Code Browser is not supported for local environments created using Ona Desktop. * Opened ports are not automatically forwarded. [Share them](/docs/ona/integrations/ports#open-ports) to access them. 1. Use `Ona: Sign Out` to sign out. 2. Sign in again with the same or a different account. 1. Check the `Ona` output view for errors. 2. When sharing reports with support: * Set log level to Trace via `Developer: Set Log Level...` * Use `Ona: Export all logs` from the problematic window. Be cautious when sharing logs, as they may contain sensitive information. # Windsurf Source: https://ona.com/docs/ona/editors/windsurf Connect to Ona environments using Windsurf editor. [Windsurf](https://windsurf.com/) connects to Ona environments using the same [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) as VS Code. All [VS Code features](/docs/ona/editors/vscode) (rebuild, port forwarding, automations) work in Windsurf. When reaching out to support, specify that you are using Windsurf as your editor. ## Prerequisites 1. [Windsurf](https://windsurf.com/) installed on your machine. 2. The [Ona extension](https://marketplace.visualstudio.com/items?itemName=gitpod.gitpod-flex) installed in Windsurf. 3. The [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) extension installed in Windsurf. ## Opening an environment Select **Windsurf** from the editor dropdown by clicking the dropdown arrow next to the Open button on the action bar. Windsurf opens via the `windsurf://` URI handler. On first use, Windsurf prompts you to install the Ona extension and authenticate. This is the same flow as [VS Code setup](/docs/ona/editors/vscode#first-time-setup). ## Windsurf AI works over SSH Windsurf's AI features work in Ona environments as they do locally: * **Cascade**: AI assistant for multi-step tasks * **Flows**: context-aware actions triggered from the editor * **Supercomplete**: code completions * **Chat**: inline AI chat for code questions Windsurf AI communicates with Windsurf's cloud services directly over the SSH connection. No Ona-specific configuration is needed. ## Extension and settings Extensions configured via `customizations.vscode.extensions` in your `devcontainer.json` apply to Windsurf. See [VS Code and forks](/docs/ona/editors/overview#vs-code-and-forks) for details. ## Troubleshooting The `windsurf://` URI handler is not registered on your system, or Windsurf is not installed. * **Linux**: Verify a Windsurf desktop entry exists in `~/.local/share/applications` or `/usr/share/applications`. If missing, reinstall Windsurf. * **All platforms**: Refresh the browser page, or test in a different browser to rule out browser-specific issues. The [VS Code troubleshooting guide](/docs/ona/editors/vscode#troubleshooting) applies to Windsurf, including log export (`Ona: Export all logs`) and authentication issues. 1. Check the `Ona` output view for errors. 2. Check your network settings. VPN or firewall can interfere. 3. When sharing reports with support: * Set log level to Trace via `Developer: Set Log Level...` * Use `Ona: Export all logs` from the problematic window. # Zed Source: https://ona.com/docs/ona/editors/zed Connect to Ona environments using Zed editor via SSH. Zed connects to Ona environments over SSH. It does not use the one-click open flow in the dashboard, so setup requires the [Ona CLI](/docs/ona/integrations/cli). ## Prerequisites 1. [Zed](https://zed.dev/download) installed. 2. The [Ona CLI](/docs/ona/integrations/cli) installed. ## Connecting to an environment 1. Run `ona env ssh-config` to configure your local SSH settings. Verify `~/.ssh/ona` exists after running. 2. Start an environment in Ona. Copy the SSH host from the environment details page. The format is `.ona.environment` (e.g., `01922350-2462-79da-8c80-770fe4275aa2.ona.environment`). 3. In Zed, open the remote projects dialog (`Cmd+Shift+P`, type `remote`). Add a connection using the SSH host. Once connected, you have access to the repository, tools, and services in the environment. Ensure the environment has started before connecting. ## Troubleshooting Confirm the environment is running and copy the host again from the environment details page. Rerun `ona env ssh-config` on your local machine and check that `~/.ssh/ona` exists. The issue is usually in the environment configuration rather than in Zed itself. See [Zed remote development docs](https://zed.dev/remote-development) and the [Ona CLI](/docs/ona/integrations/cli) page for more. # Using environments from external agents Source: https://ona.com/docs/ona/environments/agent-environments Manage Ona environments from external AI agents like Claude Code or Cursor using the Ona CLI. Use the Ona CLI to create, manage, and run commands in environments from external AI agents such as Claude Code, Cursor, or custom scripts. This guide covers the full lifecycle: discover resources, create an environment, execute commands, and clean up. ## Prerequisites * [Ona CLI installed](/docs/ona/integrations/cli) * Authenticated via `ona login` * At least one [runner](/docs/ona/runners/ona-cloud) available in your organization ## Discover projects List projects to find one to create an environment from: ```bash theme={null} ona project list ``` Use `-o json` for machine-readable output: ```bash theme={null} ona project list -o json ``` ## Discover environment classes Environment classes define the compute resources (CPU, memory) for your environment. List available classes: ```bash theme={null} ona environment list-classes ``` Filter by runner: ```bash theme={null} ona environment list-classes --runner ``` ## Create an environment ### From a project The simplest way. The project already has a repository URL, environment class, and configuration: ```bash theme={null} ona environment create ``` ### From a context URL Create directly from a repository URL. Requires an environment class: ```bash theme={null} ona environment create --class-id ``` Both creation methods support `--inactivity-timeout` to set a custom auto-stop timeout. See [auto-stop timeout](/docs/ona/organizations/policies/environment-timeout) for details and examples. ### Non-blocking creation Use `--dont-wait` to return the environment ID immediately without waiting for it to start: ```bash theme={null} ENV_ID=$(ona environment create --dont-wait) ``` Then poll for readiness: ```bash theme={null} ona environment get "$ENV_ID" -o json ``` ## List environments ```bash theme={null} ona environment list ``` Filter to JSON for parsing: ```bash theme={null} ona environment list -o json ``` ## Run commands Execute commands inside a running environment using `exec`: ```bash theme={null} ona environment exec -- ``` The command runs inside the environment's dev container via the EnvironmentOps API (not SSH). The CLI waits for the command to complete and prints stdout/stderr. ### Examples ```bash theme={null} # Run a build ona environment exec -- make build # Run tests with a longer timeout ona environment exec --timeout 300 -- npm test # Run in a specific directory ona environment exec --working-dir /workspace/myproject -- cargo test # Get structured output for parsing ona environment exec -o json -- echo hello ``` ### Exit codes The CLI exits with the same exit code as the remote command. A non-zero exit code means the command failed. ### Flags | Flag | Default | Description | | --------------- | ---------------- | ---------------------------------------- | | `--timeout` | `120` | Command timeout in seconds | | `--working-dir` | workspace folder | Working directory inside the environment | | `-o json` | table | Output format (json, yaml, table) | ## SSH access For interactive sessions or when you need a persistent shell: ```bash theme={null} ona environment ssh ``` Run a single command over SSH: ```bash theme={null} ona environment ssh -- ls -la ``` See the [CLI reference](/docs/ona/reference/cli) for SSH setup details. ## Clean up Stop an environment to preserve its state: ```bash theme={null} ona environment stop ``` Delete an environment permanently: ```bash theme={null} ona environment delete ``` ## Full workflow example End-to-end script that creates an environment, runs a command, and cleans up: ```bash theme={null} #!/bin/bash set -euo pipefail # Create environment from a project, wait for it to start ENV_ID=$(ona environment create --dont-wait) echo "Created environment: $ENV_ID" # Wait for the environment to be running ona environment start "$ENV_ID" # Run commands ona environment exec "$ENV_ID" -- npm install ona environment exec "$ENV_ID" --timeout 300 -- npm test # Clean up ona environment delete "$ENV_ID" echo "Done" ``` ### JSON workflow for agents Agents that parse structured output can use `-o json` throughout: ```bash theme={null} # Create and capture the environment ID (--dont-wait prints the ID directly) ENV_ID=$(ona environment create --dont-wait) # Check status STATUS=$(ona environment get "$ENV_ID" -o json | jq -r '.[0].phase') # Run a command and parse the result RESULT=$(ona environment exec "$ENV_ID" -o json -- echo hello) EXIT_CODE=$(echo "$RESULT" | jq -r '.[0].exit_code') STDOUT=$(echo "$RESULT" | jq -r '.[0].stdout') ``` # Archive & auto-delete Source: https://ona.com/docs/ona/environments/archive-auto-delete How Ona archives and deletes inactive environments. Ona manages inactive environments in two stages: archival after a period of inactivity, then auto-deletion based on your plan and organization policy. ## Timelines | Plan | Archive after | Auto-delete after archival | | ---------- | ---------------------------------------------- | ---------------------------------- | | Core | 3 days | 4 days | | Enterprise | 3 days by default; configurable from 1-30 days | Configurable (1-4 weeks, or never) | Environment lifecycle ## Archiving Stopped environments are archived after the inactive period for your plan. Enterprise organization policies can replace the default archive timing. You can also archive an environment manually from its actions menu or the CLI: ```bash theme={null} ona environment archive ``` If the environment is running, Ona stops it before moving it to Archived. The CLI accepts an environment ID, unique partial ID, or exact name. Archived environments move to a separate view and can be unarchived or deleted. You receive an email when environments are archived automatically. ## Viewing archived environments Open **User settings > Archived sessions** to view archived environments. Archived sessions page in user settings ## Managing archived environments Select archived environments with the row checkboxes to use bulk actions, or open a row's actions menu to manage one environment. * **Unarchive** - returns the environment to your main list. * **Delete** - permanently removes the environment after you confirm. Deleting an environment permanently removes all content. This cannot be undone. ## Archive timing settings Enterprise admins can configure when stopped environments move to Archived from **Settings > Organization > Policies**. The minimum is 1 day and the maximum is 30 days. Core organizations archive stopped environments after 3 days. See [Archive timing policy](/docs/ona/organizations/policies/archive-timing) for details. ## Auto-delete settings Archived sessions auto-delete dropdown in user settings Options: **After 1 day**, **After 2 days**, **After 3 days**, **After 4 days**, **After 5 days**, **After 1 week**, **After 2 weeks**, **After 4 weeks**, or **Never**. Auto-delete preferences are available on Enterprise plans. Core organizations auto-delete environments 4 days after archival. Organization policies and plan limits override user preferences when more restrictive. Disabled options in the dropdown indicate those restrictions. ## FAQ Core environments archive after 3 days of inactivity. Enterprise environments archive after 3 days by default, or after the organization policy period. No. Only archived environments can be restored. Your organization policy enforces a maximum retention period. Automatic archival only applies to stopped environments. If you archive a running environment manually, Ona stops it before moving it to Archived. Check organization policy restrictions. # Development environments Source: https://ona.com/docs/ona/environments/overview Isolated development workspaces for humans and agents. Ona environments are isolated development workspaces for humans and agents. Each environment combines compute, storage, your repository, and your development tooling into a reproducible setup. ## Key concepts * **[Projects](/docs/ona/create-first-project)**: connect a repository to Ona with shared configuration, access controls, and secrets. * **Environments**: running workspaces for development, review, debugging, or focused tasks. * **[Codex Agent](/docs/ona/agents/codex)**: works inside environments with the same tools a developer would use. * **[Automations](/docs/ona/automations/overview)**: create environments on triggers like PRs, schedules, or webhooks. ## What's inside an environment | Component | Description | | ---------------- | ---------------------------------------------------------------------------------------------------------------------- | | Compute | From [Ona Cloud](/docs/ona/runners/ona-cloud) or your own [runner](/docs/ona/runners/overview) | | Dev Container | Image, tools, extensions, and workspace setup. See [Container configuration](/docs/ona/configuration/devcontainer/overview) | | Tasks & services | Databases, servers, watchers. See [Startup tasks & services](/docs/ona/configuration/tasks-and-services/overview) | | Dotfiles | Personal shell and editor customization. See [Dotfiles](/docs/ona/configuration/dotfiles/overview) | | Editor access | Browser, VS Code, Cursor, JetBrains, CLI, or SSH. See [Editors](/docs/ona/editors/overview) | ## Lifecycle * **Create**: start an environment from a project — choose a branch and environment class. * **Provision**: Ona sets up compute, starts your Dev Container, and runs setup hooks. * **Work**: you or an agent connect and start developing. * **Stop**: storage persists so you can resume later. * **Archive**: after inactivity, Ona [archives and can auto-delete](/docs/ona/environments/archive-auto-delete) the environment. ## Storage and isolation Environments are isolated from each other. Storage persists across stops and starts of the same environment. Creating a new environment starts fresh from the project configuration and any available prebuild. See [Persistent storage](/docs/ona/environments/persistent-storage) for what survives Dev Container rebuilds and how prebuilds interact with storage. To share a running service, use [port sharing](/docs/ona/integrations/ports). ## Faster starts [Prebuilds](/docs/ona/projects/prebuilds) snapshot your Dev Container setup so new environments skip slow installation steps. On supported AWS runners, [warm pools](/docs/ona/projects/warm-pools) keep pre-initialized instances ready. ## Configuration * **[Container configuration](/docs/ona/configuration/devcontainer/overview)**: image, tools, mounts, editor customizations * **[Startup tasks & services](/docs/ona/configuration/tasks-and-services/overview)**: long-running processes and one-off tasks * **[Dotfiles](/docs/ona/configuration/dotfiles/overview)**: personal shell and editor setup * **[Multi-repository environments](/docs/ona/configuration/multi-repository)**: work across multiple repos New to Ona? Start with [Set up your first environment](/docs/ona/configuration/devcontainer/getting-started). # Persistent storage Source: https://ona.com/docs/ona/environments/persistent-storage What persists in Ona environments across stops, starts, and Dev Container rebuilds. Ona environments use persistent storage attached to the underlying VM. Everything on disk persists across environment stops and starts. ## What persists * `/workspaces/` - your cloned repository and any changes * `/home/gitpod` - home directory, shell history, installed tools * System packages installed during setup * Files created anywhere on the filesystem Stop an environment, come back later, and continue where you left off. ## Dev Container rebuilds Rebuilding your Dev Container recreates most of the filesystem from the image. Your repository at `/workspaces/` persists via a bind mount - code and uncommitted changes remain intact. To persist other directories across rebuilds, add bind mounts in your `devcontainer.json`: ```json theme={null} { "mounts": [ "source=/workspaces/.cache,target=/home/gitpod/.cache,type=bind" ] } ``` ## Prebuilds and storage [Prebuilds](/docs/ona/projects/prebuilds) snapshot the entire Dev Container filesystem - installed dependencies, built artifacts, and all files. New environments load from this snapshot instead of running setup from scratch. ## Storage size Storage size is configured through [environment classes](/docs/ona/runners/aws/environment-classes). Each runner type ([Ona Cloud](/docs/ona/runners/ona-cloud), [AWS](/docs/ona/runners/aws/environment-classes), [GCP](/docs/ona/runners/gcp/overview)) provides classes with different disk sizes. Use storage larger than RAM. ## Storage lifecycle | State | Storage | | --------------------------------------------------------------------------------------- | ---------------------------- | | Stopped | Persists - resume anytime | | Archived (after inactivity, [by plan or policy](/docs/ona/environments/archive-auto-delete)) | Persists - can be unarchived | | Deleted | Permanently removed | ## Ephemeral vs persistent For agents, the recommended workflow is [ephemeral environments](/docs/ona/configuration/devcontainer/optimizing-startup-times) - one fresh environment per task for isolation. With prebuilds, starting fresh is fast enough that persistence is not needed. For human developers, persistent environments work well for longer-running tasks where you want to maintain state across sessions. ## Troubleshooting Check usage with `df -h`. Select the **Regular** environment class (80 GB), or choose a larger class if your plan supports it. # Overview Source: https://ona.com/docs/ona/getting-started The platform for background agents. Ona home screen showing a new session prompt, left navigation, and quick actions for common coding tasks Ona is the platform for background agents. Run a team of AI software engineers in the cloud, orchestrated, governed, and secured at the kernel. Get started in less than 5 minutes on [Ona Cloud](/docs/ona/runners/ona-cloud), or run Ona in your own VPC on [AWS](/docs/ona/runners/aws/overview) or [GCP](/docs/ona/runners/gcp/overview). Start a single interactive session, or run fleets of agents in the background on a schedule, on pull request events, or from your issue tracker. Here's what you can do with Ona: * **Create reproducible environments**: Define your dev setup as code with [Dev Containers](/docs/ona/configuration/devcontainer/overview) and [Automations](/docs/ona/automations/overview), so every environment starts identically. No "works on my machine" problems * **Write code**: Describe what you want to build, and Ona will implement it. Bring your configuration from Claude Code or Cursor, or add an [AGENTS.md](/docs/ona/agents-md) and [skills](/docs/ona/agents/skills) to make Ona even more productive * **Automate software development**: Assign issues to Ona in [Linear](/docs/ona/integrations/configure-linear) or trigger agents on [pull request events](/docs/ona/automations/triggers/pullrequest). Anything your engineering team can do, Ona can do it too * **Integrate with your stack**: Connect [source control](/docs/ona/source-control/overview), [IDEs](/docs/ona/editors/overview), and tools like [Jira](/docs/ona/integrations/configure-atlassian) and [Notion](/docs/ona/integrations/configure-notion) * **Govern at scale**: Enforce policies, audit changes, and control agent execution with [guardrails](/docs/ona/guardrails/overview) * **Secure by design**: Ephemeral, isolated environments with [SSO](/docs/ona/sso/overview), [OIDC](/docs/ona/configuration/oidc), and SCIM built in Get started with Ona # Browser extension Source: https://ona.com/docs/ona/integrations/browser-extension One-click environment creation from GitHub, GitLab, Bitbucket, and Azure DevOps. The browser extension adds an "Open in Ona" button to repository pages on GitHub, GitLab, Bitbucket, and Azure DevOps (including self-hosted instances). GitHub repository page showing Ona button added by browser extension ## Install | Browser | Link | | ------------------- | ---------------------------------------------------------------------------------------------------- | | Chrome, Edge, Brave | [Chrome Web Store](https://chromewebstore.google.com/detail/gitpod/dodmmooeoklaejobgleioelladacbeki) | | Firefox | [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/onahq/) | ## Settings Click the extension icon in your browser toolbar to access settings. The settings panel is the same across Chrome, Edge, Brave, and Firefox. Browser extension settings ## Self-hosted SCM providers The extension works automatically on `github.com`, `gitlab.com`, `bitbucket.org`, and `dev.azure.com`. For self-hosted instances (GitLab CE/EE, Bitbucket Datacenter), enable **Run on all sites** in the extension settings, or right-click the extension icon and select **Enable on this domain**. ## Custom Ona instance If using a self-hosted Ona instance, open the extension settings and enter your instance URL. ## Migrating from Gitpod Classic If the extension's "Open" button launches Gitpod Classic instead of Ona, update the Ona URL: 1. Click the extension icon in your browser toolbar 2. Either enable **Automatic instance hopping** and visit [app.ona.com](https://app.ona.com) to trigger the update, or manually set the **Ona URL** to `https://app.ona.com` The extension is [open source](https://github.com/gitpod-io/browser-extension). # CLI Source: https://ona.com/docs/ona/integrations/cli Manage environments, SSH access, and automations from your terminal. Manage environments from your terminal - create, start, stop, SSH into environments, and run automations. ## Installation ### Homebrew (macOS and Linux) ```bash theme={null} brew install gitpod-io/tap/ona ``` The formula auto-detects your OS and architecture. Updates are handled by `brew upgrade ona`. ### macOS and Linux ```bash theme={null} curl -o ona -fsSL "https://app.gitpod.io/releases/cli/stable/gitpod-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/;s/\(arm64\|aarch64\)/arm64/')" && \ chmod +x ona && \ sudo mv ona /usr/local/bin ``` ### Direct download | Platform | Downloads | | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | macOS | [x86\_64](https://app.gitpod.io/releases/cli/stable/gitpod-darwin-amd64) \| [arm64](https://app.gitpod.io/releases/cli/stable/gitpod-darwin-arm64) | | Linux | [x86\_64](https://app.gitpod.io/releases/cli/stable/gitpod-linux-amd64) \| [arm64](https://app.gitpod.io/releases/cli/stable/gitpod-linux-arm64) | | Windows | [x86\_64](https://app.gitpod.io/releases/cli/stable/gitpod-windows-amd64.exe) \| [arm64](https://app.gitpod.io/releases/cli/stable/gitpod-windows-arm64.exe) | After downloading, make the binary executable and move it to your PATH: ```bash theme={null} chmod +x ona sudo mv ona /usr/local/bin ``` If macOS shows a security warning, approve the app in **System Settings → Privacy & Security**, or run: ```bash theme={null} xattr -d com.apple.quarantine ona ``` **Verified installation** Use SLSA verification during initial installation: ```bash theme={null} curl -fsSL https://app.gitpod.io/releases/cli/install.sh | VERIFY_SLSA=true bash ``` Requirements: `curl`, `jq`, `awk`, `base64`, and either `sha256sum` or `shasum`. Legacy releases also require `tar`. If SLSA verification fails, the installation aborts with an error. There is no fallback to an unverified download. **[SLSA](https://slsa.dev) verification behavior** Use the verified installer above for both supported release layouts. It verifies legacy `packageHash` attestations and schema-v1 per-platform provenance with a pinned, checksummed Cosign binary before installing the CLI. **Checksum verification** Get the expected checksum: ```bash theme={null} curl -sL https://app.gitpod.io/releases/cli/stable/manifest.json | jq -r '.downloads[""].digest' ``` Calculate your file's checksum and compare: ```bash theme={null} shasum -a 256 ona ``` ## Authentication ### Browser login ```bash theme={null} ona login ``` Opens your browser to authenticate and stores credentials locally. ### Personal access token For CI/CD pipelines and scripts, use a [personal access token](/docs/ona/integrations/personal-access-token): ```bash theme={null} ona login --token "your-token-here" ``` Or set the environment variable: ```bash theme={null} export ONA_TOKEN="your-token-here" ona login ``` ### Inside Ona environments The CLI is pre-installed and automatically authenticated with limited access. Run `ona login` to upgrade to full access. When running inside an environment, the CLI automatically detects the current environment context. This means: * **Environment ID is inferred**: Commands like `ona environment task`, `ona environment service`, `ona environment port`, and other environment-specific commands work without requiring `--environment-id` * **Context preserved after login**: When you run `ona login` inside an environment, the environment ID is preserved in your CLI context (as long as the login host matches the environment's host). This allows you to continue using environment-specific commands after authentication. ```bash theme={null} # Inside an environment - no --environment-id needed ona environment service list ona environment port open 3000 # After running ona login, these still work without --environment-id ona login ona environment task start my-task ``` If you log into a different host than your environment (e.g., logging into `app.gitpod.io` from an environment on `ona.e-corp.com`), the environment ID will not be preserved. `ona environment port open` defaults to creator-only access. On a runner that cannot enforce private access, an implicit open falls back to public access with a warning. Pass `--admission creator_only` to fail closed, or `--admission everyone` when an unauthenticated URL is required. ## Common commands | Command | Description | | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `ona whoami` | Show current user and access level | | `ona environment list` | List your environments | | `ona environment list --search ` | Search environments by ID, name, repository URL, or branch | | `ona environment create ` | Create a new environment | | `ona environment create --inactivity-timeout 1h` | Create an environment with a custom auto-stop timeout | | `ona environment update --name ""` | Rename an environment | | `ona environment update --inactivity-timeout 3h` | Update an environment's auto-stop timeout | | `ona environment start ` | Start an environment | | `ona environment stop ` | Stop an environment | | `ona environment delete ` | Delete an environment | | `ona environment ssh ` | SSH into an environment | | `ona environment logs ` | View environment logs | | `ona environment keep-alive` | [Keep environment alive](/docs/ona/organizations/policies/environment-timeout#keep-environment-alive-during-long-running-tasks) while a process runs | Use `-o json` or `-o yaml` for machine-readable output. ### Using partial environment IDs Instead of typing full UUIDs, you can use any substring of an environment ID: ```bash theme={null} # Full UUID ona environment ssh 019194a6-f0b0-70a1-beae-99718c351b04 # Prefix ona environment ssh 019194a6 # Suffix ona environment ssh 351b04 # Any substring ona environment ssh 70a1-beae ``` The CLI resolves the partial ID if it uniquely identifies an environment. If the substring matches multiple environments, you'll see an error listing all matching IDs. If no environments match, you'll be prompted to run `ona environment list` to see available environments. ### Using environment names Give an environment a memorable name when you do not want to copy its UUID: ```bash theme={null} # Rename an environment ona environment update 019194a6 --name "api-dev" # Use the name after renaming ona environment ssh api-dev ona environment port list api-dev ona environment task start build --environment-id api-dev ``` Most user-facing environment commands accept an environment ID, a unique partial ID, or an exact environment name. Name matching is case-insensitive. To clear a custom name, pass an empty value: ```bash theme={null} ona environment update api-dev --name "" ``` Use `--inactivity-timeout` on `create` or `update` to set a custom auto-stop timeout. See [auto-stop timeout](/docs/ona/organizations/policies/environment-timeout) for details. Names are not required to be unique. If a name matches more than one environment, the CLI asks you to use an environment ID instead. Search across environment IDs, names, repository URLs, and branches with: ```bash theme={null} ona environment list --search api-dev ``` ## SSH access Configure SSH for direct access: ```bash theme={null} ona environment ssh-config ``` Then connect using: ```bash theme={null} ssh .ona.environment ``` Generated SSH aliases and stored CLI contexts use environment IDs, not names. This keeps them stable if an environment is renamed. On macOS, configure SSH and add an environment to Codex with one command: ```bash theme={null} ona env codex ``` The command refreshes the standard Ona SSH configuration and adds the environment's workspace directory to Codex as a remote project. It writes `$CODEX_HOME/codex-app/config.json` (usually `~/.codex/codex-app/config.json`), a Codex Desktop remote-setup payload containing the selected environment, then asks the app to apply it and connect through a Codex-specific SSH alias. The payload replaces any previous payload, but applying it preserves other remote connections and projects already stored by Codex Desktop. The command does not change your normal Codex settings in `$CODEX_HOME/config.toml` (usually `~/.codex/config.toml`) or `environments.toml`. The environment must be running with its workspace directory available. The generated Codex alias does not start stopped environments; start the environment before reconnecting if it has stopped. The `codex` command must be installed and authenticated in the environment. You can also use partial environment IDs or environment names with the `ona environment ssh` command: ```bash theme={null} # Connect using a prefix instead of the full UUID ona environment ssh 019194a6 # Or use any unique substring ona environment ssh beae-997 # Or use an exact environment name ona environment ssh api-dev ``` For file transfers, use the `-O` flag: ```bash theme={null} scp -O .ona.environment:/workspaces/project/file.txt ./local-file.txt ``` ## Port management ```bash theme={null} ona environment port list ona environment port list api-dev ona environment port open --name "my-service" ona environment port close ``` ## Automation commands ```bash theme={null} ona environment config init ona environment config apply .ona/config.yaml ona environment task list ona environment task start ona environment task logs ona environment service list ona environment service start ``` Use `--environment-id ` to target a specific environment from outside that environment. ## Prebuild and warm pool commands ```bash theme={null} # List prebuilds for a project ona prebuild list --project-id # Trigger a prebuild ona prebuild trigger # List all warm pools in the organization ona prebuild warm-pool list # List warm pools for a specific project ona prebuild warm-pool list --project-id # Create a warm pool (project admin required) ona prebuild warm-pool create --environment-class-id --min-size 1 --max-size 2 # Get warm pool details ona prebuild warm-pool get # Update pool scaling bounds ona prebuild warm-pool update --min-size 1 --max-size 3 # Delete a warm pool ona prebuild warm-pool delete ``` See [Warm Pools](/docs/ona/projects/warm-pools) for configuration and auditing details. ## Webhook commands ```bash theme={null} ona webhook create --name "My Webhook" --type repository --scope "owner/repo" --provider github ona webhook secret get ``` See [Webhooks](/docs/ona/automations/webhooks) for setup details and SCM registration. ## Dotfiles management Manage your dotfiles configuration directly from the CLI: ```bash theme={null} # View current dotfiles configuration ona user dotfiles get # Set dotfiles repository ona user dotfiles set --repository https://github.com/user/dotfiles # Clear dotfiles configuration ona user dotfiles set ``` The `get` command supports output formats: ```bash theme={null} ona user dotfiles get -o json ona user dotfiles get -o yaml ``` See [dotfiles documentation](/docs/ona/configuration/dotfiles/overview) for more information about using dotfiles with Ona. ## Project and group management ```bash theme={null} ona project list ona project create ona group list ona group create --name "Team Name" ``` ## Configuration The CLI stores configuration at `~/.ona/configuration.yaml`. ```bash theme={null} ona config context list ona config context use ona config set --autoupdate=true ona config set --verify-slsa=true ona config set --release-channel=latest ona config set --organization-id= ``` ## Shell completion ```bash theme={null} # Bash ona completion bash > /etc/bash_completion.d/ona # Zsh ona completion zsh > "${fpath[1]}/_ona" # Fish ona completion fish > ~/.config/fish/completions/ona.fish ``` ## Updates ```bash theme={null} ona version ona version update ``` ### SLSA verification for updates Enable cryptographic verification of CLI updates to ensure binary integrity: **Per-update verification:** ```bash theme={null} ona version update --verify-slsa ``` **Persistent config:** ```bash theme={null} ona config set --verify-slsa=true ona version update # Now uses verification by default ``` The `--verify-slsa` flag takes precedence over the config value when explicitly set. If SLSA verification fails, the update aborts with an error. There is no fallback to unverified download - this ensures you're always notified of potential tampering. Run `ona help` or add `--help` to any command for more information. ## Troubleshooting ```bash theme={null} ona login --non-interactive # For headless environments ona login --token "" # Use token directly ``` If you see `too many authentication failures`, add to `~/.ssh/ona/config`: ``` Host *.ona.environment IdentitiesOnly yes ``` Debug with: ```bash theme={null} ssh -vvv .ona.environment ``` # Atlassian Source: https://ona.com/docs/ona/integrations/configure-atlassian Connect agents to Jira and Confluence so they can manage issues, search documentation, and stay in sync with your workflow. Connect Atlassian so agents can create Jira issues, search Confluence pages, and link code changes to tickets. ## What agents can do with Atlassian Once connected, agents can: * **Manage Jira issues**: Create, update, and transition issues with relevant context from your codebase. * **Search Confluence**: Find documentation, design specs, and runbooks without leaving your session. * **Link code to work**: Associate pull requests and code changes with Jira tickets automatically. * **Add comments**: Document findings, link PRs, or note blockers directly in Jira issues. ## Example workflows ``` "Create a Jira issue for this authentication bug with the stack trace" "Search Confluence for the API rate limiting design doc" "Move issue PROJ-456 to In Progress and add a comment that I'm starting work" "Find any existing Jira issues about database timeouts before I create a new one" ``` ## Connect Atlassian ### Step 1: Atlassian admin configuration Atlassian requires org admins to explicitly allowlist domains that can connect via MCP. Without this, users will see a cryptic error: **"Your organization admin must authorize access from a domain to this site"**. An Atlassian organization admin needs to allowlist Ona's domain first: 1. Go to [admin.atlassian.com](https://admin.atlassian.com) > **AI settings** > **Rovo MCP server** 2. Add `https://app.gitpod.io/**` to **"Your domains"** ### Step 2: Organization setup An Ona organization admin needs to enable Atlassian for your organization. 1. Go to **Organization Settings** > **Integrations** 2. Find Atlassian and click **Enable** 3. Configure default site and project settings if needed Enable Atlassian in organization settings ### Step 3: Authenticate your account Once enabled, connect your personal Atlassian account: 1. Go to **User Settings** > **Integrations** 2. Click **Connect** next to Atlassian 3. Authorize Ona to access your Atlassian site 4. Select which sites to connect Connect your Atlassian account ## Verify it works Start a session with an agent and try: ``` Show me my open Jira issues ``` If you see your issues, you're connected. If not, verify both organization enablement and your personal authentication are complete. ## Tips for effective use **Be specific about projects**: If you have multiple Jira projects, specify which one: "Create an issue in the API project for this bug." **Include context**: The more context you give, the better the issue: "Create a Jira issue for this null pointer exception, include the stack trace and the user flow that triggers it." **Use with AGENTS.md**: Add your Atlassian conventions to AGENTS.md so agents know your project keys, issue types, and workflow stages. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) including your Atlassian conventions * [Organization-level skills](/docs/ona/skills) for common Atlassian workflows like `/bug-report` * [Learn about integrations](/docs/ona/integrations/overview) for other available connections ## Troubleshooting Your Atlassian organization admin has not allowlisted Ona's domain for MCP access. Ask them to go to [admin.atlassian.com](https://admin.atlassian.com) > **AI settings** > **Rovo MCP server** and add `https://app.gitpod.io/**` to **"Your domains"**. Atlassian accounts can have access to multiple sites. Ensure you authorized access to the correct site during the OAuth flow. You can disconnect and reconnect to update your site selection. # Codex Source: https://ona.com/docs/ona/integrations/configure-codex Connect your ChatGPT account so Codex sessions in Ona can use your ChatGPT plan. Available on the Core plan. ChatGPT plan connections for Codex are currently supported on Ona Cloud only. [Contact sales](https://ona.com/contact/sales) to learn more. Connect Codex when you want the Codex agent in Ona to use your ChatGPT plan for model requests. You can use Codex without this integration; without it, Codex uses the model access available to your organization. This page covers the ChatGPT connection. For the agent itself, see [Codex Agent](/docs/ona/agents/codex). The running environment still consumes OCUs, but Codex model requests that use your ChatGPT plan are not billed by Ona. ## How Codex uses your ChatGPT plan Codex runs inside the same isolated Ona Cloud environments as other agents. It can read your repository, use configured tools, run commands, and open pull requests while following your organization's policies. After you connect your ChatGPT account, the Codex agent uses your ChatGPT plan for model requests. The connection changes model billing and limits only. Ona still provisions and meters the environment that Codex works in. ## Prerequisites * Your organization is on the Core plan. * Your organization uses Ona Cloud. * An organization admin enabled the Codex integration. * You have a ChatGPT account with Codex access. If Codex is not listed under **User Settings > Integrations** or the service account's **Integrations** section, ask an organization admin to enable it or contact Ona support. ## Connect your ChatGPT account 1. Go to [User Settings > Integrations](https://app.ona.com/?user-settings=integrations). 2. Find **Codex**. 3. Click **Connect**. 4. Ona opens the OpenAI device authorization page and copies a one-time code. 5. Sign in to ChatGPT, enter the code, and approve the authorization. 6. Return to Ona. The dialog updates when the account is connected. ## Connect Codex for a service account Connect Codex to a service account when automations running as that service account should use a ChatGPT plan. 1. Go to **Settings > Members > Service Accounts**. 2. Open the service account. 3. In **Integrations**, find **Codex**. 4. Click **Connect**. 5. Ona opens the OpenAI device authorization page and copies a one-time code. 6. Sign in to ChatGPT, enter the code, and approve the authorization. 7. Return to Ona. The dialog updates when the account is connected. ## Use Codex in Ona Start an environment, open the conversation menu, and choose **Codex** when it is available. If you connected your ChatGPT account, Codex uses your ChatGPT plan for model requests from your user session. If a service account has a Codex connection, automations running as that service account can use that connection. If you disconnect the integration, future Codex sessions for that user or service account fall back to the model access available to your organization. ## Billing and limits * OpenAI manages ChatGPT plan usage. Ona does not charge OCUs for Codex model requests that use your connected ChatGPT account. * Ona still charges for the environment while it is running. See [Cost & Budgets](/docs/ona/billing/usage). * If ChatGPT rate limits or usage limits are reached, Codex can pause or fail until the limit resets or your ChatGPT plan changes. ## Disconnect Codex 1. Go to [User Settings > Integrations](https://app.ona.com/?user-settings=integrations), or open the service account details page. 2. Find **Codex**. 3. Click **Disconnect**. ## Troubleshooting The integration is not enabled for your organization yet. Ask an organization admin to check **Organization Settings > Integrations**, or contact Ona support. Close the dialog and click **Connect** again to start a new authorization flow. If you completed OpenAI Trusted Access for Cyber verification after connecting Codex to Ona, disconnect Codex and connect it again. Sign in with the same ChatGPT account you verified, then start a new Codex conversation. Reconnecting starts a new OpenAI authorization and replaces the saved credentials. OpenAI may still block some requests after verification. If the error continues, review [OpenAI's Daybreak troubleshooting guide](https://help.openai.com/en/articles/20001259-openai-daybreak-common-issues-and-troubleshooting). The connected ChatGPT account has likely reached a Codex limit set by OpenAI. Check your ChatGPT plan and billing details, then retry after the limit resets. # GitHub Source: https://ona.com/docs/ona/integrations/configure-github Enable the GitHub integration for one or more GitHub organizations. This page is for the organization admin who enables the GitHub integration. For end-user usage, see [Mention Ona on a pull request](/docs/ona/integrations/github-pr-mentions). The GitHub integration uses the Ona GitHub App. It is separate from [GitHub source control](/docs/ona/source-control/github), which configures repository access for environments. ## Prerequisites * You are an admin of an Ona organization. * You use GitHub.com. For GitHub Enterprise Server, use a [webhook event source](/docs/ona/automations/webhooks) for pull request triggers. * You have admin rights on the GitHub.com organization (or personal account) where the App will be installed. ## Enable GitHub 1. In Ona, go to **Organization Settings** > **Integrations**. 2. Find **GitHub** and turn on the switch. 3. GitHub opens. Choose the organization (or your personal account) to install the App on. 4. Choose which repositories the App can access: * **All repositories**: the App can be mentioned on every PR in the org. * **Only select repositories**: pick a subset. You can change this later from GitHub. 5. Approve the permissions request and finish the install on GitHub. 6. Ona shows the enabled status on the integration page. ## Connect another GitHub organization Connect each GitHub organization that owns repositories you want to use with Ona. 1. In Ona, go to **Organization Settings** > **Integrations**. 2. Find **GitHub** and click the ellipsis button to open **GitHub organizations**. 3. Click **Install into another GitHub organization**. 4. In GitHub, choose the organization and the repositories the App can access. 5. Approve the permissions request and finish the install. 6. Return to Ona. The organization appears in the **GitHub organizations** dialog. ## Permissions | Permission | Access | Why | | ------------- | ------------ | --------------------------------------------------------------------------- | | Pull requests | Read & write | Read PR metadata and post agent status comments. | | Issues | Read & write | Read and post comments on PRs. GitHub treats PR comments as issue comments. | | Contents | Read | Look up the repository associated with a PR. | | Metadata | Read | Required by GitHub for any App. | If a permission is missing, Ona posts a `[!CAUTION]` comment on the PR: > Ask an organization admin to update the Ona GitHub App installation and grant read & write access to **issues** and **pull requests**. To fix it, open the App in GitHub, accept the new permissions, then ask the user to mention the agent again. ## Verify the installation 1. Open a pull request in a repository the App can access. 2. Post a comment containing `@ona-agent`. 3. Within a few seconds, the agent will react to your comment and post a reply with the running session. If nothing happens, see [Troubleshooting](/docs/ona/integrations/github-pr-mentions#troubleshooting). ## Change which repositories the App can access 1. Go to your GitHub organization's **Settings** > **GitHub Apps** > **Ona**. 2. Click **Configure**. 3. Under **Repository access**, add or remove repositories. 4. Save. The change takes effect immediately. ## Disable GitHub Disable a GitHub organization if you want to stop Ona from responding to PR mentions for that organization without uninstalling the App on GitHub (for example, during a migration or incident). 1. In Ona, go to **Organization Settings** > **Integrations**. 2. Find **GitHub** and click the ellipsis button to open **GitHub organizations**. 3. Turn off the switch for the GitHub organization you want to disable. 4. Click **Done**. While disabled: * The App stays installed on GitHub and keeps receiving webhook events for that GitHub organization, but Ona ignores them. No new agent sessions start for `@ona-agent` mentions in repositories owned by that organization. * Other enabled GitHub organizations keep working. To resume, open **GitHub organizations** and turn the organization's switch back on. ## Uninstall the App 1. Go to your GitHub organization's **Settings** > **GitHub Apps** > **Ona**. 2. Click **Configure**, scroll to **Uninstall**, and confirm. Uninstalling stops PR mention triggers for that GitHub organization. Sessions already running keep running. New sessions start again only when the App is reinstalled. ## Next steps * [Mention Ona on a pull request](/docs/ona/integrations/github-pr-mentions): what users do once GitHub is enabled. * [GitHub source control](/docs/ona/source-control/github): repository access for environments. * [Integrations overview](/docs/ona/integrations/overview). # Granola Source: https://ona.com/docs/ona/integrations/configure-granola Connect agents to your Granola meeting notes so they can search transcripts, extract action items, and access meeting context. Connect Granola so agents can search your meetings, read transcripts, and pull in discussion context during sessions. ## What agents can do with Granola Once connected, agents can: * **Search meeting notes**: Find meetings by title, date, or attendees across your Granola account. * **Read transcripts**: Access full meeting transcripts and notes without leaving your session. * **Extract action items**: Pull out tasks, decisions, and follow-ups from past meetings. * **Answer questions from meetings**: Ask natural language questions about what was discussed in any meeting. ## Example workflows ``` "Search Granola for the last meeting about the payments service" "What action items came out of yesterday's standup?" "Find the meeting where we discussed the database migration plan" "What did the team decide about the API versioning strategy in last week's design review?" ``` ## Connect Granola ### Step 1: Organization setup An admin needs to enable Granola for your organization first. 1. Go to **Organization Settings** > **Integrations** 2. Find Granola and click **Enable** 3. Configure default settings if needed Enable Granola in organization settings ### Step 2: Authenticate your account Once enabled, connect your personal Granola account: 1. Go to **User Settings** > **Integrations** 2. Click **Connect** next to Granola 3. Authorize Ona to access your Granola meeting notes via browser-based OAuth 4. Confirm which meetings and data the integration can access Connect your Granola account ## Verify it works Start a session with an agent and try: ``` Search Granola for my recent meetings ``` If you see results from your account, you're connected. If not, verify both organization enablement and your personal authentication are complete. ## Tips for effective use **Be specific about meetings**: If you have many meetings, give the agent specific details: "Find the meeting with the design team from last Tuesday about the onboarding flow." **Combine with code context**: Ask the agent to cross-reference meeting decisions with actual code: "What did we agree on for error handling in the meeting last week? Show me the current implementation." **Use with AGENTS.md**: Add references to recurring meetings or key decisions in AGENTS.md so agents know where to find relevant context from past discussions. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) including references to key meeting decisions * [Organization-level skills](/docs/ona/skills) for common workflows like `/meeting-summary` * [Learn about integrations](/docs/ona/integrations/overview) for other available connections ## Troubleshooting You can only query meetings that you own. Shared meetings from other participants are not accessible through the integration. Make sure the meeting you're looking for is in your own Granola account. Users on Granola's basic plan can only access notes from the last 30 days. If you need older meetings, check your Granola subscription tier. Granola limits requests to approximately 100 per minute. If you're running into errors during heavy use, wait briefly and try again. # Linear Source: https://ona.com/docs/ona/integrations/configure-linear Connect agents to your project management so they can create issues, update status, and stay in sync with your workflow. Connect Linear so agents can create issues, update status as they work, and link code changes to tickets. ## What agents can do with Linear Once connected, agents can: * **Create issues from context**: Find a bug? The agent creates an issue with steps to reproduce, relevant code snippets, and suggested labels. * **Update as they work**: Agents can move issues to "In Progress" when they start and "Done" when they finish. * **Search and reference**: Ask about related issues, find duplicates, or get context from existing tickets. * **Add comments**: Document findings, link PRs, or note blockers directly in Linear. ## Start a session from an issue Beyond the MCP tools above, you can start an agent session directly from a Linear issue in two ways: * **Mention the agent** in an issue comment to start a session on that issue. * **Delegate the issue** to Ona by assigning it, and the agent picks it up. The agent reads the issue for context, works in the matching Ona environment, and posts its progress back on the issue. The session runs under your identity, so it uses your organization role and project permissions. When someone assigns an issue to Ona on another person's behalf, the session runs as the issue's assignee. This requires the agent app authorization from [Step 1](#step-1-organization-setup) to be active. If it is not, see the "Agent features are not active" note under [Troubleshooting](#troubleshooting). ## Example workflows ``` "Create a Linear issue for this authentication bug with the stack trace" "Show me all high-priority issues assigned to me in the API project" "Move issue ABC-123 to In Progress and add a comment that I'm starting work" "Find any existing issues about rate limiting before I create a new one" ``` ## Connect Linear ### Step 1: Organization setup An admin needs to enable Linear for your organization first. 1. Go to **Organization Settings** > **Integrations** 2. Find Linear and click **Enable** 3. Configure default workspace settings if needed Enable Linear in organization settings ### Step 2: Authenticate your account Once enabled, connect your personal Linear account: 1. Go to **User Settings** > **Integrations** 2. Click **Connect** next to Linear 3. Authorize Ona to access your Linear workspace 4. Select which workspaces to connect Connect your Linear account ## Verify it works Start a session with an agent and try: ``` Show me my open Linear issues ``` If you see your issues, you're connected. If not, verify both organization enablement and your personal authentication are complete. ## Tips for effective use **Be specific about projects**: If you have multiple Linear teams, specify which one: "Create an issue in the API team for this bug." **Include context**: The more context you give, the better the issue: "Create an issue for this null pointer exception, include the stack trace and the user flow that triggers it." **Use with AGENTS.md**: Add your Linear conventions to AGENTS.md so agents know your labeling system and workflow stages. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) including your Linear conventions * [Organization-level skills](/docs/ona/skills) for common Linear workflows like `/bug-report` * [Learn about integrations](/docs/ona/integrations/overview) for other available connections ## Troubleshooting This warning means the app authorization for agent capabilities (like @mentions and webhooks) is missing or expired. Basic features like reading and creating issues via MCP tools still work with your personal token. Click **Authorize app** to start the authorization flow. Linear allows only one app installation per workspace. If another Ona organization has already authorized the app on the same Linear workspace, the authorization flow will show that the app is already installed instead of issuing a new token. To resolve this: 1. In Linear, go to **Settings** > **Integrations** > **Ona** and remove the existing installation 2. Return to Ona and click **Authorize app** to re-install for the correct organization Only one Ona organization can have agent features (webhooks, @mentions) active per Linear workspace at a time. Other Ona organizations connected to the same workspace can still use MCP tools (read/write issues) through personal authentication. # Notion Source: https://ona.com/docs/ona/integrations/configure-notion Connect agents to your Notion workspace so they can search pages, read documentation, and access project context. Connect Notion so agents can search your workspace, read documentation, and pull in project context during sessions. ## What agents can do with Notion Once connected, agents can: * **Search your workspace**: Find pages, databases, and documents across your Notion workspace. * **Read documentation**: Access design docs, runbooks, and technical specs without leaving your session. * **Reference project context**: Pull in requirements, meeting notes, and decisions relevant to your current task. * **Add content**: Create and update pages with findings, notes, or documentation. ## Example workflows ``` "Search Notion for the API design doc for the payments service" "Find the onboarding runbook in Notion" "What does the Notion page about our database migration plan say?" "Create a Notion page summarizing the changes I made to the auth module" ``` ## Connect Notion ### Step 1: Organization setup An admin needs to enable Notion for your organization first. 1. Go to **Organization Settings** > **Integrations** 2. Find Notion and click **Enable** 3. Configure default workspace settings if needed Enable Notion in organization settings ### Step 2: Authenticate your account Once enabled, connect your personal Notion account: 1. Go to **User Settings** > **Integrations** 2. Click **Connect** next to Notion 3. Authorize Ona to access your Notion workspace 4. Select which pages and databases to share Connect your Notion account ## Verify it works Start a session with an agent and try: ``` Search Notion for our project documentation ``` If you see results from your workspace, you're connected. If not, verify both organization enablement and your personal authentication are complete. ## Tips for effective use **Be specific about pages**: If you have a large workspace, give the agent specific page or database names: "Find the Q1 planning page in the Engineering space." **Share the right pages**: During Notion authorization, you select which pages the integration can access. Make sure to share the pages your agents will need. **Use with AGENTS.md**: Add references to key Notion pages in AGENTS.md so agents know where to find your team's documentation and conventions. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) including references to your Notion documentation * [Organization-level skills](/docs/ona/skills) for common workflows like `/find-docs` * [Learn about integrations](/docs/ona/integrations/overview) for other available connections ## Troubleshooting Notion's authorization model requires you to explicitly select which pages to share during the OAuth flow. If the agent can't find a page, disconnect and reconnect, ensuring you share the relevant pages. Pages must be explicitly shared with the integration during authorization. You can update your page selection by disconnecting and reconnecting the integration. # Sentry Source: https://ona.com/docs/ona/integrations/configure-sentry Connect agents to Sentry so they can view errors, analyze stack traces, and access monitoring context. Connect Sentry so agents can view errors, analyze stack traces, and use monitoring context to debug issues. ## What agents can do with Sentry Once connected, agents can: * **View issues**: Browse and search Sentry issues, including error messages, frequency, and affected users. * **Analyze stack traces**: Read stack traces and correlate errors with your codebase to identify root causes. * **Search events**: Find specific errors, filter by release or environment, and track regressions. * **Add context**: Reference Sentry issues in sessions and link errors to code changes. ## Example workflows ``` "Show me the most frequent unresolved Sentry issues in production" "What's the stack trace for issue SENTRY-1234?" "Find any Sentry errors related to the payment processing module" "Were there any new errors after the last deployment?" ``` ## Connect Sentry ### Step 1: Organization setup An admin needs to enable Sentry for your organization first. 1. Go to **Organization Settings** > **Integrations** 2. Find Sentry and click **Enable** 3. Configure default project settings if needed Enable Sentry in organization settings ### Step 2: Authenticate your account Once enabled, connect your personal Sentry account: 1. Go to **User Settings** > **Integrations** 2. Click **Connect** next to Sentry 3. Authorize Ona to access your Sentry organization 4. Select which projects to connect Connect your Sentry account ## Verify it works Start a session with an agent and try: ``` Show me recent Sentry issues in production ``` If you see your issues, you're connected. If not, verify both organization enablement and your personal authentication are complete. ## Tips for effective use **Be specific about projects**: If you have multiple Sentry projects, specify which one: "Show me errors in the api-server project." **Include environment context**: Mention the environment when searching: "Find production errors from the last 24 hours." **Use with AGENTS.md**: Add your Sentry project names and conventions to AGENTS.md so agents know your project structure and alerting conventions. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) including your Sentry project conventions * [Organization-level skills](/docs/ona/skills) for common workflows like `/error-report` * [Learn about integrations](/docs/ona/integrations/overview) for other available connections ## Troubleshooting Ensure you authorized access to the correct organization and projects during the OAuth flow. You can disconnect and reconnect to update your project selection. # Slack Source: https://ona.com/docs/ona/integrations/configure-slack Mention Ona in Slack to start and follow agent sessions from a channel or direct message. Connect Slack so you can start agent sessions from a Slack message and follow the work in the same thread. Mention Ona in a channel or send it a direct message, describe the task, and the agent runs in an Ona environment and replies in place. ## What you can do from Slack Once connected, you can: * **Start a session from a channel**: `@Ona` in a channel with a task and a repository link. The agent starts in the matching project's environment and replies in the thread. * **Start a session from a direct message**: Message Ona directly to work without a channel. * **Follow along in the thread**: The agent posts one reply that updates in place as it works, with a link to the Ona session and environment. * **Continue the conversation**: Reply in the same thread to give the agent more instructions. The thread stays tied to one session. ## How it works * The agent runs under **your identity**, mapped from your linked Slack account. It uses your organization role and project permissions. * The agent resolves which project to work in from the repository URL in your message. If your message has no repository link, it reuses the project from earlier in the thread, or asks you to pick a project. * A thread belongs to the user who started it. If someone else mentions Ona in that thread, the agent asks them to start their own thread. * Editing a message after the agent starts does not change the prompt. Post a new mention to change direction. ## Connect Slack Connecting Slack takes two steps: an administrator enables it for the organization, then each user links their own Slack account. ### Step 1: Organization setup An admin needs to enable Slack for your organization first. 1. Go to **Organization Settings** > **Integrations**. 2. Find Slack and click **Enable**. 3. Complete the Slack app installation and authorize it for your workspace. ### Step 2: Authenticate your account Once enabled, connect your personal Slack account so the agent acts with your permissions: 1. Go to **User Settings** > **Integrations**. 2. Click **Connect** next to Slack. 3. Authorize Ona to link your Slack account. If you mention Ona before connecting your account, it replies with a **Connect Slack in Ona** link and resumes your request automatically once you finish connecting. ## Verify it works In a channel where the Ona app is present, or in a direct message, try: ``` @Ona review this repo https://github.com/your-org/your-repo and summarize the README ``` The agent reacts to your message, posts a reply with a link to the running session, and updates that reply as it works. If nothing happens, verify both organization enablement and your personal account link are complete. ## Tips for effective use **Include a repository link**: The agent picks the project from the repository URL in your message. Without one, it falls back to the thread's earlier project or asks you to choose. **Keep one task per thread**: Each thread maps to a single session. Start a new thread for a new task. **Use with AGENTS.md**: Add your project conventions to [AGENTS.md](/docs/ona/agents-md) so agents follow your workflow. ## Next steps * [Integrations overview](/docs/ona/integrations/overview) for other available connections. * [Projects](/docs/ona/projects/overview): required so the agent knows where to run. * [AGENTS.md](/docs/ona/agents-md): teach agents your codebase and conventions. ## Troubleshooting Check, in order: 1. Is Slack enabled for your organization in **Organization Settings** > **Integrations**? 2. Have you linked your Slack account in **User Settings** > **Integrations**? 3. Is the Ona app present in the channel? In a private channel, invite the app first. 4. Did you mention `@Ona` (in a channel) or message it directly? Ona could not map your Slack account to an Ona user. Open the **Connect Slack in Ona** link in the reply, finish connecting your account, and the agent resumes your original request. The agent could not find an Ona project for the repository, or the project has no environment class configured. Create a [project](/docs/ona/projects/overview) for the repository, set an environment class in its settings, and mention Ona again. # Mention Ona on a pull request Source: https://ona.com/docs/ona/integrations/github-pr-mentions Mention @ona-agent in a GitHub pull request comment to start an agent on the PR. Available on the Core plan. [Contact sales](https://ona.com/contact/sales) to enable it for Enterprise. Mention `@ona-agent` in a pull request comment to start an agent on that PR. The agent reads the PR diff and recent comments, then works on the task you describe. For setup, see [GitHub](/docs/ona/integrations/configure-github). ## How it works * The agent runs under **your identity**, mapped from your linked GitHub login. It uses your organization role and project permissions. Commits and PRs the agent opens are attributed to you. * The Ona GitHub App posts the reactions and reply comments. Your account needs no extra permissions for that. * The agent sees the PR title, body, diff, and recent comments. Its access to the rest of the repository is governed by the [project](/docs/ona/projects/overview) at runtime. * Pull requests from forks are ignored. Fork PRs can carry untrusted code, and anyone with a GitHub account can comment on them. * Per-organization rate limits apply. ## Prerequisites * The [GitHub integration](/docs/ona/integrations/configure-github) is enabled for the GitHub organization that owns the repository. * The repository is in the App's selected repositories. * An Ona [project](/docs/ona/projects/overview) exists for the repository. If one does not, the agent prompts you to create one. ## Where you can mention The agent responds to mentions in three places on a pull request: | Surface | Where it appears | | ------------------------- | -------------------------------------------------------------------------------------------------------------- | | **PR comment** | The main conversation tab. Triggered by `issue_comment` events. | | **Inline review comment** | A comment attached to a specific line in the diff. Triggered by `pull_request_review_comment` events. | | **Review submission** | The body of a submitted review (Approve, Request changes, Comment). Triggered by `pull_request_review` events. | Mentions in regular issues and on fork PRs are ignored. ## Supported handles Use `@ona-agent` to trigger the agent. Mentions inside fenced code blocks, inline code spans, blockquotes, HTML comments, and image syntax are ignored, so you can write about the handle without triggering it. ## Examples ### Request a code review A comment with only the handle starts a review: ``` @ona-agent ``` The agent runs with the prompt `Review this PR and help with any issues.` ### Mention with a task Anything after the handle becomes the agent's prompt: ``` @ona-agent please add unit tests for the new pricing function ``` ``` @ona-agent the snapshot test on line 42 is failing, figure out why and fix it ``` ### Reply on a review thread If you mention the agent in a reply to an inline review comment, the agent receives the surrounding thread as context. ## Commands `@ona-agent retry` replays the last failed agent start on this PR. Use it after fixing the cause (for example, after creating a missing project). The command must be the whole prompt. `@ona-agent retry the deploy` runs as a normal prompt. ## What you'll see 1. The agent reacts to your comment with an emoji to confirm the trigger. 2. It posts one reply with the running session and a link to the Ona session view. 3. The same reply updates in place as the agent works.
## Cancelling To cancel a running session from GitHub: * **Delete your trigger comment.** Cancels the session and posts a confirmation. * **Delete the PR's head branch.** Cancels the session. You can also cancel from the Ona session view. ## Limitations * The agent reads the PR diff and the most recent comments. Older comments are not included. * Fork PRs are not supported. See [How it works](#how-it-works). * Editing a comment after the agent starts does not change the prompt. To change direction, post a new `@ona-agent` comment. * Posting a second `@ona-agent` mention while the first session is still running is not guaranteed to queue. Wait for the first reply, or cancel the running session by deleting the trigger comment. * Available on the Core plan. [Contact sales](https://ona.com/contact/sales) to enable it for Enterprise. ## Next steps * [GitHub](/docs/ona/integrations/configure-github): enable and manage the integration. * [Projects](/docs/ona/projects/overview): required so the agent knows where to run. * [Integrations overview](/docs/ona/integrations/overview). ## Troubleshooting Check, in order: 1. Is the [GitHub integration](/docs/ona/integrations/configure-github) enabled for the repository's owner? 2. Is the repository in the App's selected repositories? 3. Is your Ona organization on the Core plan? 4. Did you spell the handle correctly (`@ona-agent`)? 5. Are you commenting on a **pull request**, not a regular issue? 6. Is the PR from the same repository, not a fork? If all six check out and the agent stays silent for a minute or two, contact support. The agent posted a `[!CAUTION]` comment because the App is missing a required permission. Ask an admin to update the GitHub installation. See [Permissions](/docs/ona/integrations/configure-github#permissions). No Ona project is configured for this repository. The agent posts a link to create one. Once you create it, the agent resumes the original mention. If you do not create the project within a few minutes, the watcher times out and you'll need to mention the agent again. # Open from URL Source: https://ona.com/docs/ona/integrations/ona-url Create environments directly from a repository URL. Create an environment by prefixing any repository URL with `https://app.ona.com/#`: ``` https://app.ona.com/# ``` This provides an alternative to the [browser extension](/docs/ona/integrations/browser-extension). To embed the link in a repository README, see the [README button](/docs/ona/integrations/readme-button) guide. ## Examples | Provider | URL | | --------- | ------------------------------------------------------------ | | GitHub | `https://app.ona.com/#https://github.com/gitpod-io/empty` | | GitLab | `https://app.ona.com/#https://gitlab.com/gitpod-io/empty` | | Bitbucket | `https://app.ona.com/#https://bitbucket.org/gitpod-io/empty` | ## Runner and environment class When you open a repository, you'll be prompted to choose a runner and environment class. To set defaults, create a [Project](/docs/ona/projects/overview) with your preferred configuration. Projects are automatically selected when users open that repository. # Integrations Source: https://ona.com/docs/ona/integrations/overview Connect Ona to source control, work trackers, docs, incident tools, and cloud providers. Ona integrations fall into three categories: * **Source control** for cloning repositories, pushing commits, and letting agents interact with pull requests and issues * **Tool integrations** for giving agents access to work trackers, docs, incident tools, and other MCP-backed services * **Cloud access** for federating from environments into providers like AWS without long-lived credentials This page is the overview. Use the linked setup guides for provider-specific steps. ## Source control Source control is the foundational integration in Ona. It gives environments access to your repositories and lets agents work with the same permissions your developers already have. * [Source control overview](/docs/ona/source-control/overview) * [GitHub & GitLab agent tools](/docs/ona/agents/scm-tools) Supported providers: | Provider | Repo access | Agent API tools | | ------------------------------------------------ | ----------- | --------------- | | [GitHub](/docs/ona/source-control/github) | Yes | Yes | | [GitLab](/docs/ona/source-control/gitlab) | Yes | Yes | | [Bitbucket Cloud](/docs/ona/source-control/bitbucket) | Yes | No | | [Azure DevOps](/docs/ona/source-control/azuredevops) | Yes | No | ## Tool integrations for agents Most non-SCM integrations are exposed to agents through the [Model Context Protocol (MCP)](/docs/ona/mcp). There are two distinct layers, and both must be in place before an agent can use a tool: * **Organization integrations** are configured by an administrator in your organization settings. They turn an integration on for the org (e.g., "Linear is allowed in this organization") and provide the OAuth client and any shared configuration. Without this, the integration does not appear to users. * **Principal authentication** happens after the org integration is enabled. Users connect personal accounts from **User Settings > Integrations**. Service accounts connect from the service account details page so automations can run with service-account credentials. In short: 1. **Organization-level enablement** by an administrator 2. **User or service-account authentication** so the agent acts with the right identity Organization integration settings User authentication for an integration Available integrations: | Integration | What agents can do | Setup | | ----------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------ | | Linear | Read issues, update status, use backlog context, and start sessions from an issue | [Configure Linear](/docs/ona/integrations/configure-linear) | | Slack | Mention Ona to start and follow agent sessions from a channel or DM | [Configure Slack](/docs/ona/integrations/configure-slack) | | Atlassian | Work with Jira and Confluence | [Configure Atlassian](/docs/ona/integrations/configure-atlassian) | | Notion | Search and read workspace docs | [Configure Notion](/docs/ona/integrations/configure-notion) | | Sentry | Inspect errors and issue context | [Configure Sentry](/docs/ona/integrations/configure-sentry) | | Granola | Search meeting notes and transcripts | [Configure Granola](/docs/ona/integrations/configure-granola) | | GitHub | Mention `@ona-agent` on a pull request to start an agent on the PR | [Configure GitHub](/docs/ona/integrations/configure-github) | To check status during a session, open the **MCP Integrations** panel in the prompt input. MCP Integrations panel in the session input ## Cloud access Ona environments can also federate into cloud providers using short-lived credentials instead of static secrets. * [OpenID Connect (OIDC)](/docs/ona/configuration/oidc) for the core model * [AWS access from Ona](/docs/ona/integrations/aws) for the AWS-specific setup GCP follows the same OIDC pattern described in the OIDC guide. ## Related tools Some things that used to get lumped in as "integrations" are better understood as developer interfaces or launch methods: * [CLI](/docs/ona/integrations/cli) * [Ona SDK](/docs/ona/integrations/sdk) * [Personal access tokens](/docs/ona/integrations/personal-access-token) * [Browser extension](/docs/ona/integrations/browser-extension) * [Open from URL](/docs/ona/integrations/ona-url) * [README button](/docs/ona/integrations/readme-button) * [Port sharing](/docs/ona/integrations/ports) # Port sharing Source: https://ona.com/docs/ona/integrations/ports Expose ports from environments to share running services. Expose ports from your Ona environment to share running services with teammates, test webhooks, or preview work without deploying. ## How it works When you open a port, Ona creates a URL with automatic TLS termination. All shared URLs use HTTPS. You can configure whether Ona connects to your service via HTTP (default) or HTTPS. If the runner supports port authentication, each open port also has an access level that controls who can reach the URL. You may need to upgrade the runner before those access controls are available. Until then, shared ports behave like `everyone`. | Deployment | Access | | ------------------ | -------------------------------------------------------------------------------------------------------------------- | | Ona Cloud | Shared URLs are reachable on Ona's network. Port admission can still require organization or creator authentication. | | Enterprise Runners | Through your runner's Network Load Balancer, controlled by your network configuration and the port's admission level | ## Prerequisites Services must: * Listen on `0.0.0.0` (not `localhost` or `127.0.0.1`) * Use the [host network stack](#host-network-stack) if running inside a container ```javascript theme={null} app.listen(3000, '0.0.0.0', () => { console.log('Server running on port 3000'); }); ``` ## Open ports Open ports are accessible according to the port's configured admission level, your organization policy, and your runner network configuration. If access controls are unavailable in the dashboard, the runner may need an upgrade before it supports port authentication. For access level definitions and policy caps, see [Port sharing policy](/docs/ona/organizations/policies/port-sharing#port-access-levels). ### Open a port in the dashboard 1. Open the environment details page and go to **Ports**. 2. Select **Add port**. 3. Enter the port number and optional name. 4. Choose **HTTP** or **HTTPS**. 5. If available, choose an **Access** level. Open port dialog showing the port number, protocol selector, and access level selector If your organization caps the maximum admission level, options above the cap appear as **restricted by policy** in the access dropdown. See [Maximum port admission level](/docs/ona/organizations/policies/port-sharing#maximum-port-admission-level). ### Open a port in VS Code 1. In the Ona view, expand **Ports**. 2. Select **Open Port**. 3. Enter a port name and number. VS Code desktop and VS Code Browser open the port for the environment creator by default. If the runner is too old to enforce private access, VS Code opens the port for everyone instead and shows a warning. The VS Code command cannot request public access explicitly. If you need an unauthenticated URL for a webhook or callback, use `ona environment port open --admission everyone`. ### Open a port from the CLI By default, the CLI opens the port for the environment creator only. If the runner is too old to enforce private access, the CLI opens the port for everyone instead and prints a warning to stderr. For admission level definitions, see [Port access levels](/docs/ona/organizations/policies/port-sharing#port-access-levels). ```bash theme={null} # Use the private-first default ona environment port open 3000 --name my-app # Require private access and fail instead of falling back on an older runner ona environment port open 3000 --name my-app --admission creator_only # Share with other members of your organization ona environment port open 3000 --admission organization # Request unauthenticated access and tell Ona to use HTTPS to your service ona environment port open 8443 --protocol https --admission everyone # Review or close shared ports ona environment port list ona environment port close 3000 ``` Scripts created before this default changed may expect an unauthenticated URL. If unauthenticated access is part of the script's contract, such as a webhook callback, add `--admission everyone` explicitly. ## Access denied and retry When a shared port needs authentication, the browser is sent through Ona's `/auth/port/start` flow before loading the port URL. This flow establishes or refreshes the browser's port-access session and then returns the user to the requested port. If access is still not allowed, Ona shows **Port Access Denied** and explains why. Common reasons include: * The port is shared as `creator_only` or `organization`, and your identity does not satisfy that access level. * Your organization policy blocks the port's current sharing level. * The runner needs an upgrade before it can enforce port access control. Port Access Denied page showing the reason, environment ID, port number, and Retry button Use **Retry** after you sign in, switch to the correct organization, or after the port owner or an admin changes the port admission or policy. Retry reruns `/auth/port/start` with the original environment and port parameters. ## Services that only listen on localhost Some tools hardcode `localhost` as their bind address with no option to change it. AWS SSM port forwarding (`session-manager-plugin`) is a common example. Since Ona's port-sharing proxy connects from outside the loopback interface, these services return "Service Unavailable" (503) when accessed through a shared port URL. Two workarounds are available: ### Option A: iptables (no extra packages) Use kernel-level NAT to redirect incoming traffic to the loopback address. This is already available in the environment and lets you keep the same port number. ```bash theme={null} # Allow routing to loopback addresses (off by default) sudo sysctl -w net.ipv4.conf.all.route_localnet=1 # Redirect external traffic on port 6767 to localhost:6767 sudo iptables -t nat -A PREROUTING -p tcp --dport 6767 -j DNAT --to-destination 127.0.0.1:6767 # Open the port in Ona ona environment port open 6767 --name "my-service" ``` ### Option B: socat (userspace relay) Use `socat` to relay traffic from `0.0.0.0` on a second port to the localhost-bound service. Requires installing `socat` (`apt-get install -y socat`) but does not need root. ```bash theme={null} # Relay from 0.0.0.0:6768 to localhost:6767 socat TCP-LISTEN:6768,fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:6767 # Open the relayed port in Ona (note: different port number) ona environment port open 6768 --name "my-service" ``` ## Host network stack By default, the Dev Container network is isolated from the VM. For port sharing to work, services must be accessible on the host network. There are several scenarios to consider: ### Dev Container network mode To make your Dev Container itself use the host network stack, configure your `devcontainer.json`: **Single container setup:** ```json theme={null} { "name": "My Project", "image": "mcr.microsoft.com/devcontainers/javascript-node:20", "runArgs": ["--network=host"] } ``` **Multi-container setup (Docker Compose):** See [Multi-container development](/docs/ona/configuration/devcontainer/overview#multi-container-development) for complete setup. The key requirement is `network_mode: host` on all services: ```yaml theme={null} # docker-compose.yml services: app: build: . network_mode: host command: sleep infinity db: image: postgres:16 network_mode: host environment: POSTGRES_PASSWORD: postgres ``` ### Containers inside Dev Container (Docker-in-Docker) When running containers inside your Dev Container using Docker-in-Docker, those containers must also share the host network namespace. Otherwise, ports are only accessible within Docker's bridge network and Ona cannot forward them. **Docker run:** ```bash theme={null} # ✗ Won't work - port only accessible on Docker bridge network docker run -d -p 8080:8080 myapp # ✓ Works - port accessible to Ona for forwarding docker run -d --network host myapp ``` **Docker Compose inside Dev Container:** ```yaml theme={null} services: database: image: postgres:16 network_mode: host environment: POSTGRES_PASSWORD: postgres redis: image: redis:7 network_mode: host ``` Without `network_mode: host` or `--network host`, services use Docker's bridge network. Ports mapped with `-p` or `ports:` are only accessible within that bridge network, not from your Dev Container or Ona's port forwarding. ### Ona Tasks and Services When running containerized services with `docker run`, use `--network host` or map ports explicitly with `-p` to make them accessible. See [containerized service examples](/docs/ona/configuration/tasks-and-services/examples#containerized-services) for recommended patterns. ## Relationship to devcontainer port properties The `devcontainer.json` spec includes `forwardPorts` and `portsAttributes` properties. These are standard devcontainer properties that tell the editor which ports to forward from the container and how to configure them (labels, auto-forward behavior). These properties work in Ona across VS Code-based editors, but they operate independently from Ona's port sharing. They do not create shareable URLs or open ports in the Ona dashboard. | Mechanism | What it does | Use case | | ---------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------- | | `forwardPorts` / `portsAttributes` | Editor-managed port forwarding, auto-forward notifications, port labels | Per-developer access in VS Code-based editors | | `ona environment port open` | Ona URL with TLS and configurable access, visible in dashboard | Browser previews, webhooks, and CI integrations | ## Opening a port and previewing in the browser Use the [built-in web browser](/docs/ona/integrations/web-browser) when you want a preview to stay inside the environment page and remain available to Ona. You can open a port and launch the preview URL in a single command using the `$BROWSER` variable: ```bash theme={null} $BROWSER "$(ona environment port open 8000 -n my-app)" ``` To see which ports are currently listening in your environment: ```bash theme={null} ss -tlnp ``` ## Limitations * Ports 1024–65535 can be exposed. System ports (1–1023) are not supported. * Not available on local environments * Subject to fair use policies and bandwidth limits * Organization administrators can disable port sharing via [organization policies](/docs/ona/organizations/policies/port-sharing). VS Code Browser and agents are exempt from this restriction. Network flags like `--network=host` in `build.options` are stripped during Dev Container builds. Host network mode is only applied at runtime when the container starts. # README button Source: https://ona.com/docs/ona/integrations/readme-button Add a "Build with Ona" button to your repository README for one-click environment creation. Add a badge to your repository README so contributors can open the project in an Ona environment with one click. The badge links to `app.ona.com/#` — Ona clones the repo, applies your [Dev Container](/docs/ona/configuration/devcontainer/overview) configuration, and starts the environment automatically. ![Build with Ona](https://ona.com/build-with-ona.svg) ## Markdown ```markdown theme={null} [![Build with Ona](https://ona.com/build-with-ona.svg)](https://app.ona.com/#) ``` Replace `` with the full URL to your repository on any [supported SCM provider](/docs/ona/source-control/overview). For example: ```markdown theme={null} [![Build with Ona](https://ona.com/build-with-ona.svg)](https://app.ona.com/#https://github.com/gitpod-io/empty) ``` ## HTML ```html theme={null} Build with Ona ``` See [Open from URL](/docs/ona/integrations/ona-url) for the full URL format, including pre-selecting a runner or environment class. # Ona SDK Source: https://ona.com/docs/ona/integrations/sdk Create environments, run commands, and start Codex agents from Python, TypeScript, or Go. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. **SDK versions 1.x introduce a new API that is not compatible with versions 0.x.** The package names remain the same, so update your code when upgrading from a 0.x version to a 1.x version. Follow [Migrate from SDK versions 0.x](/docs/api-reference/sdk-migration) for language-specific instructions. Use the Ona SDK to create and manage environments, run commands, access files, and start Codex agents from Python, TypeScript, or Go. ## Install an SDK Install the [`gitpod-sdk` package](https://pypi.org/project/gitpod-sdk/): ```bash theme={null} python -m pip install gitpod-sdk ``` Import the high-level SDK from `ona_sdk`. Python 3.10 or later is required. Install the [`@gitpod/sdk` package](https://www.npmjs.com/package/@gitpod/sdk): ```bash theme={null} npm install @gitpod/sdk ``` The package supports CommonJS and ECMAScript modules on Node.js 20 and later. Install the [`github.com/gitpod-io/gitpod-sdk-go` module](https://github.com/gitpod-io/gitpod-sdk-go): ```bash theme={null} go get github.com/gitpod-io/gitpod-sdk-go ``` Import `github.com/gitpod-io/gitpod-sdk-go/sdk` for high-level workflows. Go 1.25 or later is required. ## Authenticate the SDK Create a [personal access token](/docs/ona/integrations/personal-access-token), then set `ONA_API_KEY`: ```bash theme={null} export ONA_API_KEY="" ``` The SDK reads `ONA_API_KEY` when you use `create_client_from_env`, `createClientFromEnv`, or `sdk.NewFromEnv`. The default API URL is `https://app.ona.com/api`. If your organization uses a custom management-plane domain, also set: ```bash theme={null} export ONA_BASE_URL="https:///api" ``` Python applications can use `create_client(api_key=..., base_url=...)`, and TypeScript applications can use `createClient({ apiKey, baseUrl })`. Do not commit tokens to source control. ## Create an environment and run a command Each high-level client creates a running environment from a repository URL and returns an environment handle. The handle provides command, file, Git, and agent operations. ```python theme={null} from ona_sdk import create_client_from_env ona = create_client_from_env() environments = ona.environments() environment = environments.create( "https://github.com/gitpod-io/template-golang-cli" ) try: result = environment.run_command( command="pwd && git status --short", working_directory=environment.workspace_dir(), ) print(result.stdout) finally: environments.delete(environment.id(), force=True) ``` ```typescript theme={null} import { createClientFromEnv } from "@gitpod/sdk"; const ona = createClientFromEnv(); const environments = ona.environments(); const environment = await environments.create({ contextUrl: "https://github.com/gitpod-io/template-golang-cli", }); try { const result = await environment.runCommand({ command: "pwd && git status --short", workingDirectory: environment.workspaceDir(), }); console.log(result.stdout); } finally { await environments.delete(environment.id(), { force: true }); } ``` ```go theme={null} package main import ( "context" "fmt" "log" "github.com/gitpod-io/gitpod-sdk-go/sdk" ) func main() { ctx := context.Background() ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } environments := ona.Environments() environment, err := environments.Create(ctx, sdk.CreateEnvironmentOptions{ ContextURL: "https://github.com/gitpod-io/template-golang-cli", }) if err != nil { log.Fatal(err) } defer environments.Delete(ctx, environment.ID(), sdk.DeleteEnvironmentOptions{Force: true}) status := environment.Proto().GetStatus() workspaceDir := status.GetDevcontainer().GetRemoteWorkspaceFolder() if workspaceDir == "" { workspaceDir = status.GetContent().GetContentLocationInMachine() } result, err := environment.RunCommand(ctx, sdk.RunCommandOptions{ Command: "pwd && git status --short", WorkingDirectory: workspaceDir, }) if err != nil { log.Fatal(err) } fmt.Print(result.Stdout) } ``` ## Choose high-level workflows or direct API clients Use the high-level SDK for environment and Codex workflows. It handles tasks such as resolving repository context, selecting an environment class, waiting for state changes, connecting to environment operations, and mapping common failures to typed errors. Use the generated clients when the high-level SDK does not cover an API operation: * **Python:** protobuf messages are under `gitpod.v1`, and authenticated synchronous service clients are available from `ona.services`. * **TypeScript:** core service clients are available from `ona.services`. Generated protobuf schemas and service descriptors are exported from subpaths such as `@gitpod/sdk/gitpod/v1/environment_pb`. * **Go:** protobuf messages are in `github.com/gitpod-io/gitpod-sdk-go/v1`, and generated Connect clients are in `github.com/gitpod-io/gitpod-sdk-go/v1/v1connect`. Direct API clients use protobuf request and response messages. See the [API reference](https://ona.com/docs/api-reference) for the available services, methods, and fields. The API also covers organization reporting through the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api) and [AI cost usage API](/docs/ona/billing/cost-usage-api). ## Run the full examples The published SDK packages include runnable examples for environment operations and Codex agents: * [Python package files](https://pypi.org/project/gitpod-sdk/#files): download the source distribution and open `examples/`. * [TypeScript package examples](https://unpkg.com/browse/@gitpod/sdk@latest/examples/) * [Go module source](https://github.com/gitpod-io/gitpod-sdk-go): open `sdk/examples/`. ## Troubleshooting Set `ONA_API_KEY` in the process that starts your application. SDK versions 1.x prefer `ONA_API_KEY`; `GITPOD_API_KEY` is supported as a compatibility fallback. Set `ONA_BASE_URL` to your custom management-plane origin followed by `/api`, for example `https://ona.example.com/api`. Do not use the `vscode.` subdomain. # Terraform provider Source: https://ona.com/docs/ona/integrations/terraform-provider Manage runners, projects, organization settings, automations, and more. Review, version, and apply organization configuration alongside your infrastructure with the [Terraform provider](https://registry.terraform.io/providers/gitpod-io/ona/latest). The provider is in beta. Pin an exact version, review each upgrade, and test upgrades outside production before broad rollout. See the complete [resource reference and configuration examples](https://registry.terraform.io/providers/gitpod-io/ona/latest/docs). ## Common use cases ### Deploy and share runner infrastructure Create a runner record and registration token, then pass the runner ID and token to the cloud module that deploys its infrastructure. This keeps control-plane and cloud resources in one dependency graph. * Use the [AWS runner module](https://github.com/gitpod-io/terraform-aws-ona-runner) to deploy an AWS runner in your VPC. * Use the [GCP runner module](https://registry.terraform.io/modules/gitpod-io/ona-runner/google/latest) to deploy a GCP runner in your project. * Share the registered runner with groups as described in [Sharing resources](/docs/ona/organizations/sharing-resources). The registration token expires after 24 hours and can be used once. Terraform marks it as sensitive but stores it in state so a cloud module can consume it. Use an encrypted, access-controlled remote state backend. ### Standardize organization settings Manage organization-wide settings such as environment lifecycle limits, project creation rules, agent policies, security policies, identity configuration, custom domains, announcements, and terms of service. Some resources reset, disable, or preserve remote settings when destroyed, so review the Registry documentation and the destroy plan before applying a removal. ### Manage and share automations Define an Automation's triggers, execution context, Codex settings, limits, and steps. Grant groups the Viewer, Executor, or Admin role as described in [Sharing Automations](/docs/ona/automations/sharing-automations). ### Manage and share projects Create projects with their repository, branch, environment classes, and prebuild configuration. Import existing projects without recreating them. Grant groups access as described in [Project sharing](/docs/ona/projects/project-sharing). ## Configure the provider Terraform CLI 1.14 or later is required. Packages for Linux `amd64` and Linux `arm64` are available; macOS and Windows packages are not available. Follow the [installation instructions](https://registry.terraform.io/providers/gitpod-io/ona/latest) and pin your chosen version. Create a read-and-write [personal access token](/docs/ona/integrations/personal-access-token) and keep it outside the configuration: ```bash theme={null} export ONA_TOKEN="" terraform init terraform plan ``` Use a token owned by someone who can read and change every managed object. Service account token support varies by API. Use a personal access token for writes unless Support confirms that a service account token works for your use case. If your organization uses a custom management-plane domain, set `ONA_HOST` to that origin: ```bash theme={null} export ONA_HOST="https://" ``` ## Protect state and review destructive changes The `sensitive` marker redacts values in normal command output but does not exclude ordinary attributes from state. Treat state and saved plans as sensitive data. Use write-only arguments and ephemeral resources when the Registry reference lists them. Managed resources support import. Terraform Query can discover many existing resources and generate import blocks, but not for every resource. Removing a resource block usually plans to delete the remote object. Use `terraform state rm
` to stop managing an object without deleting it. Review the [state, secrets, and safe deletion guide](https://registry.terraform.io/providers/gitpod-io/ona/latest/docs/guides/state-secrets-and-safe-deletion) and every destroy plan before applying changes. ## Releases and support * Review the [reference](https://registry.terraform.io/providers/gitpod-io/ona/latest) for supported resources, data sources, imports, and examples. * Follow [releases](https://github.com/gitpod-io/terraform-provider-ona/releases) and the [changelog](https://github.com/gitpod-io/terraform-provider-ona/blob/main/CHANGELOG.md) before upgrading. * Browse the [source repository](https://github.com/gitpod-io/terraform-provider-ona). * Report security issues through the [security policy](https://github.com/gitpod-io/terraform-provider-ona/security/policy). * For account access, organization setup, or product behavior, open **Support** from the organization menu in the dashboard. # Built-in web browser Source: https://ona.com/docs/ona/integrations/web-browser Open the built-in browser in an environment, preview local apps, and share browser context with Ona. Use the built-in web browser to inspect a web app from an Ona environment. When Ona AI is enabled, you can also share page state with Ona and send screenshots from the Browser tab into the conversation. The browser runs inside the environment, so it can access services on that environment's local ports. The built-in web browser is enabled by default for all organization tiers. Enterprise admins can disable it with the [web browser organization policy](/docs/ona/organizations/policies/web-browser). Browser tab open next to an Ona conversation in a running environment ## Where the browser is available The built-in browser appears on environment pages when all of these are true: * The environment is in a phase where actions can be opened, such as a running environment. * The organization allows the built-in browser. * The environment supervisor supports the browser controller. When available, the dashboard shows **Open Browser**, **Preview ... in Browser**, or the **Browser** tab. If the browser is not available, port previews fall back to external shared-port links. The **Annotate browser** and **Send screenshot to Ona** actions appear only when Ona AI is enabled for the organization. ## Enable or disable the browser The browser is enabled by default for Free, Core, and Enterprise organizations. Enterprise admins can disable or re-enable it from **Settings > Organization > Policies > Allow Web Browser in Environments**. Disabling the policy has these effects: * The dashboard hides browser actions and the Browser tab. * Ona does not expose the `browse-web` built-in skill to agents in that organization. * Members cannot start the environment's managed browser session from the dashboard. Disabling the policy does not disable [port sharing](/docs/ona/integrations/ports), [VS Code Browser](/docs/ona/editors/vscode-browser), or editor access. Those features have separate controls. ## Security and ports The built-in browser is separate from shared port URLs. Opening a local app in the Browser tab does not make that app public. For port previews, Ona navigates the managed browser to an environment-local address, such as `http://localhost:3000`. Port sharing is still relevant for the browser's own connection. When the browser starts, Ona declares a managed browser port so the dashboard can connect to the browser session. That managed port is for the Browser tab and is not the same as sharing your app's port with other people. Use [port sharing](/docs/ona/integrations/ports) when you need a URL outside Ona, such as a teammate preview link or a webhook callback URL. Use the built-in browser when you want a preview inside Ona that you and Ona can both inspect. When you ask Ona to open the exact published URL of a protected port in the current environment, Ona authenticates that browser navigation automatically. This does not make the port public or change its admission level. Authentication is scoped to that port URL and reused within the environment's browser session until it expires. ## Open the browser manually in the product Open the browser from an environment details page: 1. Open a running environment. 2. Select **Open Browser** to open a blank Browser tab. 3. To preview a local app, select **Preview ... in Browser** from a listed port. If the browser is not already running, Ona starts it for the environment and opens the Browser tab. Open Browser button on a running environment page You can also use the Browser tab directly: * Type a URL in the browser address field. * Use back, forward, reload, and external-open controls from the Browser tab header. * Switch between desktop and mobile viewport mode. * Close the Browser tab without stopping the environment. Browser tab switched to mobile viewport mode ## Ask Ona to use the browser When Ona AI is enabled, ask Ona to use the browser when a task requires visual inspection, page interaction, screenshots, videos, console output, or network requests. Mention the URL or port and the behavior you want checked. Examples: * `Open the browser and verify the app on port 3000 loads without console errors.` * `Use the browser to reproduce the login bug on localhost:8080 and tell me which step fails.` * `Open the settings page in the browser, take a screenshot, and explain why Save is disabled.` * `Record a short video of the onboarding flow in the browser and attach it to the conversation.` If your app is not already running, include that in the prompt: ```text theme={null} Start the frontend, open it in the browser on port 5173, and check whether the checkout modal still overflows on mobile. ``` The Browser tab and Ona use the same browser session for the environment. If you navigate, sign in, or change page state manually, Ona can continue from that state. If Ona navigates or fills a form, you can watch the change in the Browser tab. ## Send screenshots and annotations to Ona When Ona AI is enabled, use screenshots when Ona needs to inspect the exact page state you are seeing. * **Send screenshot to Ona** captures the current Browser tab and opens a message prompt with the screenshot attached. * **Annotate browser** lets you draw on the page, describe what to change, and send the annotated screenshot to Ona. * **Mobile viewport** switches the Browser tab between desktop and mobile viewport modes before you capture or annotate. Prompt for sending a Browser tab screenshot to Ona Use annotations for precise UI feedback, such as pointing at an overflowing element, a missing label, or a disabled button. Use a plain screenshot when the whole page state is enough. Browser annotation draft with a circled area and a message prompt After you send the annotation, Ona receives the marked-up screenshot in the conversation and can respond to the highlighted page state. Annotated Browser screenshot attached to an Ona conversation You can also ask Ona to capture artifacts while it uses the browser: * `Use the browser to open the dashboard on port 3000 and attach a screenshot of the billing page.` * `Record a short video of the signup flow in the browser and tell me where the error appears.` * `Take screenshots before and after submitting the form so I can compare the UI states.` ## FAQ No. Opening a port in the built-in browser keeps the preview inside the environment page. Use [Port sharing](/docs/ona/integrations/ports) when you need a URL that can be opened outside the environment page. Yes. The Browser tab and Ona share the same browser session for the environment, so Ona can continue from the state that is already open. No. Port sharing and the built-in browser use separate policies. The built-in browser is controlled by the [web browser policy](/docs/ona/organizations/policies/web-browser). Yes, when Ona AI is enabled. Ona and the Browser tab use the same browser session for the environment. If you sign in, navigate, or change page state in the Browser tab, Ona can continue from that state when you ask it to use the browser. ## Troubleshooting The environment may not be running, the environment supervisor may not support the browser yet, or your Enterprise organization may have disabled the web browser policy. Ask an organization administrator to check **Settings > Organization > Policies > Allow Web Browser in Environments**. The environment may be running on a supervisor version that does not support the built-in browser. Restart the environment after the runner is upgraded, then try opening the browser again. Check that the app is running and listening on the expected port. If the app also needs to be reachable through Ona port handling, follow the bind-address and network guidance in [Port sharing](/docs/ona/integrations/ports#prerequisites). # MCP servers Source: https://ona.com/docs/ona/mcp Extend agents with external tools using the Model Context Protocol [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/guide/) extends agents with external tools such as GitHub, Linear, and browser automation. MCP servers run as separate processes in your environment and communicate over stdio or HTTP. There are two ways to add MCP servers to Ona: * **[Custom organization integrations](#custom-organization-mcp-integrations)**: Administrators add HTTP MCP servers from the dashboard so everyone in the organization can use them. OAuth is set up automatically via Dynamic Client Registration, or manually with a client ID and secret. * **[Repo-local configuration](#repo-local-mcp-configuration)**: Developers commit `.ona/mcp-config.json` to a repository to configure servers per project. Supports both stdio and HTTP transports, and lets you inject secrets at runtime. ## Custom organization MCP integrations Administrators can add custom MCP servers to an organization from the dashboard. Custom integrations use HTTP transport and OAuth. You can set up OAuth in one of two ways: * **Automatic (DCR)**: Ona registers itself with the MCP server using [Dynamic Client Registration (DCR)](https://datatracker.ietf.org/doc/html/rfc7591), with no pre-shared client ID or secret. Requires the MCP server to expose a DCR endpoint. * **Manual**: You register Ona with your OAuth provider and supply a client ID and secret. Use this when the MCP server does not support DCR. Use custom integrations when you want to make an MCP server available to everyone in the organization without each developer configuring it locally. ### OAuth setup Before adding an integration, decide how Ona authenticates with the MCP server. You'll choose one of these modes in the create dialog. #### Automatic (DCR) The default. The MCP server must support [RFC 7591 OAuth 2.0 Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591). Ona registers itself with the server automatically on first use. No further configuration is required. Add MCP Integration dialog with Automatic (DCR) OAuth setup selected #### Manual Use this when the MCP server does not support DCR. You register Ona with the OAuth provider yourself and provide the resulting credentials: * **Callback URL**: Copy this value and register it as the redirect URI in your OAuth provider before saving. * **Client ID**: The client ID issued by your OAuth provider. * **Client secret**: The client secret issued by your OAuth provider. * **Authorization URL** (optional): The OAuth authorization endpoint. Auto-discovered from the MCP server's [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) metadata if left blank. * **Token URL** (optional): The OAuth token endpoint. Auto-discovered if left blank. * **Scopes** (optional): OAuth scopes to request, separated by newlines, spaces, or commas. Auto-discovered when the authorization URL is left blank. Add MCP Integration dialog with Manual OAuth setup selected, showing Callback URL, Client ID, and Client secret fields ### Add a custom integration 1. Go to [Settings > Integrations](https://app.ona.com/settings/org-integrations) 2. Click **Add MCP Integration** Organization integrations page showing the Add MCP Integration button in the page header 3. Enter: * **Name**: Display name shown to members (for example, `Hex`) * **MCP URL**: The MCP server endpoint (for example, `https://hex.tech/mcp/sse`) * **OAuth setup**: Choose **Automatic (DCR)** or **Manual** (see [OAuth setup](#oauth-setup) above). Manual reveals additional credential fields. * **Description** (optional): Short description shown on the integration card 4. Click **Create** The integration is created disabled. Enable it from the integrations list when you're ready to make it available to the organization. ### Authenticate Once enabled, each user connects their own account from [User Settings > Integrations](https://app.ona.com/?user-settings=integrations). Service accounts connect from the service account details page. Ona kicks off the OAuth flow so the agent acts with the selected user's or service account's permissions. For automatic integrations, Ona performs DCR against the MCP server on first use; for manual integrations, it uses the client credentials you provided. ## Repo-local MCP configuration Create `.ona/mcp-config.json` in your repository: ```json theme={null} { "mcpServers": { "github": { "name": "github", "command": "docker", "args": [ "run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${exec:printf 'protocol=https\nhost=github.com\n' | git credential fill 2>/dev/null | awk -F= '/password/ {print $2}' 2>/dev/null}" }, "timeout": 30, "toolDenyList": ["search_code"] }, "playwright": { "name": "playwright", "command": "npx", "args": ["-y", "@executeautomation/playwright-mcp-server"], "timeout": 60 } }, "globalTimeout": 30 } ``` ### Transport types Each server uses either **stdio** or **HTTP** transport. Ona detects the transport from your config: * Set `command` for stdio transport (runs a local process) * Set `url` for HTTP transport (connects to a remote endpoint) A server cannot have both `command` and `url`. ### Configuration options | Field | Transport | Description | | -------------- | --------- | -------------------------------------------------------------------------- | | `name` | both | Display name for the server (defaults to the map key) | | `command` | stdio | Executable to run the server | | `args` | stdio | Command arguments | | `url` | HTTP | Server endpoint (must start with `http://` or `https://`) | | `headers` | HTTP | HTTP headers sent with requests (supports `${exec:...}` and `${file:...}`) | | `env` | stdio | Environment variables (supports `${exec:...}` and `${file:...}`) | | `timeout` | both | Per-server timeout in seconds (default: 30) | | `toolDenyList` | both | Exact tool names to block | | `workingDir` | stdio | Working directory for the server process | | `disabled` | both | Set `true` to disable without removing config | Set `globalTimeout` at the top level of the config to apply a default timeout to all servers. ## Checking MCP server status Click the **MCP Integrations** button in the session input to see server status. Each server shows whether it is connected, disabled, or experiencing errors. MCP Integrations panel showing available servers with status indicators and error messages ## Examples ### Stdio transport (local process) [@executeautomation/playwright-mcp-server](https://www.npmjs.com/package/@executeautomation/playwright-mcp-server) runs as a local process via `npx`: ```json theme={null} { "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@executeautomation/playwright-mcp-server"], "timeout": 60 } } } ``` ### HTTP transport (remote server) Connect to an MCP server running over HTTP. Use `url` instead of `command`: ```json theme={null} { "mcpServers": { "my-remote-server": { "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${exec:printenv MCP_API_TOKEN}" }, "timeout": 60 } } } ``` `headers` supports `${exec:...}` and `${file:...}` expansion, like `env`. Inject tokens at runtime instead of committing secrets. ## Credentials Use [Ona Secrets](/docs/ona/configuration/secrets/overview) to inject credentials into `env` (stdio) or `headers` (HTTP): ```json theme={null} { "env": { "API_TOKEN": "${exec:printenv API_TOKEN}", "SERVICE_KEY": "${exec:your-secrets-cli get service/key}" } } ``` For HTTP servers, inject tokens via `headers`: ```json theme={null} { "headers": { "Authorization": "Bearer ${file:/run/secrets/api-token}" } } ``` * **Environment variables**: `${exec:printenv VAR_NAME}` * **Files**: `${file:/path/to/secret}` * **External stores**: `${exec:aws secretsmanager get-secret-value ...}` Avoid committing secrets to source control. Provision them at runtime using [Ona Secrets](/docs/ona/configuration/secrets/overview). ## DevContainer requirements MCP servers run inside your environment. The base image must include the tools they need (`npx` for Node-based servers, `docker` for container-based servers). If a server fails to start, verify the required runtime is in your Dev Container image. ## Applying configuration changes Ona reads MCP configuration once at the start of each agent execution. Changes are **not picked up mid-conversation**, regardless of whether they are in `.ona/mcp-config.json`, organization integrations, or the org-level MCP toggle. ### Local config (`.ona/mcp-config.json`) After creating or modifying the file: 1. **Save** the file in your workspace 2. Start a **new agent execution**: open a new Ona conversation, or wait for the current execution to finish and send a new message The agent reads the file from your workspace filesystem at the start of each execution. You do not need to rebuild the Dev Container or create a new environment. Commit the file to your repository when you're ready to share the config with new environments. ### Organization integrations (dashboard) Changes to MCP integrations in [Settings > Integrations](https://app.ona.com/settings/org-integrations) take effect on the next agent execution. No environment changes are needed. ### Organization MCP toggle Enabling or disabling MCP in [Settings > Agents > Policies](https://app.ona.com/settings/agent-policies) takes effect on the next agent execution. ## Organization controls MCP controls toggle in organization settings showing the option to enable or disable MCP servers Organization owners can disable MCP in [Settings > Agents > Policies](https://app.ona.com/settings/agent-policies). When disabled: * `.ona/mcp-config.json` files are ignored * Agent operates with built-in tools only * External MCP connections are blocked See [Audit logs](/docs/ona/audit-logs/overview) to review changes. ## Troubleshooting The agent may not list MCP tools when asked, but can still invoke them. Type `/support-bundle` in your Ona session to verify servers are connecting. If your MCP configuration has syntax errors or invalid server definitions, the agent logs the error and skips the misconfigured server. Check the MCP Integrations panel in the conversation input for error details. # Home notice Source: https://ona.com/docs/ona/organizations/announcement-banner Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Home notices let organization admins communicate important information to all members. Notices appear on the Ona home page and remain visible until disabled. Holiday notice displayed on the Ona home page ## Configure the notice 1. Go to **Settings → Organization → Announcements** 2. Turn on **Show announcement** 3. Enter your message (up to 1,000 characters) 4. Click **Save** The notice appears immediately on the home page for all organization members. Home notice configuration page showing the enable toggle ## Formatting Home notices support basic Markdown for emphasis and links. A live preview shows exactly how your message will appear. | Syntax | Result | | ------------------------ | -------------- | | `**bold**` | **bold** | | `*italic*` or `_italic_` | *italic* | | `[link text](url)` | Clickable link | Notice message editor showing a holiday notice with Markdown formatting and live preview ## Use cases * Scheduled maintenance windows * New feature announcements * Policy changes or reminders * Security notices * Team-wide updates ## Disable the notice Toggle off **Show announcement** in the settings. Your message is preserved and can be re-enabled later. ## FAQ All organization members see the notice when logged in. It appears on the Ona home page. Yes. When you enter a message, a live preview appears below the text field showing exactly how it will look. Only organization administrators can access the Announcements settings page. # Create or join an organization Source: https://ona.com/docs/ona/organizations/create-organization When signing in for the first time, Ona prompts you to create a new organization. You'll automatically be the admin. Organizations are the top-level boundary for people, projects, runners, policies, and secrets. Most teams have one organization per company or engineering group, though you can belong to more than one. ## Create an organization 1. Enter an organization name (can be changed later in Settings) 2. Optionally enable "Anyone with a *yourdomain.org* domain can join" to allow users with matching email domains to join automatically Organization creation form with name field and domain join option ## Join an organization If organizations exist that allow you to join (via domain matching), you'll see them listed. Click **Join** to become a member. Organization selection page showing available organizations to join ### From an invite link Clicking an invite link takes you directly to the join page for that organization. Join confirmation page from an organization invite link ### From the menu You can access the join/create dialog anytime from the account dropdown menu. Account dropdown menu showing Join or create organization option ## Create vs join * **Create** when you are setting up a new team space and need admin control over projects, runners, policies, and members. * **Join** when your team already has an organization and you only need access to shared resources inside it. ## What happens next After creating or joining an organization, the usual next steps are: * invite or manage members * create or connect projects * add runners or use Ona Cloud * configure login, policies, and secrets for the team See [Manage organization](/docs/ona/organizations/manage-organization) and [Team management](/docs/ona/organizations/overview) for the next layer of setup. # Insights Source: https://ona.com/docs/ona/organizations/insights Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Insights gives organization admins and Insights Viewers visibility into how their teams ship code, adopt AI tooling, and use environments. Access it from **Insights** in the left navigation menu. The page is organized into three sections: * **Velocity.** How fast your organization ships code. * **AI Adoption.** How your organization leverages AI to ship code. * **Platform usage.** How your organization uses Ona environments. Insights dashboard showing summary cards for Velocity, AI Adoption, and Platform usage ## Enabling insights Velocity and AI Adoption require per-project enablement. Platform usage data is collected automatically for all projects. To enable insights for a project: 1. Go to **Insights** and click **Manage** in the page header. 2. Toggle on the projects you want to track. Manage Insights dialog showing project toggles to enable or disable insights per project You can also enable insights from a project's settings page under the **Insights** toggle. When you enable insights for a project, a daily automation runs on behalf of your organization to analyze development activity. This incurs a small amount of usage costs. After enabling, the first analysis is triggered automatically. Initial results may take up to 24 hours to appear depending on repository size and history. Subsequent analyses run automatically. The page header shows how many of your projects have insights enabled (e.g. "3 of 12 projects have insights enabled") and when the last analysis ran. ## Filters All three sections share a set of filters at the top of the page: * **Date range.** Pick a preset (Last 7 days, Last 14 days, Last 30 days, Last 90 days, Last 6 months, Last year) or enter a custom range. The maximum range is one year. * **Project.** Scope all metrics to a single project, or view across all projects. * **Team.** Scope all metrics to a specific team. Charts support brush-zoom: click and drag on any chart to zoom into a narrower date range. Each section also has an **Aggregate by** toggle to switch between daily and weekly granularity. ## Summary cards At the top of the page, three summary cards provide an at-a-glance overview: | Card | Hero metric | Additional stats | | ------------------ | ----------------------- | ------------------------------------------------ | | **Velocity** | Lead time | PRs merged, Time to first approval, Deploys/week | | **AI Adoption** | AI-assisted commits (%) | AI commits, Agent exec/user, Agent sessions | | **Platform usage** | Env hrs/user | Active users, Power users, Environment sessions | Each card includes a sparkline and trend indicator comparing the selected period to the previous period of equal length. Click a card to scroll to its section. ## Velocity Velocity section showing Lead time, PRs merged, Time to first approval, and Deploys/week metric cards with a chart Tracks PR shipping speed across all projects with insights enabled. | Metric | Definition | | -------------------------- | ------------------------------------------------------------------------------------------------------------ | | **Lead time** | Median time from first commit on a branch to PR merge | | **PRs merged** | Total pull requests merged across all projects in scope | | **Time to first approval** | Median time from PR opened to first approving review | | **Deploys/week** | PRs merged to each project's configured branch, per week. Projects without a configured branch are excluded. | Click a metric card to view its time-series chart. Use the **Aggregate by** toggle to switch between daily and weekly buckets. For lead time and time to first approval, a downward trend is positive (faster shipping). For PRs merged and deploys/week, an upward trend is positive. ## AI Adoption AI Adoption section showing commits, lines added and removed by AI tool, and a breakdown table Shows how your organization leverages AI agents in development. Uses commit co-author trailers and AI authorship metadata to attribute changes to tools like Ona, Copilot, Cursor, Codex, and Claude. ### Metric cards | Metric | Definition | | ----------------- | ------------------------------------ | | **Commits** | Total commits in the selected period | | **Lines added** | Total lines added | | **Lines removed** | Total lines removed | | **Authors** | Distinct commit authors | Click a metric card to view its time-series chart. ### Breakdown modes For the **Lines added** and **Lines removed** views, a toggle switches between two attribution methods: * **By co-author.** Attributes lines based on `Co-authored-by` git trailers. Breaks down into: Ona, Codex, Claude, GitHub Copilot, Cursor, Other AI, Other Co-author, and Human only. * **By agent output.** Attributes lines based on AI authorship metadata tracked at the session level. Each breakdown includes a table below the chart showing per-tool totals and percentages. ## Platform usage Platform usage section showing Active users, Environments, and Total time metric cards with a chart and tables Tracks how your organization uses Ona environments across all projects. This data is collected automatically and does not require per-project enablement. ### Metric cards | Metric | Definition | | ---------------- | --------------------------------------------------------------------- | | **Active users** | Unique users who used at least one environment in the selected period | | **Environments** | Number of environments that were active in the selected period | | **Total time** | Accumulated environment runtime hours | Click a metric card to view its time-series chart. ### Detailed views Below the chart, three tables show: | Table | Shows | | --------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **Most active users** | Users ranked by total runtime hours | | **Top projects** | Projects ranked by total environment usage time | | **Top environment classes** | Resource consumption by class (e.g. Large, Regular). Local runners are aggregated for comparison with remote runners. | ## API access Query all Insights data programmatically with the [Insights API](/docs/ona/organizations/insights-api) for BI tooling, scheduled reports, or tracking AI adoption across teams. ## FAQ Organization admins can view and manage Insights. Members with the Insights Viewer organization role can view Insights, but cannot enable project insights. No. The daily analysis runs in a separate environment and does not interfere with developer workflows. Ona, Codex, Claude, GitHub Copilot, and Cursor. Other AI co-authors are grouped under "Other AI". Human co-authors (pair programming) are shown separately. A PR merged to the project's configured branch. If a project does not have a configured branch, it is excluded from the deploys metric. Yes, platform usage data persists after environments are deleted. Platform usage data is available from May 16, 2025 onwards regardless of when you enabled insights. Velocity and AI Adoption data starts from when you enable insights for each project. # Insights API Source: https://ona.com/docs/ona/organizations/insights-api Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. The Insights API exposes the data behind the [Insights dashboard](/docs/ona/organizations/insights): adoption and usage, AI co-authored commits, agent sessions, and PR speed. Use it to feed BI tools, build internal reports, or track AI adoption across teams. For metric definitions and how to enable insights for projects, see [Insights](/docs/ona/organizations/insights). Velocity and AI adoption endpoints return data only for projects with insights enabled. ## Authentication All endpoints accept a Bearer token: a [personal access token](/docs/ona/integrations/personal-access-token) (acts as you) or a [service account token](/docs/ona/organizations/service-accounts) (owned by the organization, recommended for ongoing automation). ```bash theme={null} export GITPOD_API_KEY="your-token" ``` ## Request format Every endpoint is a POST with a JSON body: ```text theme={null} POST https://app.gitpod.io/api/gitpod.v1.UsageService/ ``` | Parameter | Required | Description | | ------------ | ---------------- | --------------------------------------------------------------------------------------------------- | | `dateRange` | Yes | `startTime` and `endTime` as RFC-3339 timestamps. Maximum range is one year. | | `projectId` | No | Scope results to a single project. Requires read access to that project. | | `userId` | No | Scope results to a single user. Mutually exclusive with `teamId`. | | `teamId` | No | Scope results to members of a [team](/docs/ona/organizations/teams). Mutually exclusive with `userId`. | | `resolution` | Time series only | Bucket size: `RESOLUTION_HOURLY`, `RESOLUTION_DAILY`, `RESOLUTION_WEEKLY`, or `RESOLUTION_MONTHLY`. | Responses follow two conventions: * All `*Trend` fields are the fractional change against the previous period of equal length, computed as `(current - previous) / previous`. For example, `0.25` means up 25% and `-0.1` means down 10%. * 64-bit integer fields (counts, line totals) are returned as JSON strings, per protobuf JSON encoding. Parse them as integers. ## Adoption and usage summary Returns active users, power users, environment sessions, and average environment runtime per user, each with a trend, plus a sparkline. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetAdoptionUsageSummary` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetAdoptionUsageSummary \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}}' ``` **Response:** ```json theme={null} { "envRuntimePerUserSeconds": 431970.5, "envRuntimePerUserTrend": 0.12, "activeUsersCount": "48", "activeUsersTrend": 0.06, "powerUsersCount": "21", "powerUsersTrend": 0.1, "powerUsersThresholdSeconds": "308571", "sessionsCount": "12480", "sessionsTrend": -0.04, "sparkline": [ { "time": "2026-06-09T00:00:00Z", "value": 44 }, { "time": "2026-06-12T00:00:00Z", "value": 47 }, { "time": "2026-06-15T00:00:00Z", "value": 51 } ] } ``` ## AI co-authored commits summary Returns commit totals, line changes, and distinct authors, broken down per AI tool. Attribution uses `Co-authored-by` git trailers; see [AI Adoption](/docs/ona/organizations/insights#ai-adoption) for the detection rules. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetCoAuthorSummary` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetCoAuthorSummary \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}}' ``` **Response:** ```json theme={null} { "summary": { "totalCommits": "412", "totalLinesAdded": "30480", "totalLinesRemoved": "9860", "distinctAuthors": "24", "byTool": [ { "tool": "CO_AUTHOR_TOOL_NO_COAUTHOR", "commits": "118", "linesAdded": "4120", "linesRemoved": "1240", "distinctAuthors": "18" }, { "tool": "CO_AUTHOR_TOOL_ONA", "commits": "232", "linesAdded": "21260", "linesRemoved": "7140", "distinctAuthors": "16" }, { "tool": "CO_AUTHOR_TOOL_CLAUDE", "commits": "62", "linesAdded": "5100", "linesRemoved": "1480", "distinctAuthors": "9" } ], "totalCommitsTrend": 0.18, "totalLinesAddedTrend": 0.22, "totalLinesRemovedTrend": 0.09, "distinctAuthorsTrend": 0.04 }, "sparkline": [ { "time": "2026-06-09T00:00:00Z", "value": 96 }, { "time": "2026-06-16T00:00:00Z", "value": 104 } ] } ``` `tool` is one of `CO_AUTHOR_TOOL_NO_COAUTHOR`, `CO_AUTHOR_TOOL_HUMAN_COAUTHOR`, `CO_AUTHOR_TOOL_ONA`, `CO_AUTHOR_TOOL_GITHUB_COPILOT`, `CO_AUTHOR_TOOL_CURSOR`, `CO_AUTHOR_TOOL_CLAUDE`, `CO_AUTHOR_TOOL_CODEX`, or `CO_AUTHOR_TOOL_OTHER`. ## AI co-authored commits time series Returns the same contribution stats bucketed over time, including the AI-assisted share of lines added per bucket. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetCoAuthorTimeSeries` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetCoAuthorTimeSeries \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}, "resolution": "RESOLUTION_WEEKLY" }' ``` **Response:** ```json theme={null} { "timeSeries": [ { "startTime": "2026-06-08T00:00:00Z", "byTool": [ { "tool": "CO_AUTHOR_TOOL_NO_COAUTHOR", "commits": "31", "linesAdded": "1080", "linesRemoved": "320", "distinctAuthors": "12" }, { "tool": "CO_AUTHOR_TOOL_ONA", "commits": "58", "linesAdded": "5410", "linesRemoved": "1830", "distinctAuthors": "14" } ], "totalLinesAdded": "6490", "totalLinesRemoved": "2150", "aiRatio": 0.83, "totalCommits": "89", "distinctAuthors": "16" }, { "startTime": "2026-06-15T00:00:00Z", "byTool": [ { "tool": "CO_AUTHOR_TOOL_ONA", "commits": "64", "linesAdded": "6220", "linesRemoved": "2040", "distinctAuthors": "15" } ], "totalLinesAdded": "6220", "totalLinesRemoved": "2040", "aiRatio": 1, "totalCommits": "64", "distinctAuthors": "15" } ] } ``` ## Agent sessions summary Returns agent session counts and line changes, with a per-model breakdown. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetAgentTraceSummary` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetAgentTraceSummary \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}}' ``` **Response:** ```json theme={null} { "summary": { "totalSessions": "1240", "totalLinesAdded": "382400", "totalLinesRemoved": "76110", "byModel": [ { "model": "SUPPORTED_MODEL_OPUS_4_8", "sessions": "820", "linesAdded": "268900", "linesRemoved": "51200" }, { "model": "SUPPORTED_MODEL_SONNET_5", "sessions": "420", "linesAdded": "113500", "linesRemoved": "24910" } ], "totalSessionsTrend": 0.31, "totalLinesAddedTrend": 0.27, "totalLinesRemovedTrend": 0.19 }, "sparkline": [ { "time": "2026-06-09T00:00:00Z", "value": 274 }, { "time": "2026-06-16T00:00:00Z", "value": 301 } ] } ``` ## Agent sessions time series Returns agent sessions and line changes bucketed over time. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetAgentTraceTimeSeries` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetAgentTraceTimeSeries \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}, "resolution": "RESOLUTION_WEEKLY" }' ``` **Response:** ```json theme={null} { "timeSeries": [ { "startTime": "2026-06-08T00:00:00Z", "totalSessions": "274", "totalLinesAdded": "84300", "totalLinesRemoved": "16750", "byModel": [ { "model": "SUPPORTED_MODEL_OPUS_4_8", "sessions": "181", "linesAdded": "59400", "linesRemoved": "11300" }, { "model": "SUPPORTED_MODEL_SONNET_5", "sessions": "93", "linesAdded": "24900", "linesRemoved": "5450" } ] } ] } ``` ## PR speed summary Returns median lead time (first commit to merge), PRs merged, median time to first approval, and deployment frequency (PRs merged to the project's configured branch, per week). **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetPrSummary` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetPrSummary \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}}' ``` **Response:** ```json theme={null} { "summary": { "leadTimeSeconds": 8131.5, "leadTimeTrend": -0.14, "prsMergedCount": "648", "prsMergedTrend": 0.08, "timeToFirstApprovalSeconds": 821, "timeToFirstApprovalTrend": -0.05, "deploymentFrequency": 149.3, "deploymentFrequencyTrend": 0.11 }, "sparkline": [ { "time": "2026-06-09T00:00:00Z", "value": 148 }, { "time": "2026-06-16T00:00:00Z", "value": 162 } ] } ``` `timeToFirstApprovalSeconds` is zero when no PRs in the range had approvals. For lead time and time to first approval, a negative trend means faster shipping. ## PR speed time series Returns the same PR metrics bucketed over time. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.UsageService/GetPrTimeSeries` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetPrTimeSeries \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}, "resolution": "RESOLUTION_WEEKLY" }' ``` **Response:** ```json theme={null} { "timeSeries": [ { "startTime": "2026-06-09T00:00:00Z", "leadTimeSeconds": 6428, "prsMergedCount": "320", "timeToFirstApprovalSeconds": 958, "deploys": "313" }, { "startTime": "2026-06-16T00:00:00Z", "leadTimeSeconds": 10894, "prsMergedCount": "147", "timeToFirstApprovalSeconds": 803, "deploys": "146" } ] } ``` ## Combining filters Scope any endpoint with the shared parameters. For example, a single team's weekly co-author trend: ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.UsageService/GetCoAuthorTimeSeries \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "dateRange": {"startTime": "2026-06-09T00:00:00Z", "endTime": "2026-07-09T00:00:00Z"}, "teamId": "", "resolution": "RESOLUTION_WEEKLY" }' ``` # Manage members Source: https://ona.com/docs/ona/organizations/manage-members Organization admins can manage members in **Settings → Members**: change roles, remove members, invite teammates, and view any user's environments. Members page showing the People tab, member list, filters, and Invite button ## Member roles Every user in an organization has one of these roles: | Role | Description | | ---------- | -------------------------------------------------------------------------------------- | | **Admin** | Full control: manage members, create runners, configure policies, view all resources | | **Member** | Use shared runners and projects; cannot create runners or manage organization settings | For delegated administration without full admin access, assign [organization roles](/docs/ona/organizations/organization-roles) to groups. This lets you give specific teams management capabilities over runners, projects, groups, or automations. ## Permissions | Permission | Admin | Member | | ------------------------------------- | --------------------- | --------------------- | | **Organization** | | | | Invite members | | | | Manage member roles | | | | View all members | | | | Configure policies | | | | View audit logs | | | | Configure SSO | | | | **Projects** | | | | Create projects | | Depends on policy | | Share projects (as org admin) | | | | Share own projects (as project admin) | | | | Use existing projects | | | | **Runners** | | | | Create runners | | | | Use runners | | When shared | | **Environments** | | | | Create from any repository | | Depends on policy | | View all environments | | | | **Secrets** | | | | Manage project secrets | | | | Manage personal secrets | | | ## Change a member's role 1. Click the three-dot menu next to the member's name 2. Select **Change Role** 3. Choose the new role and confirm Member actions menu showing View Environments, Copy ID, Change Role, Suspend, and Delete options ## Invite members Click **Invite** at the top of the members list. There are three ways to add members: * **Invite link**: copy the link and share it with your team. Anyone with the link can join. Click **Reset Invite Link** to invalidate existing links. * **Invite by email**: enter email addresses to send invitations directly. * **Allowed email domains**: allow anyone with a matching email domain to join automatically. Invite members page showing invite link, invite by email, and allowed email domains options # Manage organization Source: https://ona.com/docs/ona/organizations/manage-organization Organization admins can modify settings in **Organization Settings → General**. Organization general settings page showing display name, tier, organization ID, and delete organization ## Display name Change your organization's name at any time. This affects how it appears in the UI and invite links. The name must be at least 3 characters. ## Tier The General page shows your organization's current tier (Core or Enterprise). Click **Compare tiers** to see what each tier includes. Core tier organizations can manage their subscription and OCUs under **Billing** in the sidebar. ## Organization ID A read-only, copyable UUID that identifies your organization. Use this when contacting support or integrating with the Ona API. ## Delete organization At the bottom of the page, you can permanently delete the organization. This permanently removes the organization and everything within it, including members, resources, and integrations. If the organization has a GitHub App installation connected through Ona, deleting the organization also uninstalls the GitHub App from GitHub. This action cannot be undone. Review projects, runners, secrets, and billing implications before deleting an organization. ## Related * [Create or join an organization](/docs/ona/organizations/create-organization) * [Team management](/docs/ona/organizations/overview) * [Manage members](/docs/ona/organizations/manage-members) # Organization secrets Source: https://ona.com/docs/ona/organizations/organization-secrets Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Organization secrets provide company-wide defaults. Shared credentials, API keys, and configuration are available to everyone in your organization. They are ideal for shared service accounts and company-wide integrations. **Organization secrets have the lowest precedence.** Project secrets and user secrets with the same name will override them, allowing teams and individuals to customize as needed. ## Manage organization secrets Navigate to **Settings → Organization → Secrets**. Organization secrets settings page showing list of company-wide secrets with type and name columns From here you can create, edit, and delete secrets. Each secret can be an [environment variable](/docs/ona/configuration/secrets/environment-variables), [file](/docs/ona/configuration/secrets/files), or [container registry credential](/docs/ona/configuration/secrets/container-registry-secret). ## When to use organization secrets * **Company-wide service accounts**: Shared database credentials, monitoring API keys * **Default configuration**: Standard environment variables everyone needs * **Container registry access**: Private images used across multiple projects For project-specific credentials, use [project secrets](/docs/ona/projects/project-secrets). For personal credentials, use [user secrets](/docs/ona/configuration/secrets/user-secrets). ## Precedence example If `API_KEY` exists at all three levels: 1. User secret value is used (highest) 2. Falls back to project secret 3. Falls back to organization secret (lowest) This lets you set organization defaults while allowing projects and users to override when needed. # Team management Source: https://ona.com/docs/ona/organizations/overview Organizations let teams share runners, projects, and secrets with role-based access control. Organizations provide a shared space for development resources. Administrators can manage projects, environments, runners, and member access. For personal use, you can create an organization for yourself. Think of an organization as the administrative and security boundary for Ona. Projects, runners, secrets, login settings, and policies all live inside an organization. ## What organizations contain | Resource | Description | | ----------------------------------------------------------- | --------------------------------------------------------------------------- | | [Projects](/docs/ona/projects/overview) | Environment configurations linked to repositories | | [Runners](/docs/ona/runners/overview) | Infrastructure for running environments | | [Members](/docs/ona/organizations/manage-members) | Users with role-based permissions | | [Groups](/docs/ona/organizations/groups) | Collections of members for access management | | [Teams](/docs/ona/organizations/teams) | Organizational units used for usage attribution and per-team credit budgets | | [Organization roles](/docs/ona/organizations/organization-roles) | Delegated admin roles for runners, projects, groups, and automations | | [Secrets](/docs/ona/configuration/secrets/overview) | Shared credentials and API keys | | [Policies](/docs/ona/organizations/policies/overview) | Organization-wide settings and restrictions | ## Groups vs. teams [Groups](/docs/ona/organizations/groups) and [teams](/docs/ona/organizations/teams) are two ways to organize people in an organization. They solve different problems and most organizations use both. * **Use a group** to answer *"who can use this runner?"* or *"who can edit this project?"* * **Use a team** to answer *"who's on the Backend team?"* and *"how much did Backend spend this month?"* | | **Groups** | **Teams** | | -------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------- | | **Purpose** | Access control for projects, runners, and automations | Organizational reporting and cost management | | **Membership** | A member can belong to **many groups** | A member belongs to **at most one team** per organization | | **Provisioning** | Managed in Ona, or synced from your identity provider via SCIM | Managed in Ona | | **Visibility** | Group membership is visible to organization members | All organization members can see all teams | | **Affects billing reporting?** | No | Yes, usage is rolled up per team | | **Affects access to resources?** | Yes | No | See [Manage groups](/docs/ona/organizations/groups) and [Manage teams](/docs/ona/organizations/teams) for the details. ## Isolation Organizations are hard boundaries. Resources cannot be shared or transferred between them. Each runner, project, and environment belongs to exactly one organization. Users can be members of multiple organizations but must switch between them explicitly. ## What admins usually manage Organization admins usually own: * who can join and how they authenticate * which runners and projects are available * how resources are shared across teams * which guardrails and policies apply by default * what secrets and service accounts shared workflows can use ## Common operating model For many teams, the pattern looks like this: 1. create or join the organization 2. connect identity and invite members 3. add runners or enable Ona Cloud regions 4. create shared projects 5. apply policies, secrets, and guardrails as the team grows ## Next steps * [Create an organization](/docs/ona/organizations/create-organization) * [Manage organization](/docs/ona/organizations/manage-organization) * [Manage members](/docs/ona/organizations/manage-members) * [Configure policies](/docs/ona/organizations/policies/overview) * [Sharing resources](/docs/ona/organizations/sharing-resources) # Sharing resources Source: https://ona.com/docs/ona/organizations/sharing-resources Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Share projects and runners with individual users, groups, or everyone in your organization. Resource admins can manage sharing for their resources. See [Manage groups](/docs/ona/organizations/groups) for group setup. ## Share a project Project admins can share their projects with other users and groups. When you create a project, you automatically become its admin. 1. Open the project and click **Share** 2. Click **Add users or groups** 3. Select individual users or groups to add 4. Choose a permission level for each: | Role | Capabilities | | ---------- | -------------------------------------------------------------- | | **User** | View and use the project | | **Editor** | Modify settings, manage secrets, configure environment classes | | **Admin** | Full control including sharing and deletion | Share project dialog showing user and group selection with permission role options ### Change permissions 1. In the Share dialog, find the user or group 2. Click the role dropdown 3. Select a new permission level (takes effect immediately) Role dropdown showing User, Editor, and Admin permission options ### Remove access 1. Click the role dropdown next to the user or group 2. Select **Remove access** ### Organization-wide access To share with everyone in your organization: 1. In **General access**, select your organization name 2. All members get User access; you can still grant elevated permissions to specific users or groups To restrict to specific users and groups only: 1. In **General access**, select **Only people with access** General access dropdown showing organization-wide or restricted access options ## Share a runner Runner admins can share their runners with other users and groups. 1. Go to **Settings → Runners** 2. Click **⋯** → **Share runner** 3. Add users or groups and assign roles (same dialog as projects) Runner roles: | Role | Capabilities | | --------- | ---------------------------------------------- | | **User** | Create environments on this runner | | **Admin** | Configure runner settings, manage integrations | Runner context menu showing Share runner option ## Access dependencies Users need access to **both** a project and at least one of its runners to create environments. Projects use runners through environment classes. If a user has project access but no access to any of its runners, they can see the project but cannot create environments. ### Share dialog warnings The Share dialog displays warnings to prevent access issues: **When sharing a project:** > "These users will not be able to use the project unless the underlying runner is also shared with them." **When restricting runner access:** > "Removing access to this runner may prevent these users from using projects that depend on it." # Terms of Service Source: https://ona.com/docs/ona/organizations/terms-of-service Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Require members to read and accept your organization's terms of service before they can continue using Ona. Acceptance is tracked per member, per version, and per organization, and can be exported as CSV for compliance reporting. Terms of Service settings page showing the acceptance toggle, Markdown editor, and live preview ## Enable terms of service 1. Go to **Settings → Organization → Terms of Service** 2. Write or paste your terms in the **Terms markdown** field. The editor supports up to 32,000 characters and renders a live preview alongside. 3. Toggle **Require terms acceptance** on 4. Click **Save** The first save publishes version 1. From that moment on, members are prompted to accept the current version on their next dashboard load. ## Markdown editor The editor accepts [GitHub Flavored Markdown](https://github.github.com/gfm/). The following are rendered: * Headings (`#`, `##`, `###`) * Paragraphs and line breaks * Bold and italic emphasis * Ordered and unordered lists * Links: `http(s)://` and `mailto:` only; other schemes are dropped * Inline `code` and fenced code blocks * Blockquotes * Tables (GFM) The following are **not** supported: * Images: `` tags and `![alt](src)` syntax are stripped * Raw HTML: escaped as text rather than rendered * JavaScript or other URL schemes in links: dropped silently A live preview to the right of the editor shows exactly what members will see. ## Publish a new version Each saved change to the markdown publishes a new immutable version. Toggling the switch on or off does not create a new version on its own. * Versions are numbered sequentially starting at 1. * Saving the page without changing the markdown does **not** create a new version. * Saving the page with changed markdown creates a new version and sets it as the current version. * Existing versions are immutable. Earlier text remains available in the acceptance report's version filter so you can reconstruct who accepted what. When the current version changes, members who had already accepted the previous version are automatically marked as needing to re-accept on their next dashboard load. There is no separate "force re-acceptance" action; re-acceptance follows version changes. ## What members see when terms are enabled On their next dashboard load, every active member of the organization sees: 1. A persistent banner at the top of the dashboard: *"Your organization requires you to accept its Terms of Service."* with a **Review terms** action. 2. A modal that opens automatically with the current version of the terms. The modal cannot be dismissed by clicking outside, pressing Escape, or navigating away. 3. The **Accept terms** button stays disabled until the member scrolls to the bottom of the terms. A hint reads *"Scroll to the bottom of the terms to enable Accept."* until they reach it. The banner remains visible across the dashboard until the member reviews and accepts the current version. Dashboard banner prompting a member to review and accept organization terms of service Acceptance is recorded per organization and per version. A member who belongs to two organizations accepts each organization's terms independently. When the current version changes, the modal reappears with the new text. ## Acceptance reporting Track who has accepted in **Settings → Organization → Members → Terms Acceptance**. The tab is visible to organization admins once a version has been published. The report lists organization members matching the selected filters with their acceptance status for the selected version. Terms Acceptance tab showing filters for version, acceptance status, member status, and accepted members You can: * **Filter by version**: switch between the current version and any earlier published version. * **Filter by member status**: All, Active, or Suspended. * **Search** by name or email. ### Export to CSV Use the **Export CSV** button at the top of the Terms Acceptance tab to download the report. The export reflects the version, member-status filter, and search currently selected in the tab. The download arrives as a gzipped CSV named `terms-of-service-acceptances--v.csv`. #### CSV columns | Column | Description | | ------------------ | --------------------------------------------------------------------- | | `user_id` | UUID of the user. | | `full_name` | Display name of the user. | | `email` | Email address of the user. | | `role` | `admin` or `member`. | | `member_status` | Organization membership status. One of `active`, `suspended`, `left`. | | `terms_status` | `ACCEPTED` or `PENDING`. | | `accepted_version` | Version number the user accepted. Blank if `terms_status` is pending. | | `accepted_at` | RFC3339 timestamp of acceptance. Blank if `terms_status` is pending. | ## Disable terms of service Toggle **Require terms acceptance** off and click **Save**. The published versions are preserved and the acceptance history remains queryable in the Terms Acceptance tab. Re-enabling later resumes prompting members to accept the current version. ## FAQ Only organization administrators can access the Terms of Service settings page and the Terms Acceptance tab. Only when the markdown changes. Saving with no changes (for example, toggling the switch on and off) does not publish a new version and does not require re-acceptance. Members who haven't accepted see the banner and the modal on their next dashboard load. They can browse to the modal and accept at any time. Acceptance is required to dismiss the modal. No. Images are stripped and raw HTML is escaped as text. Use Markdown headings, lists, links, tables, and code blocks to structure the content. Yes. The CSV reflects the version selector, member-status filter, and search query that are active in the Terms Acceptance tab when you click **Export CSV**. # Project configuration Source: https://ona.com/docs/ona/projects/overview Projects connect a repository to runners with predefined configuration. Team members create environments from a project with one click and get the same setup every time. ## Prerequisites * At least one runner in your organization * By default, all organization members can create projects * On the Enterprise tier, admins can restrict project creation to admins only via **Settings → Policies → Project policies → "Only admins can create projects"** ## Create a project When you create a project, you become its admin. You can manage settings and share the project with other users and groups. 1. Go to your organization dashboard and navigate to the Projects page 2. Click **New Project** Create a project dialog with repository selector, project name, and environment classes 3. Search for or browse to your repository 4. Enter a project name 5. Select at least one environment class ## Configuration options | Option | Description | | ------------------------------------------ | ------------------------------------------------------------------------------ | | **Context URL** / **Repository Clone URL** | Repository cloned when creating environments | | **Repository branch** | Default branch checked out (e.g., `main`, `develop`) | | **Environment classes** | Compute resources (CPU, memory, storage) and region. Min 1, max 30 per project | | **Dev Container path** | Path to devcontainer configuration file | | **Tasks and services configuration path** | Optional custom path to the tasks and services configuration file | | **Recommended editors** | Editors and versions suggested for this project | ### Environment classes An **environment class** is a named compute configuration provided by a [runner](/docs/ona/runners/overview). Each class defines the CPU, memory, storage, and region used to run an environment, and is the unit of resource selection inside Ona. When someone starts an environment for a project, they pick from the project's allowed classes. Each runner publishes its own set of classes (typically `Small`, `Regular`, `Large`, and sometimes specialized variants like GPU-enabled classes). The classes you select on a project determine which of those configurations are available to users creating environments for that project. ### Dev Container configuration Controls the development environment setup: base image, VS Code extensions, environment variables, and port forwarding rules. See [Dev Container configuration](/docs/ona/configuration/devcontainer/overview) for details. ### Tasks and services Define automations beyond Dev Container setup: * **Services**: long-running processes (databases, servers) * **Tasks**: one-off actions (test runs, builds) See [Tasks and services](/docs/ona/configuration/tasks-and-services/overview) for details. ### Recommended editors Set which editors and versions appear as suggestions when team members open an environment. See [Recommended editors](/docs/ona/projects/recommended-editors) for the full list of editor aliases and version configuration. ## Manage projects Select a project from your organization dashboard to open its detail page. The detail page has tabs for **Settings**, **Secrets**, and **Prebuilds**. From **Settings** you can modify environment classes, Dev Container and tasks/services paths, recommended editors, and [project secrets](/docs/ona/projects/project-secrets). ## Limitations Multi-repo configurations are not built-in. See [Working with multiple repositories](/docs/ona/configuration/multi-repository) for a workaround. ## Next steps * [Create an environment](/docs/ona/environments/overview) from your project * [Share the project](/docs/ona/organizations/sharing-resources) with your team * [Add project secrets](/docs/ona/projects/project-secrets) # Prebuilds Source: https://ona.com/docs/ona/projects/prebuilds Prebuilds reduce environment startup times by pre-executing Dev Container lifecycle commands and tasks. Instead of installing dependencies and running build steps every time, prebuilds prepare a snapshot that is ready to use. A prebuild creates an environment, runs your Dev Container build process, lifecycle hooks (`onCreateCommand` and `updateContentCommand`), and tasks with the `prebuild` trigger. Once these commands complete, Ona snapshots the Dev Container filesystem. New environments start from this snapshot, skipping the setup steps. ## Using prebuilds When you create an environment, Ona uses a prebuild if one is available. Selection is best-effort: * Matches your environment class (CPU, memory, storage) * Uses the most recent successful prebuild * Prebuilds expire after 7 days If no matching prebuild exists, the environment starts normally without one. ### What gets executed During prebuild creation, Ona runs: * **Dev Container build**: Builds your Dev Container image from the Dockerfile or docker-compose configuration. Prebuilds populate the [Dev Container image cache](/docs/ona/runners/devcontainer-image-cache), which speeds up subsequent builds. * **Dev Container lifecycle commands**: * `initializeCommand` - Runs before the container is created * `onCreateCommand` - Runs when the container is created for the first time * `updateContentCommand` - Runs when the container is created or updated * **Prebuild tasks**: Any tasks in `.ona/config.yaml` configured with the `prebuild` trigger. Organization and project secrets are available during these tasks, but user secrets are not. By default, a failed task produces a warning but the prebuild still succeeds. Set [`prebuildRequiresSuccess: true`](/docs/ona/reference/ona-config-schema#requiring-task-success-in-prebuilds) on a task to fail the prebuild when the task doesn't succeed. * **JetBrains warmup** (optional): When enabled, downloads and installs the JetBrains backend and runs the warmup command to build project indexes. See [JetBrains warmup](#jetbrains-warmup) for details. ### What doesn't run The following do **not** run during prebuilds. They run when a user starts an environment: * **Dev Container lifecycle commands**: * `postCreateCommand`: runs after the environment is created * `postStartCommand`: runs every time the environment starts * `postAttachCommand`: runs when you attach to the environment * **Tasks and services triggers**: Tasks and services with `postDevcontainerStart`, `postEnvironmentStart`, or `postMachineStart` triggers do not run during prebuilds. Only the `prebuild` trigger fires during prebuild execution. This separation is intentional. Prebuilds run without user context (no user secrets), so running a task during a prebuild is opt-in via the `prebuild` trigger. When a user creates an environment from a prebuild, the normal triggers (`postDevcontainerStart`, `postEnvironmentStart`, etc.) fire as usual. ### What gets included in the snapshot The prebuild snapshot captures the entire Dev Container filesystem: installed dependencies, built artifacts, downloaded assets, and all file system changes made during prebuild execution. Nothing is excluded. Untracked git changes created during the prebuild are cleared when an environment starts. Ona fetches the latest changes from the remote repository, which resets uncommitted or untracked files. To persist generated files, add them to `.gitignore` or write them outside the workspace folder. Prebuilds use the same [persistent storage](/docs/ona/environments/persistent-storage) model as regular environments. ## Benefits * **Faster startup**: Skip dependency installation and build steps * **Consistent environments**: All team members start from the same state * **Lower resource usage**: Build once, use many times ## Runtime impact Most prebuilds consume **5-10 minutes of runtime per project per day** across the entire organization. They run once daily. **Example**: 20 engineers on a project, one 10-minute prebuild per day. Prebuilds account for about **2% of total runtime** while making every engineer faster. Prebuilds trade a small amount of runtime to skip repetitive setup for your entire team. ## How prebuilds work 1. **Trigger**: A prebuild starts on schedule or manual trigger 2. **Environment creation**: Ona creates a temporary environment from your project's configuration 3. **Command execution**: Dev Container lifecycle commands and prebuild tasks run 4. **Snapshot**: Ona snapshots the environment once commands complete 5. **Cleanup**: The temporary environment is deleted 6. **Usage**: New environments start from the most recent successful snapshot ## Prebuild lifecycle Prebuilds go through several phases: * **Pending**: Prebuild created, waiting to start * **Starting**: Environment is being created * **Running**: Commands and tasks are executing * **Stopping**: Commands completed, environment is stopping * **Snapshotting**: Creating a snapshot of the environment * **Completed**: Prebuild successful, snapshot available * **Failed**: Prebuild encountered an error. This includes Dev Container image build failures and tasks with [`prebuildRequiresSuccess`](/docs/ona/reference/ona-config-schema#requiring-task-success-in-prebuilds) that did not succeed. * **Cancelling**: Prebuild is being cancelled, cleanup in progress * **Cancelled**: Prebuild was manually cancelled ## Secrets and authentication During prebuild execution: * **Organization secrets**: Available to all prebuilds * **Project secrets**: Available to prebuilds for that project * **User secrets**: Not available (prebuilds run without user context) ### Prebuild executor The executor determines which identity clones the repository and runs the prebuild. Configure it in project settings. * **User (default)**: The prebuild runs as the user who enabled prebuilds * **Service account**: The prebuild runs as a [service account](/docs/ona/organizations/service-accounts), using the service account's SCM credentials Regardless of executor, **no user secrets are used** during prebuilds. Only organization and project secrets are available. When using a service account, configure SCM access on all runners where prebuilds run. See [Git authentication](/docs/ona/organizations/service-accounts#git-authentication) for setup. Project admins can change the executor to themselves or a service account. If another user is the current executor, admins can leave it unchanged but cannot switch it to a different user. **Best practice:** Use service accounts so prebuilds keep working regardless of individual user availability. ## Timeouts | Timeout Type | Default | Range | Description | | ---------------------- | ------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Prebuild execution** | 1 hour | 5 minutes - 2 hours | Time allowed for running the environment with Dev Container build/lifecycle commands and automation prebuild tasks (configurable per project) | | **Snapshotting** | 4 hours | Fixed | Time allowed for creating the snapshot after prebuild execution completes | | **Overall timeout** | 6 hours | Fixed | Catch-all timeout for the entire prebuild process, including environment creation, command execution, and snapshotting | If a prebuild exceeds its timeout, it fails. The underlying environment is torn down immediately so you stop paying for the VM, while the prebuild logs remain viewable for the remainder of the prebuild's retention window. ## Prebuild retention * Prebuilds are deleted after **7 days** * Only the most recent successful prebuild per environment class is used * Failed prebuild logs remain viewable for 7 days; the underlying environment is deleted as soon as the prebuild fails ## Pricing ### Ona Cloud * **Environment usage**: Standard usage-based billing for the time the prebuild environment runs * **Storage**: Prebuild snapshots are **free** (this may change) ### Enterprise (Your Cloud) * **Environment usage**: You pay for compute resources used by the prebuild environment * **Storage**: You pay for actual data stored in the snapshot. If you use 50 GB of a 100 GB volume, you are billed for 50 GB. Snapshots are stored as volume snapshots in your cloud provider (backed by S3). See [Billing](/docs/ona/billing/overview) for details. ## Runner support Prebuilds are supported on the latest version of every runner type: * **Ona Cloud**: supported by default * **AWS runners**: supported on the latest CloudFormation stack. See [Update an AWS runner](/docs/ona/runners/aws/update-runner#upgrade-runner-infrastructure) * **GCP runners**: supported on the latest Terraform stack. See [Update a GCP runner](/docs/ona/runners/gcp/update-runner#updating-infrastructure) If prebuilds are not available in your organization, upgrade your runner to pick them up. ## JetBrains warmup JetBrains warmup pre-installs the JetBrains backend and builds project indexes during prebuilds. Users skip the download and indexing time when they open a JetBrains editor. ### What JetBrains warmup does 1. **Backend pre-installation**: Downloads and installs the JetBrains backend during the prebuild 2. **Index building**: Runs the warmup command to build project indexes (code analysis, symbol tables) ### Enabling JetBrains warmup 1. Navigate to your project settings 2. In the prebuild configuration section, enable **JetBrains warmup** 3. Configure [recommended editors](/docs/ona/projects/recommended-editors) to specify which JetBrains editors to warm up ### Warmup execution order JetBrains warmup runs after all other prebuild tasks complete. This means dependencies are installed and build artifacts are generated before indexing begins. ## Use case: caching large file downloads If your project downloads large assets (e.g. 20 GB+ of data files), configure a prebuild task to download them once. Subsequent environments start from the snapshot with the files already present, avoiding repeated downloads and reducing egress costs. ## Warm pools For projects where even prebuild-based startup is too slow (e.g. large monorepos with big EBS volumes), [warm pools](/docs/ona/projects/warm-pools) keep pre-initialized EC2 instances running and ready to claim. This significantly reduces environment startup time by skipping instance provisioning and snapshot restoration. Warm pools require the Enterprise plan and an AWS runner. ## Limitations * Prebuilds are tied to a specific environment class on a runner * Only one prebuild per environment class is active at a time * Only daily scheduling is available (more trigger options coming soon) * Prebuilds cannot be triggered on every commit (coming soon) ## Next steps * [Configure prebuilds for your project](/docs/ona/projects/prebuilds-setup) * [View and manage prebuilds](/docs/ona/projects/prebuilds-management) * [Enable warm pools](/docs/ona/projects/warm-pools) for faster startup times * Learn about [Dev Container configuration](/docs/ona/configuration/devcontainer/overview) * Explore [Tasks and Services](/docs/ona/configuration/tasks-and-services/overview) # Managing prebuilds Source: https://ona.com/docs/ona/projects/prebuilds-management ## View prebuilds Navigate to your project settings and click the **Prebuilds** tab. All project members can view prebuilds and their logs. Each prebuild shows: * **Date & Time** - when the prebuild was created. * **Class** - the environment class and runner used. * **Triggered by / Ran as** - the trigger source (push, schedule, or manual) and the user it ran as. * **Status & Duration** - the current phase (pending, running, snapshotting, completed, failed, cancelled) and elapsed time. During snapshotting, a completion percentage is shown when available from the cloud provider. * **Snapshot Size** - the size of the resulting snapshot, shown once the prebuild completes. ## Configure prebuild settings In the project **Settings** tab, the prebuild configuration section lets you: * **Enable prebuilds** - turn prebuilds on or off for the project. * **Select environment classes** - choose which environment classes to prebuild. * **Schedule** - set the daily prebuild time (hour in UTC). Prebuilds start within the scheduled hour and may be delayed by up to 30 minutes because runs are staggered to spread cloud capacity requests. * **Executor** - choose who runs prebuilds (yourself or a service account). The executor's SCM credentials are used to clone the repository. * **Timeout** - set the maximum duration for a prebuild (5 minutes to 2 hours, defaults to 1 hour). * **JetBrains warmup** - pre-install the JetBrains backend and build project indexes during prebuilds so JetBrains editors start faster. See [JetBrains warmup](/docs/ona/projects/prebuilds#jetbrains-warmup) for details. ## View logs Click the actions menu on a prebuild row and select **Logs** to see Dev Container lifecycle command output, automation task logs, build progress, and error messages. When troubleshooting failures, check logs for errors, verify required secrets are configured, and confirm commands do not require user interaction. ## Trigger prebuilds manually Click the **Run Prebuild** button in the top right of your project settings to run prebuilds for all selected environment classes. For specific environment classes, use the CLI: ```bash theme={null} ona prebuild trigger --environment-class-id ``` ## Cancel prebuilds Cancel a running prebuild from the Prebuilds tab or via CLI: ```bash theme={null} ona prebuild cancel ``` Cancelled prebuilds consume resources until cleanup completes. ## Bulk cancel and delete Use the checkboxes on the Prebuilds tab to select multiple prebuilds at once, then choose an action from the bulk-action bar: * **Cancel prebuilds** stops any in-progress prebuilds in the selection. Prebuilds that are already completed, failed, or cancelled are skipped. * **Delete prebuilds** removes the selected prebuilds. New environments will not start from them. Existing environments that were created from these prebuilds keep running and are unaffected. Bulk actions process each prebuild independently. The progress dialog shows per-item success or failure so you can see exactly which prebuilds were skipped or returned an error. ## CLI commands ```bash theme={null} # List prebuilds ona prebuild list --project-id # Get prebuild details ona prebuild get # Delete a prebuild ona prebuild delete ``` See the [CLI documentation](/docs/ona/integrations/cli) for configuration commands. ## Related * [Prebuild concepts](/docs/ona/projects/prebuilds) * [Setting up prebuilds](/docs/ona/projects/prebuilds-setup) ## Troubleshooting Check logs for errors, verify secrets are configured at organization or project level, and confirm commands do not require user interaction. Verify a successful prebuild exists for the environment class and is less than 7 days old. Review logs for hanging commands, check timeout settings, or cancel and retry. # Setup prebuilds Source: https://ona.com/docs/ona/projects/prebuilds-setup Configure prebuilds for your project to reduce environment startup times. ## Prerequisites * Project user, editor, or admin role on the project * An existing project with at least one environment class * AWS or GCP Enterprise runner, or Ona Cloud **AWS and GCP Enterprise runners**: Update to the latest infrastructure version before using prebuilds: * **AWS**: [Upgrade your CloudFormation stack](/docs/ona/runners/aws/update-runner#upgrade-runner-infrastructure) * **GCP**: [Update your Terraform stack](/docs/ona/runners/gcp/update-runner#updating-infrastructure) ## Enable prebuilds ### 1. Navigate to project settings 1. Go to your organization dashboard at [https://app.ona.com](https://app.ona.com) 2. Select your project from the projects list ### 2. Configure prebuild settings In the project settings, the prebuild configuration section lets you: 1. **Enable prebuilds** for the project 2. **Select environment classes** to prebuild 3. **Configure the schedule** for automatic prebuild creation 4. **Configure the executor** to run prebuilds as yourself or a service account 5. **Set timeout** for prebuild execution Prebuild configuration section showing enable toggle, environment classes, schedule, executor, and timeout options When you enable prebuilds, the daily schedule activates. Disabling prebuilds: * Stops the daily schedule * Prevents new environments from using existing snapshots * Leaves existing snapshots until they expire (7 days) You can run prebuilds manually at any time to create fresh snapshots after configuration changes or to retry failures. ### 3. Select environment classes Check the boxes next to the environment classes you want to prebuild. Prebuilds run for each selected class on the configured schedule. **Tip**: If your team primarily uses one or two classes (e.g., "Regular"), enable prebuilds only for those to keep costs low. ### 4. Configure the executor Choose which identity runs your prebuilds: * **User (default)**: Prebuilds run as the user who enabled them * **Service account**: Prebuilds run as a [service account](/docs/ona/organizations/service-accounts), using the service account's SCM credentials **When to use a service account:** * Prebuilds keep working regardless of individual user availability * Permissions stay consistent independent of user role changes * Prebuild activity is attributed to a dedicated account **Requirements for service accounts:** * [Git authentication configured](/docs/ona/organizations/service-accounts#git-authentication) on all runners where prebuilds run * The service account's Personal Access Token must have access to the project's repository Regardless of executor, no user secrets are used during prebuilds. Only organization and project secrets are available. Project admins can change the executor to themselves or a service account. If another user is the current executor, admins can leave it unchanged but cannot switch to a different user. ### 5. Configure the schedule Set when prebuilds run: 1. **Daily schedule**: Choose the hour (UTC) when prebuilds trigger 2. **Recommended timing**: Schedule during off-hours so fresh prebuilds are ready when your team starts work Prebuilds are created in batches during the scheduled hour to spread cloud capacity requests. Your prebuild will start within the scheduled hour, but not necessarily at the exact start of it. Expect up to 30 minutes of delay depending on how many projects share the same hour. **Example**: If your team is in EST (UTC-5) and starts at 9 AM, schedule prebuilds for 1 PM UTC (8 AM EST). ### 6. Set timeout Configure how long prebuilds can run before timing out. You can set the timeout in project settings under **Prebuild Environments → Times out after**, or via the CLI: ```bash theme={null} ona project configure-prebuilds --enabled --timeout 90m ``` Set the timeout above your typical build duration with some buffer. If builds take 30 minutes, a 45-minute timeout works well. See the [timeouts overview](/docs/ona/projects/prebuilds#timeouts) for limits and behavior. ### 7. Configure JetBrains warmup (optional) If your team uses JetBrains editors, enable warmup to pre-install the backend and build project indexes during prebuilds: 1. In the prebuild configuration section, enable **JetBrains warmup** 2. Configure [recommended editors](/docs/ona/projects/recommended-editors) to specify which JetBrains editors to warm up Warmup runs after all other prebuild tasks complete, so the project is built before indexing begins. Users skip the backend download and get prebuilt indexes for code navigation. ## Configure your Dev Container for prebuilds Structure your Dev Container configuration so prebuilds handle the slow parts. ### Commands that run during prebuilds Place time-consuming setup in these lifecycle hooks: ```json theme={null} { "initializeCommand": "echo 'Runs before container creation'", "onCreateCommand": "npm install && npm run build", "updateContentCommand": "npm install" } ``` ### Commands that run after prebuilds Place user-specific or session-specific commands here: ```json theme={null} { "postCreateCommand": "echo 'Runs after container creation'", "postStartCommand": "npm run dev", "postAttachCommand": "echo 'Welcome!'" } ``` ## Configure tasks and services for prebuilds Add the `prebuild` trigger to tasks that should run during prebuilds: ```yaml theme={null} tasks: seedDatabase: name: Seed the database with test data triggeredBy: - prebuild command: npm run db:seed downloadAssets: name: Download large asset files triggeredBy: - prebuild command: ./scripts/download-assets.sh ``` Tasks with the `prebuild` trigger execute during prebuild creation alongside Dev Container lifecycle commands. Organization and project secrets are available to tasks during prebuilds, but user secrets are not. Configure any credentials needed for prebuild tasks at the organization or project level. ### Choosing between `prebuild` and `postDevcontainerStart` During a prebuild, **only** tasks with the `prebuild` trigger run. Other triggers like `postDevcontainerStart` do **not** fire during prebuilds. Prebuilds run without user context (no user secrets), so running a task during a prebuild is opt-in. When a user creates an environment from a prebuild, `postDevcontainerStart` fires as usual. | Scenario | Trigger to use | | ----------------------------------------------------------------------------------------------------- | ------------------------------------------- | | Task should run during prebuilds only (e.g., download large assets once) | `prebuild` | | Task should run when a user starts an environment (e.g., start a dev server) | `postDevcontainerStart` | | Task should run during prebuilds *and* when the Dev Container is rebuilt (e.g., install dependencies) | Both `prebuild` and `postDevcontainerStart` | **Example**: Install dependencies during prebuilds so the snapshot includes `node_modules`, and also when a user rebuilds their Dev Container (which creates a fresh container without the snapshot): ```yaml theme={null} tasks: install-deps: name: Install dependencies triggeredBy: - prebuild - postDevcontainerStart command: npm ci ``` ## Manually trigger a prebuild ### Via web UI 1. Open your project from the dashboard 2. Click the **Run Prebuild** button in the project header This runs a prebuild for all selected environment classes. Use manual runs to test configuration changes, create fresh prebuilds after code changes, or prepare prebuilds before the scheduled time. ### Via CLI Run prebuilds for specific environment classes: ```bash theme={null} ona prebuild trigger --environment-class-id ``` ## Verify your setup After enabling prebuilds: 1. Run a manual prebuild and verify it completes 2. Check the prebuild logs for errors 3. Create a new environment and confirm it starts from the prebuild 4. Verify the schedule matches your timezone If the prebuild fails, check logs for error messages and verify that required secrets are configured at the organization or project level. ## Best practices ### Speed and cost Install only what development needs. Schedule prebuilds during off-hours so fresh snapshots are ready when your team starts. Start with one or two commonly used environment classes, then expand based on usage. ### Structuring commands Place stable, time-consuming operations in prebuild commands: dependency installation, database seeding, asset downloads. Reserve `postCreateCommand` for dynamic operations like starting dev servers or user-specific setup. Keep all commands idempotent. ### Managing secrets Use organization secrets for shared build credentials and project secrets for project-specific credentials. User secrets are not available during prebuilds. ## Next steps * [View and manage your prebuilds](/docs/ona/projects/prebuilds-management) * [Enable warm pools](/docs/ona/projects/warm-pools) for faster startup times (Enterprise, AWS only) * [Understand prebuild concepts](/docs/ona/projects/prebuilds) * [Optimize your Dev Container configuration](/docs/ona/configuration/devcontainer/optimizing-startup-times) * [Learn about Tasks and Services](/docs/ona/configuration/tasks-and-services/overview) ## Troubleshooting Verify prebuilds are enabled in project settings. Check logs for errors, verify secrets are configured, and confirm commands do not require user interaction. If builds time out, increase the timeout in project settings or via CLI. Confirm a successful prebuild exists for the environment class and is less than 7 days old. Move user-specific or session-specific commands to `postCreateCommand`. Verify file permissions are correct after the snapshot. See [Managing prebuilds](/docs/ona/projects/prebuilds-management) for more troubleshooting. # Project secrets Source: https://ona.com/docs/ona/projects/project-secrets Project secrets are scoped to a single project. Anyone who launches an environment from the project gets these secrets injected automatically. Use them for credentials the whole team needs for that repository (API keys, service accounts, registry access) without exposing them to other projects in the organization. **Project secrets have middle precedence.** They override organization secrets but can be overridden by user secrets. Teams set project defaults while individuals can still customize. ## Common uses Project secrets are the right default for credentials tied to one repository or workflow. Typical examples: * API keys for services used by one codebase * shared test credentials * project-specific registry access * configuration values that should travel with the project rather than the whole organization ## Manage project secrets Navigate to **Project → Secrets**. Project secrets page showing list of shared secrets with type and name columns From here you can create, edit, and delete secrets. Each secret can be an [environment variable](/docs/ona/configuration/secrets/environment-variables), [file](/docs/ona/configuration/secrets/files), or [container registry credential](/docs/ona/configuration/secrets/container-registry-secret). ## When to use project secrets * **Shared service accounts**: Database credentials, API keys for project-specific services * **Project configuration**: Environment-specific settings the whole team needs * **Container registry access**: Private images for this project's Dev Container For personal credentials like your own Linear or GitHub token, use [user secrets](/docs/ona/configuration/secrets/user-secrets) instead. ## How project secrets affect environments and automations Project secrets are available to environments launched from that project, including automation runs that create environments from the project. That makes them the best place for shared defaults a project-backed workflow depends on. If the same secret also exists at organization scope, the project secret takes precedence for this project. ## Related * [How secrets work](/docs/ona/configuration/secrets/overview) * [User secrets](/docs/ona/configuration/secrets/user-secrets) * [Organization secrets](/docs/ona/organizations/organization-secrets) # Project visibility Source: https://ona.com/docs/ona/projects/project-sharing When you create a project, you become its admin. Default visibility depends on your organization's tier: * **Enterprise tier**: projects are visible to admins only by default, until access is granted to specific groups or users via the Share dialog * **All other tiers**: projects are shared with the entire organization by default On the Enterprise tier, the Share dialog also lets you grant access to specific groups and individual users. For more on this, see [Sharing resources](/docs/ona/organizations/sharing-resources). To give a team admin access to **all** projects in the organization, assign the [Projects Admin](/docs/ona/organizations/organization-roles) role to their group. ## What visibility controls Project visibility controls who can discover a project in the UI and who can use it to create environments. It does not change who can access the underlying repository outside Ona, and it does not hide a project from organization admins. In practice, visibility answers three questions: * who can see the project * who can create environments from it * whether the project is broadly available or limited to a smaller team ## Change visibility 1. Open the project from your dashboard 2. Click the **Share** button in the project header 3. Under **General access**, select: * **Everyone in **: all members can see and use the project * **Only groups and users with access**: restricted to explicitly added groups and users Projects cannot be hidden from admins. Project sharing settings showing visibility options for organization members or admins only ## When to use each mode * **Everyone in **: use this for common services, shared internal platforms, templates, and repositories many engineers need. * **Only groups and users with access**: use this while a project is being prepared, when access should be tightly controlled, or when the project should only be available to specific teams. If you need more control, use [Sharing resources](/docs/ona/organizations/sharing-resources) to grant access to specific users or groups. ## Create an environment from a shared project Once a project is shared with you, you can create an environment from it directly. On the **Projects** page, click **Create Environment** on the project card. The environment inherits the project's repository, secrets, and configuration. ## Access dependencies Project access alone is not always enough to create an environment. A user also needs access to at least one runner used by that project. If someone can see a project but cannot start an environment from it, check: * whether the project is shared with them * whether a compatible runner is shared with them * whether organization policies restrict environment creation ## Related * [Create your first project](/docs/ona/create-first-project) * [Sharing resources](/docs/ona/organizations/sharing-resources) * [Organization roles](/docs/ona/organizations/organization-roles) # Warm Pools Source: https://ona.com/docs/ona/projects/warm-pools Available on the Enterprise plan. Supported on [AWS](/docs/ona/runners/aws/overview) and [GCP](/docs/ona/runners/gcp/overview) runners. [Contact sales](https://ona.com/contact/sales) to learn more. Warm pools keep pre-initialized instances ready to claim. When a user creates an environment, Ona assigns a warm instance instead of launching a new one, reducing startup time from minutes to seconds. The pool scales dynamically between a minimum and maximum size based on demand. It scales up during peak hours and back down (optionally to zero) when idle. ## When to use warm pools Warm pools are most effective for: * **Large or monorepo projects** where snapshot restoration adds noticeable startup latency. Instances lazy-load data from the prebuild snapshot on first boot, and larger volumes take longer to fully hydrate. For these projects, warm pools can cut startup time from minutes to around 10 seconds. * **Smaller projects with many users** where prebuilds already bring startup to 30-50 seconds. Warm pools can reduce this further to around 10 seconds. Whether the cost is justified depends on how many engineers use the project and how often they create new environments versus reusing existing ones. * **Latency-sensitive workflows** where every second of startup time matters (e.g. PR review environments, demo environments). Without warm pools, each environment launch provisions a new instance and restores the prebuild snapshot. With warm pools, the instance is already running and the snapshot is already loaded, skipping the most time-consuming parts of startup. Actual startup time depends on your devcontainer configuration. Dotfiles installation and post-prebuild lifecycle hooks (`postCreateCommand`, `postStartCommand`, `postAttachCommand`) still run when the environment starts. Optimize these commands for the fastest experience. ## How it works 1. You enable a warm pool for a project and environment class, specifying a minimum and maximum pool size. 2. The runner launches instances from the latest prebuild snapshot, scaling between the minimum and maximum pool size. 3. The pool scales dynamically between your configured minimum and maximum based on demand (see [Dynamic scaling](#dynamic-scaling)). 4. When a user creates an environment, Ona claims a warm instance from the pool instead of launching a new one. The pool immediately begins replenishing. 5. When a new prebuild completes, the pool rotates instances to use the new snapshot. Instances can be claimed even while still initializing. A partially warmed instance is still faster than a cold start because the EC2 instance is already running and the snapshot is partially loaded. ## Dynamic scaling Warm pools scale automatically based on demand. The runner monitors how frequently instances are claimed and adjusts the number of running instances accordingly. It scales up when environments are being created (by engineers, automations, or agents) and scales back down when demand drops. * **Scale-out** happens when sustained demand exceeds what the current running instances can serve. Stopped instances are started to meet demand (see [Stopped instances](#stopped-instances)), so scaling out takes roughly 1–2 minutes rather than the 5+ minutes of a cold boot. * **Scale-in** happens when demand drops. The pool waits for demand to stay low before removing instances, so brief idle periods don't cause unnecessary churn. * The pool never scales below `min-size` or above `max-size`. ### Stopped instances In addition to running instances, the pool maintains **stopped instances** that are pre-provisioned but not actively running. These act as a buffer for fast scale-out: when demand increases, a stopped instance can be started in roughly 1–2 minutes instead of provisioning a new one from scratch (\~5 minutes). The number of stopped instances equals the remaining capacity between the current number of running instances and `max-size`. For example, with `max-size = 5` and 3 running instances, there are 2 stopped instances ready to start. Stopped instances save on cost because you only pay for their disk storage, not compute. This means the pool can maintain headroom for burst demand without paying for idle running instances. Stopped instances only help when the pool scales *out* (adding more running instances). They do not reduce startup time for the first environment when the pool is scaled to zero, because there are no running instances to claim. In that case, the first environment is a cold start. ### Scale to zero Setting `min-size` to `0` allows the pool to scale down to zero running instances when there is no demand. This is useful for reducing costs during off-hours, weekends, or for projects with intermittent usage. **Tradeoffs:** | | min-size = 0 | min-size ≥ 1 | | -------------------------------- | ---------------------------------------------- | ---------------------------------- | | **Off-hours cost** | No running instances, no compute cost | At least one instance running 24/7 | | **First environment after idle** | Cold start (similar to not having a warm pool) | Near-instant (\~10 seconds) | | **Subsequent environments** | Near-instant once the pool has scaled up | Near-instant | **How quickly does the pool scale down to zero?** The pool requires at least **30 minutes** of inactivity (no environments created) before it begins scaling down to zero. This idle guard prevents aggressive scale-down during brief lulls, such as a lunch break. After the idle guard expires, the cloud provider completes the scale-in shortly after. Use `min-size = 0` for projects where occasional slower startups are acceptable in exchange for lower cost. Use `min-size = 1` (or higher) for projects where instant startup is always expected. ## Prerequisites * [Enterprise plan](https://ona.com/pricing) * [Prebuilds enabled](/docs/ona/projects/prebuilds-setup) for the project * A runner with warm pool support: * **AWS**: latest infrastructure version. [Upgrade your CloudFormation stack](/docs/ona/runners/aws/update-runner#upgrade-runner-infrastructure) if you haven't already. * **GCP**: latest Terraform module version. [Upgrade your Terraform module](/docs/ona/runners/gcp/update-runner#updating-infrastructure) if you haven't already. * At least one successful prebuild for the environment class * **Project admin** role on the project ## Enable warm pools Only **project admins** can configure warm pools. ### Via the dashboard 1. Navigate to your project settings 2. In the **Prebuilds** section, find the environment class list 3. Expand an environment class row. A **Warm Pool** toggle appears below each class that has prebuilds enabled 4. Toggle **Warm Pool** on 5. Set the **Min Size** and **Max Size** to define the scaling range The warm pool toggle only appears for environment classes on runners that support warm pools and have prebuilds enabled. ### Via the CLI ```bash theme={null} # Create a warm pool with scaling bounds ona prebuild warm-pool create \ --environment-class-id \ --min-size 1 \ --max-size 3 # Create a warm pool that can scale to zero ona prebuild warm-pool create \ --environment-class-id \ --min-size 0 \ --max-size 3 # List warm pools for a project ona prebuild warm-pool list --project-id # Check warm pool status ona prebuild warm-pool get # Update scaling bounds ona prebuild warm-pool update --min-size 0 --max-size 5 # Delete a warm pool ona prebuild warm-pool delete ``` All commands support `--format json`, `--format yaml`, and `--format table` output. ## Pool lifecycle Warm pools go through these phases: | Phase | Description | | ------------ | ------------------------------------------------------------------------------------------------------ | | **Pending** | Pool created, waiting for a prebuild snapshot to be assigned | | **Ready** | Instances are available for claiming (running count may vary based on current demand) | | **Degraded** | The runner reported a problem (e.g. failed to launch instances). Check the failure message for details | | **Deleting** | Pool is being deleted, instances are draining | | **Deleted** | All instances terminated, cleanup complete | When you disable prebuilds or delete the warm pool, instances drain gracefully. The pool enters the **Deleting** phase and transitions to **Deleted** once all instances are terminated. ## Cost Warm pool instances are regular compute instances in your cloud account. With dynamic scaling, you pay only for instances that are actually running. The pool scales down during low-demand periods. No Ona credits are consumed. You pay only for the cloud infrastructure. **Running instances** (actively serving or waiting to be claimed) are billed at standard on-demand rates. **Stopped instances** (pre-provisioned for fast scale-out) are not billed for compute. You pay only for their attached storage. Start with `min-size = 1` and `max-size = 2`. Increase `max-size` if your team frequently hits cold starts during peak hours. Switch to `min-size = 0` once you're comfortable with the startup tradeoff during off-hours. ### AWS cost estimates Costs depend on the [environment class](/docs/ona/runners/aws/environment-classes) (instance type) and AWS region. Estimates below use `us-east-1` on-demand pricing: | Environment Class | Instance Type | Approx. cost per running instance/month | | ----------------- | --------------------------- | --------------------------------------- | | Small | m6i.large (2 vCPU, 8 GB) | \~\$70 | | Regular | m6i.xlarge (4 vCPU, 16 GB) | \~\$140 | | Large | m6i.2xlarge (8 vCPU, 32 GB) | \~\$280 | **Example**: A warm pool configured with `min-size = 0` and `max-size = 3` using `m6i.xlarge` (Regular) instances might average 1 running instance during business hours and 0 outside of them. That costs roughly **\$70–100/month** instead of \$280/month for a fixed pool of 2. EBS volume costs are additional but typically small relative to compute, roughly \$0.08/GB/month for gp3 volumes. Filter AWS Cost Explorer by the tag `gitpod.dev/warm-pool` to isolate warm pool instance costs from regular environment costs. See [Costs & budgeting](/docs/ona/runners/aws/aws-runner-costs) for general cost tracking. ### GCP cost estimates Costs depend on the machine type and GCP region. Estimates below use `us-central1` on-demand pricing: | Machine Type | vCPUs | Memory | Approx. cost per running instance/month | | -------------- | ----- | ------ | --------------------------------------- | | n2d-standard-2 | 2 | 8 GB | \~\$65 | | n2d-standard-4 | 4 | 16 GB | \~\$130 | | n2d-standard-8 | 8 | 32 GB | \~\$260 | Persistent disk costs are additional but typically small relative to compute. See [Costs & budgeting](/docs/ona/runners/gcp/gcp-runner-costs) for general cost tracking. ## Sizing guidance | Team size | Recommended min | Recommended max | Rationale | | --------------- | --------------- | --------------- | ---------------------------------------------------------- | | 1-10 engineers | 0-1 | 2 | Low concurrency; scale-to-zero saves cost for small teams | | 10-30 engineers | 1 | 3 | Keeps one instance always ready; scales for burst patterns | | 30+ engineers | 1-2 | 3-5 | Higher baseline for peak-hour concurrency | These are starting points. The right configuration depends on how large the project is (larger projects take longer to replenish), how often engineers create new environments versus reusing existing ones, and whether off-hours cost savings matter. Monitor your pool's claim hit rate and adjust. ## Viewing warm pool usage You can view warm pools configured in your organization from the dashboard or CLI. Organization admins see all warm pools. Other members only see warm pools for projects they have access to. ### Via the dashboard Navigate to a runner's details page and select the **Warm Pools** tab. This shows all warm pools on that runner, including the associated project, environment class, pool size, and current phase. ### Via the CLI ```bash theme={null} # List all warm pools in the organization ona prebuild warm-pool list # Filter by a specific project ona prebuild warm-pool list --project-id # Filter by environment class ona prebuild warm-pool list --environment-class-id # Output as JSON for scripting ona prebuild warm-pool list --format json # Get details for a specific warm pool ona prebuild warm-pool get ``` ## Monitoring Warm pools expose Prometheus metrics through the runner's metrics endpoint. Use these to track pool utilization, claim hit rate, and scaling behavior. See [Custom metrics pipeline](/docs/ona/runners/monitoring-and-metrics#warm-pools-warm_pool_) for setup instructions and the full list of available metrics. Key metrics to watch: * **`warm_pool_claims_total`**: Track the `instance_not_found` result to see how often users hit cold starts. If this happens frequently, increase `max-size` or `min-size` (the pool may be scaling down too aggressively). * **`warm_pool_claim_instance_age_seconds`**: Shows how long instances waited before being claimed. Very short ages may indicate the pool is undersized. * **`warm_pool_instances_by_state`**: Compare running vs stopped instance counts to verify scaling behavior. ## Limitations * **No spot instances (AWS).** Warm pools require on-demand environment classes. If you enable a warm pool on a [spot environment class](/docs/ona/runners/aws/environment-classes#spot-instance-reclamation), the pool enters the [**Degraded** phase](#pool-lifecycle). Use a non-spot class instead. ## Related * [Prebuilds overview](/docs/ona/projects/prebuilds) * [Setting up prebuilds](/docs/ona/projects/prebuilds-setup) * [AWS environment classes](/docs/ona/runners/aws/environment-classes) * [AWS runner costs](/docs/ona/runners/aws/aws-runner-costs) * [Upgrade AWS runner infrastructure](/docs/ona/runners/aws/update-runner#upgrade-runner-infrastructure) * [GCP runner costs](/docs/ona/runners/gcp/gcp-runner-costs) * [Upgrade GCP runner infrastructure](/docs/ona/runners/gcp/update-runner#updating-infrastructure) # Quickstart Source: https://ona.com/docs/ona/quickstart Get up and running with Ona in less than 5 minutes. Ona automations overview showing recent runs, filters, and suggested automation templates By the end of this guide you'll have an environment running your code and an agent working on your first task. Get started → Want to run Ona in your own VPC? [Get in touch](https://ona.com/contact/sales) to set up a self-hosted deployment on [AWS](/docs/ona/runners/aws/overview) or [GCP](/docs/ona/runners/gcp/overview). ## Prerequisites * An [Ona account](https://app.ona.com) * Select your [Git provider](/docs/ona/source-control/overview) ## 1. Create a project Ona projects page showing a grid of projects and a New project button A project connects a repository to Ona, giving you a single place to manage environments, Automations, secrets, and team access for that codebase. Once a project exists, anyone on your team can spin up a fully configured environment in seconds. No local setup, no "works on my machine" problems. Go to **Projects > New Project**, select your Git provider, and pick a repository. See [Create your first project](/docs/ona/create-first-project) for a detailed walkthrough. Speed up environment starts with [prebuilds](/docs/ona/projects/prebuilds) and [warm pools](/docs/ona/projects/warm-pools) so environments are ready before anyone needs them. ## 2. Start an environment Ona environment view showing a running environment with the conversation pane and environment details From your project, click **Create Environment**. Ona clones the repository into a container and provisions a development environment. Once the environment is running, you can open VS Code in your browser, talk to Ona, or [connect your preferred IDE](/docs/ona/editors/overview). If the environment stays in a loading state for more than two minutes, check that your repository is accessible and that your Git provider is connected under **Settings > Git Authentications**. See [troubleshooting](/docs/ona/troubleshooting) for more. ## 3. Talk to Ona Once your environment is running, you have a session with Ona. Describe what you want to build, fix, or explore: Paste one of these prompts into Ona:
Explore a codebase
"Explain the architecture of this codebase"
Paste into Ona
Fix failing tests
"Fix the failing tests in the auth module"
Paste into Ona
Add a feature
"Add a new API endpoint for user preferences, following the patterns in the existing code"
Paste into Ona
Review pull requests
"Review the open pull requests and leave detailed code review comments"
Paste into Ona
If you've connected [Linear](/docs/ona/integrations/configure-linear) or [Jira](/docs/ona/integrations/configure-atlassian), you can ask Ona to pick up tickets directly:
Pick up a Linear ticket
"Pick up the next ticket assigned to me in Linear and start working on it"
Paste into Ona
Implement a Jira ticket
"Look at PROJ-142 in Jira and implement what's described"
Paste into Ona
## 4. Optimize your environment Ona works out of the box with a default image, but you'll get better results with a configured environment. You can set this up manually or let Ona do it. It will analyze your repository and generate a `devcontainer.json` and `.ona/config.yaml` tailored to your codebase. Open Ona, then paste the prompt below if you want Ona to generate a starter configuration for the current environment. Open Ona → ```text theme={null} Create a high-quality, fully working "development environment as code" configuration for the current environment. The setup must work for: - Ona development environments, which use DevContainer configurations. - All Git repositories mounted under the DevContainer workspace. Required Process 1. Read the documentation to fully understand: - Ona tasks and services, secrets, environment variables, CLI, and prebuilds. - DevContainer fundamentals and how they integrate with Ona and VS Code. 2. Analyze the source code and identify: - Documentation on dev setup or contribution guidelines. - Configuration files for containers, IDEs, build tools, environment variables, etc. 3. Update all necessary files, including: - devcontainer.json - Ona tasks and services 4. Run the Acceptance Tests and iterate until they pass. Success Criteria - The DevContainer includes all tools needed to work with any file in any repo. - Ona services exist for every service required to run any app. - Ona tasks exist for all standard development workflows. - If an app exposes a TCP port, the DevContainer must forward it. - The DevContainer installs all VS Code extensions necessary to work effectively. Allowed Sources - Ona documentation: https://ona.com/docs/llms.txt - DevContainer documentation: https://containers.dev/ - DevContainers in VS Code: https://code.visualstudio.com/docs/devcontainers/containers - DevContainer base images: https://hub.docker.com/r/microsoft/devcontainers - Any publicly available DevContainer features ``` See [configure your environment](/docs/ona/configuration/devcontainer/getting-started) for a full reference on manual configuration. ## 5. Run agents in the background Ona automation editor showing the 10x engineer workflow configuration Start multiple tasks from the home page using **Cmd+Enter** (Ctrl+Enter on Windows/Linux). Each task gets its own environment, so agents work in parallel without file conflicts. When you're ready to automate that on a schedule, set up [Automations](/docs/ona/create-first-automation) to run agents on triggers like new issues or pull requests: ## Tips * **Be specific.** Describe the exact symptom and location rather than saying "fix the bug." See [be explicit](/docs/ona/best-practices#be-explicit). * **Plan first.** For complex tasks, ask Ona to plan before implementing. See [plan before building](/docs/ona/best-practices#plan-before-building). * **Commit often.** Ask Ona to commit working changes as checkpoints. See [commit early, commit often](/docs/ona/best-practices#commit-early-commit-often). ## Next steps * [Best practices](/docs/ona/best-practices) for writing effective prompts and working with agents * [Configure your environment](/docs/ona/configuration/devcontainer/getting-started) with Dev Containers, tasks, and services * [Connect integrations](/docs/ona/integrations/overview) like Linear, Jira, Slack, and Sentry * [Set up automations](/docs/ona/automations/configure-automations) to run agents on schedules and triggers * [Teach agents your codebase](/docs/ona/agents-md) with AGENTS.md # Organization-level skills Source: https://ona.com/docs/ona/skills Codify your organization's best practices into reusable skills that agents can discover and anyone can run. Your best engineers have prompts that work - ways of reviewing code, writing tests, or debugging issues that they've refined over time. Skills let you capture that expertise and share it with everyone. Skills are reusable prompts that the agent can discover and use proactively when relevant. They can optionally be made available as slash commands, so users can also invoke them manually by typing `/` in the chat. Slash command menu showing available skills while the user types /code-review ## Why this matters Without shared skills, quality varies. One developer's code review catches security issues; another's misses them. One person knows how to write tests that actually test behavior; others write tests that only hit coverage targets. With skills: * **Expertise scales**: A senior engineer's review checklist becomes available to the whole team * **Quality standardizes**: Everyone follows the same thorough process * **Onboarding accelerates**: New team members immediately have access to proven workflows * **Agents get smarter**: Skills are discoverable by the agent, so it can apply them proactively without being asked ## What a great skill looks like Here's a real example - a code review skill that captures one engineer's review philosophy: ```markdown theme={null} /review-like-mads You are reviewing code changes with Mads Hartmann's perspective. Apply his review philosophy systematically: ## Design System First - **Theme compatibility**: Works in light/dark AND old/new themes? - **Semantic tokens**: Replace hardcoded colors with `border-subtle`, `surface-glass` - **Visual evidence**: Request screenshots/videos if missing - **Design alignment**: Matches Figma specs? ## Aggressive Cleanup - **Remove unused**: Components, imports, files, commented code - **Consolidate**: Similar components that could be unified - **File organization**: Components in right locations? ## Technical Excellence - **React patterns**: Proper `forwardRef`, `useImperativeHandle`, TypeScript - **Component reuse**: Composing existing vs creating new - **Accessibility**: ARIA, keyboard nav, screen readers ## Red Flags - Hardcoded colors (`#fff`, `rgb()`) - Duplicate patterns - Missing visual docs - Poor TypeScript **Priority order**: Design system consistency → Code cleanliness → Component reusability → Technical implementation → Test coverage ``` Now anyone can type `/review-like-mads` and get a review with that level of rigor. The agent can also apply this skill on its own when it detects a code review task. ## More examples | Skill | What it codifies | | ------------------- | ---------------------------------------------------- | | `/security-review` | Your security team's checklist for reviewing PRs | | `/write-tests` | How your team writes tests that actually catch bugs | | `/explain-this` | Your standard for documentation and code explanation | | `/debug-strategy` | Your senior engineer's approach to debugging | | `/deploy-checklist` | Everything to verify before shipping | ## Create your first skill 1. Go to [Settings > Agents > Skills](https://app.ona.com/settings/agent-skills) 2. Click **New Skill** 3. Configure: * **Name**: What appears in the skill list (e.g., "Review like Mads") * **Description**: When to use it * **Prompt**: The full prompt text * **Available as slash command**: Toggle on if you want users to invoke it with a `/trigger` * **Command trigger**: The slash trigger (e.g., `review-like-mads`). Only shown when the slash command toggle is on 4. Click **Create Skill** New Skill modal showing fields for name, description, prompt, and slash command availability ## Using skills Skills work in two ways: 1. **Proactive discovery**: The agent automatically discovers skills and applies them when a task matches. No user action needed. 2. **Slash commands**: For skills with a command trigger, type `/` in the agent prompt to see available commands. Start typing to filter, then select with arrow keys or click. You can add context after a slash command: ``` /review-like-mads Focus especially on the authentication changes in src/auth/ ``` The agent combines the skill's prompt with the additional context you provide. ## Migrating legacy commands Existing slash commands created before skills were introduced appear as **Legacy Commands** in the settings page. They continue to work as before, but won't be discovered proactively by the agent. To migrate a legacy command to a skill, click **Edit** on the command card and use the **Migrate to Skill** button in the banner. Migration preserves the slash command trigger while enabling proactive discovery. ## Tips for good skills **Capture real expertise**: Base skills on how your best people actually work, not theoretical ideals. **Be specific**: "Security Review" is better than "Review". Include the actual checklist, not "check for security issues." **Include priorities**: Tell agents what matters most. "Focus on X before Y" helps them make tradeoffs. **Update over time**: When someone catches something your skill missed, add it to the prompt. ## Example skills we use at Ona These are real skills from our own workflow. They show what a well-structured skill looks like at scale. Automates the full PR lifecycle from diff to merge-ready. The skill: 1. Cleans up code and runs formatters/linters 2. Detects linked Linear issues automatically from branch names 3. Creates a branch using your initials and a short description 4. Commits with Conventional Commits format 5. Opens a draft PR using your repo's PR template 6. Auto-categorizes for the changelog (feature, improvement, fix, or skip) 7. Cross-references documentation and runs a docs content review 8. Posts a summary and asks for changelog confirmation The skill handles edge cases like feature-flag detection (auto-skips changelog for flagged work), in-progress feature detection across related PRs, and separate docs PRs when code changes need documentation updates. PR workflow skill that gathers context, reads diffs, posts comments, and submits reviews. The skill: 1. Gathers PR metadata, diffs, existing reviews, and CI status 2. Fetches context from Linear (linked issues), GitHub (discussions), and Notion (design docs) 3. Delegates code quality analysis to a separate `review` skill that detects scope (backend Go, frontend React/TS, or mixed) and loads the appropriate checklist 4. Classifies findings by severity: `[P0]` Must fix, `[P1]` Should fix, `[P2]` Suggestion 5. Posts inline comments on specific lines with actionable fixes 6. Submits formal PR reviews (approve, request changes, or comment) via the GitHub API 7. Runs documentation review and product principles checks on frontend PRs 8. Auto-applies changelog labels if missing Generates changelog entries from merged PRs in two modes: **weekly** (default) and **major** (standalone feature launch page). For weekly changelogs, the skill: 1. Finds the boundary using git tags from the previous changelog run 2. Collects all merged PRs since the boundary via GitHub 3. Classifies each PR as New, Improvement, Bug fix, or Skip using labels, commit types, and LLM analysis 4. Filters out internal-only changes, feature-flagged work, and infrastructure PRs 5. Picks a headline feature and generates a 2-4 sentence description 6. Produces a Mintlify `Update` block with the headline, screenshot placeholder, and collapsible accordion sections 7. Opens a draft PR with the entry All prose follows the `technical-writing` and `blog-writing` skill rules. The skill bans internal jargon (like "management plane", "Ent schema", "orchestrator") and rewrites everything from the user's perspective. Finds flaky Go tests and CI build failures on main, diagnoses root causes, fixes what's mechanical, and raises individual PRs per fix. The skill: 1. Queries Honeycomb for Go test failures on main (last 24h and 7d trend) 2. Queries Honeycomb and GitHub Actions for CI build failures 3. Triages and ranks failures by frequency, impact, and fixability 4. For each flaky test, diagnoses the root cause (race conditions, shared state, non-deterministic ordering, testcontainer lifecycle, etc.) 5. Applies mechanical fixes under 20 lines, only proceeding when the root cause is clear 6. Runs the full test package 3 times with `-race` to verify stability 7. Opens individual ready-for-review PRs with re-run evidence The skill follows a strict confidence gate: if the fix exceeds 20 lines, changes test semantics, or has an unclear root cause, it skips and logs the reason. A style guide that ensures consistent tone and structure across all developer-facing content. Key principles: * **Bottom line up front**: If the reader stops after the first paragraph, they should have what they need * **Show, don't tell**: Prefer code examples over explanations, prompts over tutorials * **Diataxis classification**: Every page belongs to exactly one type (tutorial, how-to guide, reference, or explanation) * **Verify against source code**: Every claim must match the current code. When docs and code disagree, the code is right * **Agent-ready**: Write docs that work as context for coding agents. Structure content so an agent can find the right page, extract the answer, and act on it The skill includes a review checklist covering Diataxis type, code verification, link checking, heading quality, tier labeling, and messaging anti-patterns. Query distributed tracing data across production, CI, and development environments. The skill documents: * **Production datasets**: Backend API traces, EC2/GCP runner traces, and supervisor (in-environment) traces * **CI datasets**: GitHub Actions workflow traces (via Thoth), Leeway build traces with Go test results * **Key columns**: Environment IDs, organization IDs, RPC error codes, startup durations, test results, cache status * **Example queries**: Environment startup duration, slowest RPC endpoints, failed builds, flaky test detection, supervisor setup times The skill also includes instructions for constructing direct Honeycomb URLs so users can explore interactively, and documents gotchas like the attribute split across parent/child spans for startup traces. ## Next steps * [Teach agents your codebase](/docs/ona/agents-md) with [AGENTS.md](/docs/ona/agents-md) and [Skills](/docs/ona/agents-md#skills-for-repository-specific-workflows) * [Configure integrations](/docs/ona/integrations/overview) to connect agents with your project management # Azure DevOps Source: https://ona.com/docs/ona/source-control/azuredevops Configure Azure DevOps as a source control provider for your Ona environments. Azure DevOps is supported on [Self-Hosted Runners](/docs/ona/runners/aws/overview). Set up the integration during runner creation or in runner settings. Self-hosted Azure DevOps instances are supported by changing the Host during setup. Azure DevOps is not available on Ona Cloud. Creating an environment from an Azure DevOps repository there fails with: `Ona Cloud (US01) requires authentication with Source Control - the SCM integration for host dev.azure.com is not configured`. ## Configuring Azure DevOps Access If Azure DevOps is already set up on your runner, skip to [Authorizing Azure DevOps Access](#authorizing-azure-devops-access). ### Self-Hosted Runners For self-hosted runners (like AWS), Azure DevOps integration is configured during runner creation or in the runner settings. There are two ways to integrate with Azure DevOps. Both can be used simultaneously: 1. **OAuth App (Recommended):** Using a Microsoft Entra ID OAuth app allows users to sign in more quickly. You'll need to set up an OAuth app within Microsoft Entra ID. 2. **Personal Access Token (PAT):** Each user will need to create a Personal Access Token. They will be provided with a deep link to do so on their first environment creation. For Azure DevOps, allow outbound HTTPS connections from your runner to `app.vssps.visualstudio.com` in your firewall, proxy, or egress filtering rules. Ona uses this Azure DevOps identity endpoint to validate the user's OAuth or PAT credentials and resolve the Azure DevOps profile before the runner can access repositories on that user's behalf. This request is made by the runner, not by a user's browser, and it is separate from Git or REST traffic to `dev.azure.com`. If the endpoint is blocked, Azure DevOps authorization can fail even when repository URLs are otherwise reachable. #### Using OAuth OAuth requires a [Microsoft Entra ID](https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/entra-oauth?view=azure-devops) app registration. You will set up the app in Azure, then enter its credentials in Ona. **Step 1: Create the Entra ID app registration** 1. Go to the [Azure Portal](https://portal.azure.com) and navigate to **Microsoft Entra ID > App registrations**. 2. Click **New registration** and provide a name (e.g., "Ona Azure DevOps Integration"). 3. Note the *Client ID* from the **Overview** page. 4. Note the *Issuer URL* from **Overview > Endpoints**. Use the v2.0 URL, e.g. `https://login.microsoftonline.com/00000000-0000-0000-0000-000000000000/oauth2/v2.0`. **Step 2: Configure authentication** 1. In your app registration, go to **Manage > Authentication**. 2. Ensure **Web** platform is selected and paste the callback URL from the Ona configuration dialog. 3. Enable **ID tokens** under *Implicit grant and hybrid flows*. Microsoft Entra ID authentication settings showing Web platform with ID tokens enabled **Step 3: Create a client secret** 1. Navigate to **Manage > Certificates & secrets**. 2. Click **New client secret**, add a description, and set expiration as needed. 3. Copy the secret **Value** immediately (it is only shown once). Microsoft Entra ID Certificates and secrets page for creating a new client secret **Step 4: Configure API permissions** Go to **Manage > API permissions** and add the following scopes: | API | Scope | Purpose | | --------------- | ---------------- | --------------------------------------------------------- | | Microsoft Graph | `openid` | OpenID Connect authentication | | Microsoft Graph | `offline_access` | Refresh tokens | | Azure DevOps | `vso.code` | Read repositories, commits, pull requests, refs, branches | | Azure DevOps | `vso.code_write` | Commit and push operations | Microsoft Entra ID API permissions showing Microsoft Graph and Azure DevOps scopes **Step 5: Prepare Azure DevOps** 1. In Azure DevOps, go to **Organization Settings > Security > Policies** and enable **Third-party application access via OAuth**. Azure DevOps Security Policies page with Third-party application access via OAuth setting 2. Go to **Organization Settings > General** and connect your Microsoft Entra ID tenant. Azure DevOps organization settings showing Microsoft Entra ID connection **Step 6: Connect in Ona** 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **Azure DevOps (Entra ID)**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable OAuth**. 4. Enter the **Issuer URL**, **Client ID**, and **Client Secret** from the steps above. The client secret is encrypted with the runner's public key, so only the runner can read it. 5. Click **Save & Test**. This also verifies the connection to Entra ID. #### Using Personal Access Tokens (PATs) 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **Azure DevOps**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable Personal Access Token**. 4. Click **Save**. ## Authorizing Azure DevOps Access ### Using OAuth (Microsoft Entra ID) 1. When creating your first environment, you will be prompted to authorize. Click **Connect**. A new window opens directing you to Microsoft Entra ID to authorize the OAuth app with the scopes configured above. 2. After authorizing, close the window. You should see a confirmation that Azure DevOps (Entra ID) is connected. ### Using Personal Access Tokens (PATs) 1. When creating your first environment, you will be asked to authorize the new application. Select *Provide a Personal Access Token*. * Follow the instructions of the Azure documentation to create a PAT * The name of the token and all required scopes are pre-set. * By default, the token is valid for 30 days, but you can change the duration if needed. 2. After creating the token, return to the dialog and paste the token. 3. The environment will now be created using the provided token. # Bitbucket Cloud Source: https://ona.com/docs/ona/source-control/bitbucket Configure Bitbucket Cloud as a source control provider for your Ona environments. Source control integrations can be configured for both [Self-Hosted Runners](/docs/ona/runners/aws/overview) and [Ona Cloud](/docs/ona/runners/ona-cloud). You can set up a Bitbucket integration during runner creation or in the runner settings. Self-hosted Bitbucket instances (Bitbucket Server / Data Center) are currently not supported. ## Configuring Bitbucket Access If Bitbucket is already set up on your runner, skip to [Authorizing Bitbucket Access](#authorizing-bitbucket-access). ### Ona Cloud [Ona Cloud](/docs/ona/runners/ona-cloud) provides built-in Bitbucket Cloud integration with no configuration required. [Authorize access to Bitbucket](#authorizing-bitbucket-access) when creating your first environment. ### Self-Hosted Runners For self-hosted runners (like AWS), Bitbucket integration is configured during runner creation or in the runner settings. We are currently supporting OAuth for authorizing Bitbucket access. Support for Personal Access Tokens (PATs) is planned. #### Using OAuth 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **Bitbucket**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable OAuth**. 4. Follow the instructions in [Bitbucket's docs](https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/) to create an OAuth app. * The app name can be any name you like * You can get the callback URL from the configuration dialog * Select the required scopes: * *account* so that the git author name and email can be set in the environment * *repository* so that the repository can be cloned and the context URL can be parsed * *repository:write* so that changes can be pushed from the environment * *pullrequest* so that an environment can be started from a pull request 5. Enter the **Client ID** and **Client Secret** from the OAuth app. Bitbucket calls these *Key* and *Secret*. The client secret is encrypted with the runner's public key, so only the runner can read it. 6. Click **Save & Test**. ## Authorizing Bitbucket Access ### Using OAuth 1. When creating your first environment, you will be asked to authorize the new application. To use OAuth press the *Connect* button. A new window will open that directs you to Bitbucket to authorize the OAuth app. The requested scopes are *account*, *repository*, *repository:write*, and *pullrequest*. * The *account* scope is required so that the git author name and email can be set in the environment * The *repository* scope is required so that the repository can be cloned and the context URL can be parsed * The *repository:write* scope is required so that changes can be pushed from the environment * The *pullrequest* scope is required so that an environment can be started from a pull request 2. After you have authorized, you can close the window. After a few seconds you should get a confirmation that Bitbucket is now connected. # GitHub Source: https://ona.com/docs/ona/source-control/github Configure GitHub as a source control provider for your Ona environments. Source control integrations can be configured for both [Self-Hosted Runners](/docs/ona/runners/aws/overview) and [Ona Cloud](/docs/ona/runners/ona-cloud). You can set up a GitHub integration during runner creation or in the runner settings. Self-hosted GitHub instances are supported by changing the Host during setup. ## Configuring GitHub Access If GitHub is already set up on your runner, skip to [Authorizing GitHub Access](#authorizing-github-access). ### Self-Hosted Runners For self-hosted runners (like AWS), GitHub integration is configured during runner creation or in the runner settings. There are two ways to integrate with GitHub. Both can be used simultaneously: 1. **OAuth App (Recommended):** Using an OAuth app allows users to sign in more quickly. You'll need to set up an OAuth app within Ona. 2. **Personal Access Token (PAT):** Each user will need to create a Personal Access Token. They will be provided with a deep link to do so on their first environment creation. #### Using OAuth 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **GitHub**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable OAuth**. 4. Follow the instructions in [GitHub's docs](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) to create an OAuth app. * The app name can be any name you like * For the homepage URL, you can use [https://app.ona.com/](https://app.ona.com/) * You can get the callback URL from the configuration dialog 5. Enter the **Client ID** and **Client Secret** from the OAuth app. The client secret is encrypted with the runner's public key, so only the runner can read it. 6. Click **Save & Test**. #### Using Personal Access Tokens (PATs) 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **GitHub**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable Personal Access Token**. 4. Click **Save**. ### Ona Cloud Ona Cloud provides built-in GitHub integration with no configuration required: * **github.com** is supported by default using Ona's managed OAuth application * **No OAuth app setup needed** - Ona manages the OAuth application for you * **Automatic authentication** - Users can authenticate with their GitHub accounts immediately For custom GitHub instances or advanced repository access configurations, consider [upgrading to Enterprise](/docs/ona/runners/ona-cloud#upgrading-to-enterprise) with self-hosted runners. ## Authorizing GitHub Access ### Using OAuth 1. When creating your first environment, you will be asked to authorize the new application. A new window will open that directs you to GitHub to authorize the OAuth app. * The requested scopes are *repo*, *read:user*, *user:email*, and *workflow*. * The *repo* permission is required so that your environment can clone the repository. * The *read:user* permission is required so that the git author name can be set in the environment. * The *user:email* permission is required so that the git author email can be set in the environment. * The *workflow* permission is required so that GitHub Action YAML files can be edited in the environment. 2. After you have authorized, you can close the window and go back to the environment details screen. ### Using Personal Access Tokens (PATs) 1. The first time a user creates an environment, they will be asked to enter a Personal Access Token. * Click the link provided on the screen to access the configuration dialog for creating a GitHub token. * The name of the token and all required scopes are pre-set. * By default, the token is valid for 30 days, but you can change the duration if needed. 2. After creating the token, return to the dialog and paste the token. 3. The environment will now be created using the provided token. ## Granting Access to Additional GitHub Organizations After your initial OAuth authorization, you may need to grant Ona access to additional GitHub organizations to work with repositories from those organizations. This is a common scenario when you join new organizations or when organizations are added to your GitHub account after your initial setup. This section applies to OAuth-based authentication. If you're using Personal Access Tokens (PATs), you'll need to ensure your token has access to the required organizations when creating the token. ### When You Need Additional Organization Access You'll need to grant additional organization access when: * You try to create an environment from a repository in an organization that wasn't previously authorized * You receive an error message indicating insufficient permissions for a specific organization * You join a new GitHub organization and want to use Ona with repositories from that organization ### Granting Access via GitHub Settings To grant Ona access to additional GitHub organizations: 1. **Navigate to GitHub OAuth Applications:** * Go to [GitHub Settings > Applications](https://github.com/settings/applications) * Click on the **Authorized OAuth Apps** tab * Find the Ona Cloud application in the list GitHub OAuth Applications list 2. **Review Current Organization Access:** * Click on the Ona Cloud application to view its details * You'll see a list of organizations and their access status * Organizations may show as **Granted**, **Denied**, or **Request access** OAuth app organization permissions 3. **Grant Access to New Organizations:** * For organizations showing **Request access**, click the **Request** button * For organizations you own, access will be granted immediately * For organizations you don't own, an access request will be sent to the organization owners 4. **Organization Owner Approval (if required):** * If you're not an owner of the organization, the organization owners will receive a notification * They can approve or deny the request from their organization settings * You'll receive an email notification once the request is processed ## Custom Git email address If you use GitHub's private email feature or want a specific commit email, create two user-level [environment variable secrets](/docs/ona/configuration/secrets/environment-variables): * `GIT_COMMITTER_EMAIL` - your desired email * `GIT_AUTHOR_EMAIL` - your desired email These override the default Git configuration in all new environments. Existing environments are not affected. Create a new environment to apply the change. ## Repository access permissions Ona requests broad GitHub permissions to enable environment creation from any of your repositories. Granting repository access does not mean AI agents automatically access your code. Agents only interact with repositories you explicitly open in an environment. Scoped repository access (granting access to specific repos only) is on the roadmap. ## Troubleshooting * Verify you have access to the repository on GitHub directly * Check that the organization has granted access to the Ona OAuth application * Ensure you're a member of the organization with appropriate repository permissions * Confirm you're a member of the organization on GitHub * Check if the organization has restricted OAuth app access * Contact your organization administrator to enable third-party application access Contact your GitHub organization owners and ask them to review pending OAuth application requests in **Settings > Third-party access**. If you enter a PAT, it confirms, then prompts again, the token is missing required scopes. Create a new token with `repo`, `workflow`, `read:user`, and `user:email`. Generate a correctly scoped token at: [github.com/settings/tokens/new](https://github.com/settings/tokens/new?scopes=repo%2Cworkflow%2Cread%3Auser%2Cuser%3Aemail\&description=ona). The link in our UI during PAT setup also pre-fills the required scopes. After creating the token, disconnect and reconnect GitHub at [Settings > Git Authentications](https://app.ona.com/settings/git-authentications). 1. Go to your organization's **Settings > Third-party access** 2. Review the Ona Cloud application request and verify the requested permissions 3. Click **Grant** or **Deny** based on your organization's policies You can also pre-approve trusted applications in your organization's Third-party access settings. # GitLab Source: https://ona.com/docs/ona/source-control/gitlab Configure GitLab as a source control provider for your Ona environments. Source control integrations can be configured for both [Self-Hosted Runners](/docs/ona/runners/aws/overview) and [Ona Cloud](/docs/ona/runners/ona-cloud). You can set up a GitLab integration during runner creation or in the runner settings. Self-hosted GitLab instances are supported by changing the Host during setup. ## Configuring GitLab Access If GitLab is already set up on your runner, skip to [Authorizing GitLab Access](#authorizing-gitlab-access). ### Self-Hosted Runners For self-hosted runners (like AWS), GitLab integration is configured during runner creation or in the runner settings. There are two ways to integrate with GitLab. Both can be used simultaneously: 1. **OAuth App (Recommended):** Using an OAuth app allows users to sign in more quickly. You'll need to set up an OAuth app within Ona. 2. **Personal Access Token (PAT):** Each user will need to create a Personal Access Token. They will be provided with a deep link to do so on their first environment creation. #### Using OAuth 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **GitLab**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable OAuth**. 4. Follow the instructions in [GitLab's docs](https://docs.gitlab.com/ee/integration/oauth_provider.html) to create an OAuth app. * The app name can be any name you like * You can get the callback URL from the configuration dialog * Select the required scopes: * *api* so that the context URL can be parsed * *read\_repository* so that your environment can clone the repository * *read\_user* so that the git author name and email can be set in the environment 5. Enter the **Client ID** and **Client Secret** from the OAuth app. The client secret is encrypted with the runner's public key, so only the runner can read it. 6. Click **Save & Test**. #### Using Personal Access Tokens (PATs) 1. Go to **Settings → Runners** and select the runner you want to configure. 2. In the **Configure repository access** section, click **Select** next to **GitLab**. If other providers are already configured, click **Add a new provider** first. 3. Toggle **Enable Personal Access Token**. 4. Click **Save**. ### Ona Cloud Ona Cloud provides built-in GitLab integration with no configuration required: * **gitlab.com** is supported by default using Ona's managed OAuth application * **No OAuth app setup needed** - Ona manages the OAuth application for you * **Automatic authentication** - Users can authenticate with their GitLab accounts immediately For custom GitLab instances or advanced repository access configurations, consider [upgrading to Enterprise](/docs/ona/runners/ona-cloud#upgrading-to-enterprise) with self-hosted runners. ## Authorizing GitLab Access ### Using OAuth 1. When creating your first environment, you will be asked to authorize the new application. To use OAuth press the *Connect* button. A new window will open that directs you to GitLab to authorize the OAuth app. The requested scopes are *api*, *read\_repository* and *read\_user*. * The *api* scope is required so that the context url can be parsed * The *read\_repository* scope is required so that your environment can clone the repository * The *read\_user scope* is required so that the git author name and git author email can be set in the environment 2. After you have authorized, you can close the window. After a few seconds you should get a confirmation that GitLab is now connected. ### Using Personal Access Tokens (PATs) 1. When creating your first environment, you will be asked to authorize the new application. Select *Provide a Personal Access Token*. * Click the link provided on the screen to access the configuration dialog for creating a GitLab token. * The name of the token and all required scopes are pre-set. * By default, the token is valid for 30 days, but you can change the duration if needed. 2. After creating the token, return to the dialog and paste the token. 3. The environment will now be created using the provided token. ## Plan availability | Plan | GitLab.com (SaaS) | Self-hosted GitLab | | ---------- | ----------------- | ----------------------- | | Core | ✓ | ✗ | | Enterprise | ✓ | ✓ (self-hosted runners) | GitLab login authentication on the Ona login page is currently in development. In the meantime, sign up with GitHub or Google, then add GitLab at [Settings > Git Authentications](https://app.ona.com/settings/git-authentications). # Git providers Source: https://ona.com/docs/ona/source-control/overview Source control integrations in Ona Ona connects to your existing Git provider to clone repositories into environments, push commits, and enable agents to interact with pull requests and issues. Source control integration is the bridge between your code host and Ona's [runner infrastructure](/docs/ona/runners/overview). Ona's [two-plane architecture](/docs/ona/understanding/architecture) keeps source control credentials on runners. They never reach the management plane. * **Your code stays where you choose.** With a self-hosted runner, source code and SCM credentials never leave your infrastructure. With [Ona Cloud](/docs/ona/runners/ona-cloud), code runs on Ona-managed infrastructure separate from the management plane. * **Authentication is per-user.** Each developer authorizes their own access via OAuth or a Personal Access Token (PAT). Ona uses these credentials to clone repos and push changes on behalf of that user. * **Agents inherit your permissions.** When an agent creates a pull request or adds a review comment, it acts using the environment owner's SCM credentials and respects the same repository permissions. ## How it works Source control configuration happens at two levels: 1. **Runner level**: An administrator configures which Git providers and authentication methods (OAuth, PAT) are available on a runner. This determines what providers developers can connect to. 2. **User level**: Each developer authorizes access to their Git provider. On first environment creation, Ona prompts for authorization using the methods the administrator configured. When a developer or agent starts an environment, the runner uses the developer's credentials to clone the repository. All subsequent git operations (commits, pushes, fetches) use the same credentials within that environment. ## Supported providers | Provider | OAuth | PAT | Agent SCM tools | | ------------------------------------------------ | ----- | ------- | ---------------- | | [GitHub](/docs/ona/source-control/github) | Yes | Yes | Yes | | [GitLab](/docs/ona/source-control/gitlab) | Yes | Yes | Yes | | [Bitbucket Cloud](/docs/ona/source-control/bitbucket) | Yes | Planned | Yes (Cloud only) | | [Azure DevOps](/docs/ona/source-control/azuredevops) | Yes | Yes | No | [Agent SCM tools](/docs/ona/agents/scm-tools) let agents create pull requests, manage issues, and add code review comments directly through your provider's API. ### Organization controls for SCM tools Administrators can control whether agents are allowed to use SCM tools across the organization. This is useful when your team requires human review of all SCM interactions, or when rolling out agent-assisted workflows gradually. Agent policy settings showing SCM Tools toggle with access restriction options Configure this in [Settings > Agents > Policies](https://app.ona.com/settings/agent-policies). When SCM tools are disabled, agents can still clone, commit, and push code using git, but cannot interact with your provider's API to create PRs or manage issues. See [SCM tools policy](/docs/ona/organizations/policies/scm-tools) for details. ## Setting up Git authentication To connect a Git provider to your Ona account: 1. Set up the SCM integration for your runner at [Settings > Runners](https://app.ona.com/settings/runners). **This is required for Enterprise only.** 2. Connect or disconnect available providers at [Settings > Git Authentications](https://app.ona.com/settings/git-authentications) For provider-specific setup instructions including required scopes and OAuth app configuration, see the individual provider pages above. ## Troubleshooting If you see `Failed to create provider - Aborted: operation cancelled` when configuring repository access, switch from Personal Access Token to **OAuth** authentication. # API Reference Source: https://ona.com/docs/api-reference Call the public Ona Connect API from scripts, services, and generated clients. The Ona API is a [Connect](https://connectrpc.com/) RPC API for managing Ona resources. Service and method pages are generated directly from the public Protocol Buffer definitions whenever the API is generated. ## Use the API base URL Send requests to `https://app.ona.com/api`. If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. Create and use tokens from the same domain. ## Authenticate requests Send a [personal access token](/docs/ona/integrations/personal-access-token) or [service account token](/docs/ona/organizations/service-accounts) as a Bearer token in the `Authorization` header. ```bash theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.EnvironmentService/ListEnvironments" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{}' ``` Tokens inherit the permissions of their user or service account. A request fails when the token does not grant the permission required by the method. ## Send Connect requests Unary methods accept `POST` requests with Protocol Buffer JSON request bodies. The generated method pages list the route, RPC cardinality, request fields, response fields, validation constraints, and a copyable example. Protocol Buffer JSON differs from ordinary JSON in a few places: * Field names use their lower camel-case JSON name, such as `environmentId`. * Enum values use symbolic names, such as `ENVIRONMENT_PHASE_RUNNING`. * 64-bit integers are strings. * `bytes` fields are base64-encoded strings. * Timestamps use RFC 3339 strings and durations use strings such as `60s`. * Unknown fields are rejected. Server-streaming methods use Connect message envelopes with `application/connect+json` or `application/connect+proto`. Use a generated Connect client for streaming rather than sending an unframed JSON body directly. ## Handle errors Connect errors contain a machine-readable code and message. Treat authentication and permission errors separately from validation failures, and do not retry requests with invalid arguments. Retry transient errors such as `unavailable` with exponential backoff. Never log Bearer tokens or secret request fields when recording failed requests. # Block Account Source: https://ona.com/docs/api-reference/generated/account/block-account Blocks an account, preventing all API access. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Blocks an account, preventing all API access. Use this method to: * Revoke access for policy violations * Handle abuse cases * Enforce compliance requirements When an account is blocked: * All API requests return 403 PERMISSION\_DENIED * All running environments are stopped * All active subscriptions are cancelled Requires the `block_account` permission. ### Examples * Block account for policy violation: ```yaml theme={null} accountId: "f53d2330-3795-4c5d-a1f3-453121af9c60" reason: "Terms of Service violation - spam" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/BlockAccount ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/BlockAccount" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "accountId": "", "reason": "" }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.BlockAccountRequest( account_id="", reason="", ) response = ona.services.account.block_account(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { BlockAccountRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(BlockAccountRequestSchema, { accountId: "", reason: "", }); const response = await ona.services.account.blockAccount(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.BlockAccountRequest{ AccountId: "", Reason: "", }) response, err := ona.Services.Account.BlockAccount(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "accountId": "", "reason": "" } ``` ## Request `gitpod.v1.BlockAccountRequest` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `accountId` | string | Yes | account\_id is the UUID of the account to block Constraints: `required=true, string.uuid=true`. | | `reason` | string | Yes | reason is the reason for blocking the account (required for audit trail) Constraints: `required=true, string.max_len=1024, string.min_len=1`. | ## Response `gitpod.v1.BlockAccountResponse` | Field | Type | Required | Description | | ------------------------ | ------- | -------- | --------------------------------------------------------------------------- | | `environmentsStopped` | integer | No | environments\_stopped is the number of environments that were stopped | | `subscriptionsCancelled` | integer | No | subscriptions\_cancelled is the number of subscriptions that were cancelled | # Delete Account Source: https://ona.com/docs/api-reference/generated/account/delete-account Deletes an account permanently. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Deletes an account permanently. Use this method to: * Remove unused accounts * Clean up test accounts * Complete account deletion requests The account must not be an active member of any organization. ### Examples * Delete account: Permanently removes an account. ```yaml theme={null} accountId: "f53d2330-3795-4c5d-a1f3-453121af9c60" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/DeleteAccount ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/DeleteAccount" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "accountId": "" }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.DeleteAccountRequest( account_id="", ) response = ona.services.account.delete_account(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { DeleteAccountRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(DeleteAccountRequestSchema, { accountId: "", }); const response = await ona.services.account.deleteAccount(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.DeleteAccountRequest{ AccountId: "", }) response, err := ona.Services.Account.DeleteAccount(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "accountId": "" } ``` ## Request `gitpod.v1.DeleteAccountRequest` | Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------ | | `accountId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `reason` | string | No | reason is an optional field for the reason for account deletion Constraints: `ignore=1, string.max_len=256`. | ## Response `gitpod.v1.DeleteAccountResponse` This message has no fields. # Get Account Source: https://ona.com/docs/api-reference/generated/account/get-account Gets information about the currently authenticated account. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Gets information about the currently authenticated account. Use this method to: * Retrieve account profile information * Check organization memberships * View account settings * Get joinable organizations ### Examples * Get account details: Retrieves information about the authenticated account. ```yaml theme={null} {} ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/GetAccount ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/GetAccount" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{}' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.GetAccountRequest() response = ona.services.account.get_account(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetAccountRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(GetAccountRequestSchema, {}); const response = await ona.services.account.getAccount(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetAccountRequest{}) response, err := ona.Services.Account.GetAccount(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} {} ``` ## Request `gitpod.v1.GetAccountRequest` This message has no fields. ## Response `gitpod.v1.GetAccountResponse` | Field | Type | Required | Description | | --------- | ---------------------------------- | -------- | ----------------------------- | | `account` | [Account](#type-gitpod-v1-account) | Yes | Constraints: `required=true`. | ## Related types `gitpod.v1.Account` | Field | Type | Required | Description | | --------------------- | ---------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------- | | `id` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `name` | string | Yes | Constraints: `required=true`. | | `avatarUrl` | string | No | | | `email` | string | Yes | Constraints: `required=true`. | | `createdAt` | RFC 3339 timestamp | Yes | Constraints: `required=true`. | | `updatedAt` | RFC 3339 timestamp | Yes | Constraints: `required=true`. | | `memberships` | array of [AccountMembership](#type-gitpod-v1-account-membership) | No | | | `joinables` | array of [JoinableOrganization](#type-gitpod-v1-joinable-organization) | No | **Deprecated.** joinables is deprecated. Use ListJoinableOrganizations instead. | | `publicEmailProvider` | boolean | No | public\_email\_provider is true if the email for the Account matches a known public email provider | | `organizationId` | string | No | organization\_id is the ID of the organization the account is owned by if it's created through custom SSO | `gitpod.v1.AccountMembership` | Field | Type | Required | Description | | ------------------------- | ----------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | | `userId` | string | Yes | user\_id is the ID the user has in the organization Constraints: `required=true, string.uuid=true`. | | `userRole` | [OrganizationRole](#enum-gitpod-v1-organization-role) | Yes | user\_role is the role the user has in the organization Constraints: `required=true`. | | `organizationId` | string | Yes | organization\_id is the id of the organization the user is a member of Constraints: `required=true, string.uuid=true`. | | `organizationName` | string | Yes | organization\_name is the name of the organization the user is a member of Constraints: `required=true`. | | `organizationMemberCount` | integer | No | organization\_member\_count is the member count of the organization the user is a member of | | `organizationTier` | [OrganizationTier](#enum-gitpod-v1-organization-tier) | No | organization\_tier is the tier of the organization (Free, Core, Enterprise) | `gitpod.v1.JoinableOrganization` | Field | Type | Required | Description | | ------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | organization\_id is the id of the organization the user can join Constraints: `required=true, string.uuid=true`. | | `organizationName` | string | Yes | organization\_name is the name of the organization the user can join Constraints: `required=true`. | | `organizationMemberCount` | integer | No | organization\_member\_count is the member count of the organization the user can join | | Value | Number | Description | | ------------------------------- | -----: | ----------- | | `ORGANIZATION_ROLE_UNSPECIFIED` | 0 | | | `ORGANIZATION_ROLE_ADMIN` | 1 | | | `ORGANIZATION_ROLE_MEMBER` | 2 | | | Value | Number | Description | | ------------------------------- | -----: | ----------- | | `ORGANIZATION_TIER_UNSPECIFIED` | 0 | | | `ORGANIZATION_TIER_FREE` | 1 | | | `ORGANIZATION_TIER_ENTERPRISE` | 2 | | | `ORGANIZATION_TIER_CORE` | 3 | | | `ORGANIZATION_TIER_FREE_ONA` | 4 | | # Get SSO Login URL Source: https://ona.com/docs/api-reference/generated/account/get-sso-login-url Gets the SSO login URL for a specific email domain. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Gets the SSO login URL for a specific email domain. Use this method to: * Initiate SSO authentication * Get organization-specific login URLs * Handle SSO redirects ### Examples * Get login URL: Retrieves SSO URL for email domain. ```yaml theme={null} email: "user@company.com" ``` * Get URL with return path: Gets SSO URL with specific return location. ```yaml theme={null} email: "user@company.com" returnTo: "https://gitpod.io/workspaces" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/GetSSOLoginURL ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/GetSSOLoginURL" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "email": "" }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.GetSSOLoginURLRequest( email="", ) response = ona.services.account.get_sso_login_url(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetSSOLoginURLRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(GetSSOLoginURLRequestSchema, { email: "", }); const response = await ona.services.account.getSSOLoginURL(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetSSOLoginURLRequest{ Email: "", }) response, err := ona.Services.Account.GetSSOLoginURL(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "email": "" } ``` ## Request `gitpod.v1.GetSSOLoginURLRequest` | Field | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------- | | `email` | string | Yes | email is the email the user wants to login with Constraints: `required=true, string.email=true`. | | `returnTo` | string | No | return\_to is the URL the user will be redirected to after login Constraints: `ignore=1, string.uri=true`. | ## Response `gitpod.v1.GetSSOLoginURLResponse` | Field | Type | Required | Description | | ---------- | ------ | -------- | ----------------------------------------------------------------------------------------- | | `loginUrl` | string | Yes | login\_url is the URL to redirect the user to for SSO login Constraints: `required=true`. | # List Joinable Organizations Source: https://ona.com/docs/api-reference/generated/account/list-joinable-organizations Lists organizations that the currently authenticated account can join. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Lists organizations that the currently authenticated account can join. Use this method to: * Discover organizations associated with the account's email domain. * Allow users to join existing organizations. * Display potential organizations during onboarding. ### Examples * List joinable organizations: Retrieves a list of organizations the account can join. ```yaml theme={null} {} ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/ListJoinableOrganizations ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/ListJoinableOrganizations" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "pagination": { "pageSize": 1 } }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 import gitpod.v1.pagination_pb2 as pagination_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.ListJoinableOrganizationsRequest( pagination=pagination_pb2.PaginationRequest( page_size=1, ), ) response = ona.services.account.list_joinable_organizations(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { ListJoinableOrganizationsRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(ListJoinableOrganizationsRequestSchema, { pagination: { pageSize: 1, }, }); const response = await ona.services.account.listJoinableOrganizations(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.ListJoinableOrganizationsRequest{ Pagination: &gitpodpb.PaginationRequest{ PageSize: 1, }, }) response, err := ona.Services.Account.ListJoinableOrganizations(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "pagination": { "pageSize": 1 } } ``` ## Request `gitpod.v1.ListJoinableOrganizationsRequest` | Field | Type | Required | Description | | ------------ | ------------------------------------------------------- | -------- | ----------------------------------------------------------------------------- | | `pagination` | [PaginationRequest](#type-gitpod-v1-pagination-request) | No | pagination contains the pagination options for listing joinable organizations | ## Response `gitpod.v1.ListJoinableOrganizationsResponse` | Field | Type | Required | Description | | ----------------------- | ---------------------------------------------------------------------- | -------- | ----------------------------- | | `joinableOrganizations` | array of [JoinableOrganization](#type-gitpod-v1-joinable-organization) | No | | | `pagination` | [PaginationResponse](#type-gitpod-v1-pagination-response) | Yes | Constraints: `required=true`. | ## Related types `gitpod.v1.JoinableOrganization` | Field | Type | Required | Description | | ------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | organization\_id is the id of the organization the user can join Constraints: `required=true, string.uuid=true`. | | `organizationName` | string | Yes | organization\_name is the name of the organization the user can join Constraints: `required=true`. | | `organizationMemberCount` | integer | No | organization\_member\_count is the member count of the organization the user can join | `gitpod.v1.PaginationRequest` | Field | Type | Required | Description | | ---------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `pageSize` | integer | No | Page size is the maximum number of results to retrieve per page. Defaults to 25. Maximum 100. Constraints: `int32.gte=0, int32.lte=100`. | | `token` | string | No | Token for the next set of results that was returned as next\_token of a PaginationResponse | `gitpod.v1.PaginationResponse` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `nextToken` | string | No | Token passed for retrieving the next set of results. Empty if there are no more results | # List Login Providers Source: https://ona.com/docs/api-reference/generated/account/list-login-providers Lists available login providers with optional filtering. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Lists available login providers with optional filtering. Use this method to: * View supported authentication methods * Get provider-specific login URLs * Filter providers by invite ### Examples * List all providers: Shows all available login providers. ```yaml theme={null} pagination: pageSize: 20 ``` * List for specific invite: Shows providers available for an invite. ```yaml theme={null} filter: inviteId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" pagination: pageSize: 20 ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/ListLoginProviders ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/ListLoginProviders" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "pagination": { "pageSize": 1 } }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 import gitpod.v1.pagination_pb2 as pagination_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.ListLoginProvidersRequest( pagination=pagination_pb2.PaginationRequest( page_size=1, ), ) response = ona.services.account.list_login_providers(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { ListLoginProvidersRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(ListLoginProvidersRequestSchema, { pagination: { pageSize: 1, }, }); const response = await ona.services.account.listLoginProviders(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.ListLoginProvidersRequest{ Pagination: &gitpodpb.PaginationRequest{ PageSize: 1, }, }) response, err := ona.Services.Account.ListLoginProviders(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "pagination": { "pageSize": 1 } } ``` ## Request `gitpod.v1.ListLoginProvidersRequest` | Field | Type | Required | Description | | ------------ | ------------------------------------------------------------- | -------- | -------------------------------------------------------------------- | | `pagination` | [PaginationRequest](#type-gitpod-v1-pagination-request) | No | pagination contains the pagination options for listing login methods | | `filter` | [Filter](#type-gitpod-v1-list-login-providers-request-filter) | No | filter contains the filter options for listing login methods | ## Response `gitpod.v1.ListLoginProvidersResponse` | Field | Type | Required | Description | | ---------------- | --------------------------------------------------------- | -------- | --------------------------------------------------------------------- | | `pagination` | [PaginationResponse](#type-gitpod-v1-pagination-response) | Yes | Constraints: `required=true`. | | `loginProviders` | array of [LoginProvider](#type-gitpod-v1-login-provider) | No | | | `allowCustom` | boolean | No | allow\_custom indicates whether custom SSO is allowed for this domain | ## Related types `gitpod.v1.ListLoginProvidersRequest.Filter` | Field | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------------------------------------------------------------- | | `inviteId` | string | No | invite\_id is the ID of the invite URL the user wants to login with Constraints: `string.uuid=true`. | | `email` | string | No | email is the email address to filter SSO providers by | `gitpod.v1.LoginProvider` | Field | Type | Required | Description | | ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------- | | `loginUrl` | string | No | login\_url is the URL to redirect the browser agent to for login, when provider is "custom" | | `provider` | string | Yes | provider is the provider used by this login method, e.g. "github", "google", "custom" Constraints: `required=true`. | `gitpod.v1.PaginationRequest` | Field | Type | Required | Description | | ---------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `pageSize` | integer | No | Page size is the maximum number of results to retrieve per page. Defaults to 25. Maximum 100. Constraints: `int32.gte=0, int32.lte=100`. | | `token` | string | No | Token for the next set of results that was returned as next\_token of a PaginationResponse | `gitpod.v1.PaginationResponse` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `nextToken` | string | No | Token passed for retrieving the next set of results. Empty if there are no more results | # List SSO Logins Source: https://ona.com/docs/api-reference/generated/account/list-sso-logins Call gitpod.v1.AccountService.ListSSOLogins. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/ListSSOLogins ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/ListSSOLogins" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "email": "" }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.ListSSOLoginsRequest( email="", ) response = ona.services.account.list_sso_logins(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { ListSSOLoginsRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(ListSSOLoginsRequestSchema, { email: "", }); const response = await ona.services.account.listSSOLogins(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.ListSSOLoginsRequest{ Email: "", }) response, err := ona.Services.Account.ListSSOLogins(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "email": "" } ``` ## Request `gitpod.v1.ListSSOLoginsRequest` | Field | Type | Required | Description | | ------------ | ------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------- | | `email` | string | Yes | email is the email the user wants to login with Constraints: `required=true, string.email=true`. | | `returnTo` | string | No | return\_to is the URL the user will be redirected to after login Constraints: `ignore=1, string.uri=true`. | | `pagination` | [PaginationRequest](#type-gitpod-v1-pagination-request) | No | pagination contains the pagination options for listing SSO logins | ## Response `gitpod.v1.ListSSOLoginsResponse` | Field | Type | Required | Description | | ------------ | ---------------------------------------------------------------- | -------- | ----------------------------- | | `logins` | array of [Login](#type-gitpod-v1-list-sso-logins-response-login) | No | | | `pagination` | [PaginationResponse](#type-gitpod-v1-pagination-response) | Yes | Constraints: `required=true`. | ## Related types `gitpod.v1.ListSSOLoginsResponse.Login` | Field | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------- | | `displayName` | string | Yes | provider is the provider used by this login method, e.g. "github", "google", "custom" Constraints: `required=true`. | | `loginUrl` | string | Yes | login\_url is the URL to redirect the user to for SSO login Constraints: `required=true`. | `gitpod.v1.PaginationRequest` | Field | Type | Required | Description | | ---------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `pageSize` | integer | No | Page size is the maximum number of results to retrieve per page. Defaults to 25. Maximum 100. Constraints: `int32.gte=0, int32.lte=100`. | | `token` | string | No | Token for the next set of results that was returned as next\_token of a PaginationResponse | `gitpod.v1.PaginationResponse` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `nextToken` | string | No | Token passed for retrieving the next set of results. Empty if there are no more results | # Accounts Source: https://ona.com/docs/api-reference/generated/account/overview Reference for the Accounts API methods. ## Methods Blocks an account, preventing all API access. Deletes an account permanently. Gets information about the currently authenticated account. Gets the SSO login URL for a specific email domain. Lists organizations that the currently authenticated account can join. Lists available login providers with optional filtering. Call gitpod.v1.AccountService.ListSSOLogins. Unblocks a previously blocked account, restoring API access. # Unblock Account Source: https://ona.com/docs/api-reference/generated/account/unblock-account Unblocks a previously blocked account, restoring API access. `Unary` · [`Accounts`](/docs/api-reference/generated/account/overview) Unblocks a previously blocked account, restoring API access. Use this method to: * Restore access after resolving policy violations * Reinstate accounts after review Note: Unblocking does NOT restore: * Stopped environments (must be restarted manually) * Cancelled subscriptions (must be re-subscribed) * Deleted resources Requires the `block_account` permission. ### Examples * Unblock account: ```yaml theme={null} accountId: "f53d2330-3795-4c5d-a1f3-453121af9c60" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AccountService/UnblockAccount ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AccountService/UnblockAccount" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "accountId": "" }' ``` ```python Python theme={null} import gitpod.v1.account_pb2 as account_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = account_pb2.UnblockAccountRequest( account_id="", ) response = ona.services.account.unblock_account(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { UnblockAccountRequestSchema } from "@gitpod/sdk/gitpod/v1/account_pb"; async function main() { const ona = createClientFromEnv(); const request = create(UnblockAccountRequestSchema, { accountId: "", }); const response = await ona.services.account.unblockAccount(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.UnblockAccountRequest{ AccountId: "", }) response, err := ona.Services.Account.UnblockAccount(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "accountId": "" } ``` ## Request `gitpod.v1.UnblockAccountRequest` | Field | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------------------------------------------------------- | | `accountId` | string | Yes | account\_id is the UUID of the account to unblock Constraints: `required=true, string.uuid=true`. | ## Response `gitpod.v1.UnblockAccountResponse` This message has no fields. # Create Agent Execution Conversation Token Source: https://ona.com/docs/api-reference/generated/agent/create-agent-execution-conversation-token Creates a token for conversation access with a specific agent run. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Creates a token for conversation access with a specific agent run. This method generates a temporary token that can be used to securely connect to an ongoing agent conversation, for example in a web UI. ### Examples * Create a token to join an agent run conversation in a front-end application: ```yaml theme={null} agentExecutionId: "6fa1a3c7-fbb7-49d1-ba56-1890dc7c4c35" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/CreateAgentExecutionConversationToken ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/CreateAgentExecutionConversationToken" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentExecutionId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.CreateAgentExecutionConversationTokenRequest( agent_execution_id="", ) response = ona.services.agent.create_agent_execution_conversation_token(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { CreateAgentExecutionConversationTokenRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(CreateAgentExecutionConversationTokenRequestSchema, { agentExecutionId: "", }); const response = await ona.services.agent.createAgentExecutionConversationToken(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.CreateAgentExecutionConversationTokenRequest{ AgentExecutionId: "", }) response, err := ona.Services.Agent.CreateAgentExecutionConversationToken(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentExecutionId": "" } ``` ## Request `gitpod.v1.CreateAgentExecutionConversationTokenRequest` | Field | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.CreateAgentExecutionConversationTokenResponse` | Field | Type | Required | Description | | ------- | ------ | -------- | ----------- | | `token` | string | No | | # Create Prompt Source: https://ona.com/docs/api-reference/generated/agent/create-prompt Creates a new prompt. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Creates a new prompt. Use this method to: * Define new prompts for templates or commands * Set up organization-wide prompt libraries ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/CreatePrompt ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/CreatePrompt" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "name": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.CreatePromptRequest( name="", ) response = ona.services.agent.create_prompt(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { CreatePromptRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(CreatePromptRequestSchema, { name: "", }); const response = await ona.services.agent.createPrompt(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.CreatePromptRequest{ Name: "", }) response, err := ona.Services.Agent.CreatePrompt(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "name": "" } ``` ## Request `gitpod.v1.CreatePromptRequest` | Field | Type | Required | Description | | ------------- | ------- | -------- | ------------------------------------------------------------------ | | `name` | string | No | Constraints: `string.max_len=255, string.min_len=1`. | | `description` | string | No | Constraints: `string.max_len=500, string.min_len=1`. | | `prompt` | string | No | Constraints: `string.max_len=20000, string.min_len=1`. | | `isTemplate` | boolean | No | | | `isCommand` | boolean | No | | | `command` | string | No | Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | | ## Response `gitpod.v1.CreatePromptResponse` | Field | Type | Required | Description | | -------- | -------------------------------- | -------- | ----------- | | `prompt` | [Prompt](#type-gitpod-v1-prompt) | No | | ## Related types `gitpod.v1.Prompt` | Field | Type | Required | Description | | ---------- | ------------------------------------------------- | -------- | ----------- | | `id` | string | No | | | `metadata` | [PromptMetadata](#type-gitpod-v1-prompt-metadata) | No | | | `spec` | [PromptSpec](#type-gitpod-v1-prompt-spec) | No | | `gitpod.v1.PromptMetadata` | Field | Type | Required | Description | | ---------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------------- | | `organizationId` | string | No | organization\_id is the ID of the organization that contains the prompt Constraints: `string.uuid=true`. | | `name` | string | No | name is the human readable name of the prompt | | `description` | string | No | description is a description of what the prompt does | | `creator` | Subject | No | creator is the identity of the prompt creator | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | `gitpod.v1.PromptSpec` | Field | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | | `prompt` | string | No | prompt is the content of the prompt Constraints: `string.max_len=20000`. | | `isTemplate` | boolean | No | is\_template indicates if this prompt is a template | | `isCommand` | boolean | No | is\_command indicates if this prompt is a command | | `command` | string | No | command is the unique command string within the organization Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | is\_skill indicates if this prompt is a skill (workflow instructions for agents) | # Delete Agent Execution Source: https://ona.com/docs/api-reference/generated/agent/delete-agent-execution Deletes an agent run. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Deletes an agent run. Use this method to: * Clean up agent runs that are no longer needed ### Examples * Delete an agent run by ID: ```yaml theme={null} agentExecutionId: "6fa1a3c7-fbb7-49d1-ba56-1890dc7c4c35" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/DeleteAgentExecution ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/DeleteAgentExecution" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentExecutionId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.DeleteAgentExecutionRequest( agent_execution_id="", ) response = ona.services.agent.delete_agent_execution(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { DeleteAgentExecutionRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(DeleteAgentExecutionRequestSchema, { agentExecutionId: "", }); const response = await ona.services.agent.deleteAgentExecution(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.DeleteAgentExecutionRequest{ AgentExecutionId: "", }) response, err := ona.Services.Agent.DeleteAgentExecution(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentExecutionId": "" } ``` ## Request `gitpod.v1.DeleteAgentExecutionRequest` | Field | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.DeleteAgentExecutionResponse` This message has no fields. # Delete Prompt Source: https://ona.com/docs/api-reference/generated/agent/delete-prompt Deletes a prompt. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Deletes a prompt. Use this method to: * Remove unused prompts ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/DeletePrompt ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/DeletePrompt" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "promptId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.DeletePromptRequest( prompt_id="", ) response = ona.services.agent.delete_prompt(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { DeletePromptRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(DeletePromptRequestSchema, { promptId: "", }); const response = await ona.services.agent.deletePrompt(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.DeletePromptRequest{ PromptId: "", }) response, err := ona.Services.Agent.DeletePrompt(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "promptId": "" } ``` ## Request `gitpod.v1.DeletePromptRequest` | Field | Type | Required | Description | | ---------- | ------ | -------- | -------------------------------- | | `promptId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.DeletePromptResponse` This message has no fields. # Get Agent Execution Source: https://ona.com/docs/api-reference/generated/agent/get-agent-execution Gets details about a specific agent run, including its metadata, specification, `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Gets details about a specific agent run, including its metadata, specification, and status (phase, error messages, and usage statistics). Use this method to: * Monitor the run's progress * Retrieve the agent's conversation URL * Check if an agent run is actively producing output ### Examples * Get agent run details by ID: ```yaml theme={null} agentExecutionId: "6fa1a3c7-fbb7-49d1-ba56-1890dc7c4c35" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/GetAgentExecution ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/GetAgentExecution" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentExecutionId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.GetAgentExecutionRequest( agent_execution_id="", ) response = ona.services.agent.get_agent_execution(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetAgentExecutionRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(GetAgentExecutionRequestSchema, { agentExecutionId: "", }); const response = await ona.services.agent.getAgentExecution(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetAgentExecutionRequest{ AgentExecutionId: "", }) response, err := ona.Services.Agent.GetAgentExecution(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentExecutionId": "" } ``` ## Request `gitpod.v1.GetAgentExecutionRequest` | Field | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.GetAgentExecutionResponse` | Field | Type | Required | Description | | ---------------- | ------------------------------------------------- | -------- | ----------- | | `agentExecution` | [AgentExecution](#type-gitpod-v1-agent-execution) | No | | ## Related types `gitpod.v1.AgentExecution` | Field | Type | Required | Description | | ---------- | ---------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `id` | string | No | ID is a unique identifier of this agent run. No other agent run with the same name must be managed by this agent manager | | `metadata` | [Metadata](#type-gitpod-v1-agent-execution-metadata) | No | Metadata is data associated with this agent that's required for other parts of Gitpod to function | | `spec` | [Spec](#type-gitpod-v1-agent-execution-spec) | No | Spec is the configuration of the agent that's required for the runner to start the agent | | `status` | [Status](#type-gitpod-v1-agent-execution-status) | No | Status is the current status of the agent | `gitpod.v1.AgentExecution.Metadata` | Field | Type | Required | Description | | ------------------ | ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | No | | | `description` | string | No | | | `creator` | Subject | No | | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | | `role` | [AgentExecutionRole](#enum-gitpod-v1-agent-execution-role) | No | role is the role of the agent execution | | `workflowActionId` | string | No | workflow\_action\_id is set when this agent execution was created as part of a workflow. Used to correlate agent executions with their parent workflow execution action. Constraints: `ignore=1, string.uuid=true`. | | `annotations` | map of string to string | No | annotations are key-value pairs for tracking external context. | | `sessionId` | string | No | session\_id is the ID of the session this agent execution belongs to. | `gitpod.v1.AgentExecution.Spec` | Field | Type | Required | Description | | --------------- | ---------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `specVersion` | 64-bit integer string | No | version of the spec. The value of this field has no semantic meaning (e.g. don't interpret it as as a timestamp), but it can be used to impose a partial order. If a.spec\_version \< b.spec\_version then a was the spec before b. | | `session` | string | No | | | `desiredPhase` | [Phase](#enum-gitpod-v1-agent-execution-phase) | No | desired\_phase is the desired phase of the agent run | | `agentId` | string | No | Constraints: `string.uuid=true`. | | `codeContext` | AgentCodeContext | No | | | `limits` | Limits | No | | | `codexSettings` | CodexSettings | No | codex\_settings contains persisted desired/manual settings for the Codex app agent. | `gitpod.v1.AgentExecution.Status` | Field | Type | Required | Description | | -------------------------- | ----------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `statusVersion` | 64-bit integer string | No | version of the status. The value of this field has no semantic meaning (e.g. don't interpret it as as a timestamp), but it can be used to impose a partial order. If a.status\_version \< b.status\_version then a was the status before b. | | `session` | string | No | | | `phase` | [Phase](#enum-gitpod-v1-agent-execution-phase) | No | | | `failureMessage` | string | No | failure\_message contains the reason the agent run failed to operate. | | `warningMessage` | string | No | warning\_message contains warnings, e.g. when the LLM is overloaded. | | `failureReason` | [AgentExecutionFailureReason](#enum-gitpod-v1-agent-execution-failure-reason) | No | failure\_reason contains a structured reason code for the failure. | | `conversationUrl` | string | No | conversation\_url is the URL to the conversation (all messages exchanged between the agent and the user) of the agent run. | | `transcriptUrl` | string | No | transcript\_url is the URL to the LLM transcript (all messages exchanged between the agent and the LLM) of the agent run. | | `supportBundleUrl` | string | No | support\_bundle\_url is the URL to download a diagnostic bundle for this agent execution. | | `conversationUrls` | ConversationURLs | No | conversation\_urls contains the v2 conversation streaming endpoints. When present, clients should use these URLs instead of conversation\_url. | | `iterations` | 64-bit integer string | No | | | `inputTokensUsed` | 64-bit integer string | No | | | `outputTokensUsed` | 64-bit integer string | No | | | `contextWindowLength` | 64-bit integer string | No | | | `cachedCreationTokensUsed` | 64-bit integer string | No | | | `cachedInputTokensUsed` | 64-bit integer string | No | | | `contextWindowLimit` | 64-bit integer string | No | context\_window\_limit is the selected model's maximum context window size in tokens. | | `judgement` | string | No | judgement is the judgement of the agent run produced by the judgement prompt. | | `currentOperation` | CurrentOperation | No | current\_operation is the current operation of the agent execution. | | `usedEnvironments` | array of EnvironmentUsage | No | used\_environments is the list of environments that were used by the agent execution. | | `currentActivity` | string | No | current\_activity is the current activity description of the agent execution. | | `outputs` | map of string to OutputValue | No | outputs is a map of key-value pairs that can be set by the agent during execution. Similar to task execution outputs, but with typed values for structured data. Constraints: `map.keys.string.max_len=128, map.keys.string.min_len=1`. | | `supportedModel` | [SupportedModel](#enum-gitpod-v1-supported-model) | No | supported\_model is the LLM model being used by the agent execution. | | `llmCapabilities` | LLMCapabilities | No | llm\_capabilities describes provider capabilities for the selected LLM integration. | | `mode` | [AgentMode](#enum-gitpod-v1-agent-mode) | No | mode is the current operational mode of the agent execution. This is set by the agent when entering different modes (e.g., Ralph mode via /ona:ralph command). | | `mcpIntegrationStatuses` | array of MCPIntegrationStatus | No | mcp\_integration\_statuses contains the status of all MCP integrations used by this agent execution | | `waitingInfo` | WaitingInfo | No | waiting\_info is set when phase is PHASE\_WAITING\_FOR\_INPUT and the agent has registered interests (timers, sub-agent completions, user messages). | | `terminalId` | string | No | terminal\_id is the ID of the terminal running the agent, if the agent runs as a terminal service (runsOn: terminal). | | `goal` | Goal | No | goal projects the current agent goal, if any. | | `codexSettings` | CodexSettings | No | codex\_settings contains runtime effective settings reported by the Codex app agent. | | `subagents` | array of Subagent | No | | | Value | Number | Description | | ------------------------- | -----: | ----------------------------------- | | `PHASE_UNSPECIFIED` | 0 | The phase is not set. | | `PHASE_PENDING` | 10 | The agent run is pending. | | `PHASE_RUNNING` | 20 | The agent run is active. | | `PHASE_WAITING_FOR_INPUT` | 30 | The agent run is waiting for input. | | `PHASE_STOPPED` | 40 | The agent run is inactive. | AgentExecutionFailureReason represents the reason why an agent execution failed | Value | Number | Description | | ------------------------------------------------ | -----: | --------------------------------------------------------------------------------------------------------------------------------------------- | | `AGENT_EXECUTION_FAILURE_REASON_UNSPECIFIED` | 0 | | | `AGENT_EXECUTION_FAILURE_REASON_ENVIRONMENT` | 1 | The agent execution failed due to environment issues | | `AGENT_EXECUTION_FAILURE_REASON_SERVICE` | 2 | The agent execution failed due to service issues | | `AGENT_EXECUTION_FAILURE_REASON_LLM_INTEGRATION` | 3 | The agent execution failed due to LLM integration issues | | `AGENT_EXECUTION_FAILURE_REASON_INTERNAL` | 4 | **Deprecated.** Deprecated: The agent execution failed due to internal errors Use AGENT\_EXECUTION\_FAILURE\_REASON\_AGENT\_EXECUTION instead | | `AGENT_EXECUTION_FAILURE_REASON_AGENT_EXECUTION` | 5 | The agent execution failed due to agent execution errors | AgentExecutionRole represents the role of an agent execution | Value | Number | Description | | ---------------------------------- | -----: | -------------------------------------------------------------- | | `AGENT_EXECUTION_ROLE_UNSPECIFIED` | 0 | | | `AGENT_EXECUTION_ROLE_DEFAULT` | 1 | Default role for agent executions | | `AGENT_EXECUTION_ROLE_WORKFLOW` | 2 | Workflow role for agent executions that are part of a workflow | AgentMode defines the operational mode of an agent | Value | Number | Description | | ------------------------ | -----: | ----------------------------------------------------------------- | | `AGENT_MODE_UNSPECIFIED` | 0 | Default execution mode - standard agent behavior | | `AGENT_MODE_EXECUTION` | 1 | Execution mode - agent performs tasks and makes changes | | `AGENT_MODE_PLANNING` | 2 | Planning mode - agent focuses on analysis and planning | | `AGENT_MODE_RALPH` | 3 | Ralph mode - autonomous planning and implementation mode | | `AGENT_MODE_SPEC` | 4 | Spec mode - planning phase followed by interactive implementation | | `AGENT_MODE_GOAL` | 5 | Goal mode - agent treats the user input as a goal objective | SupportedModel enumerates the LLM models available for agent executions | Value | Number | Description | | ------------------------------------- | -----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SUPPORTED_MODEL_UNSPECIFIED` | 0 | | | `SUPPORTED_MODEL_SONNET_3_5` | 1 | | | `SUPPORTED_MODEL_SONNET_3_7` | 2 | | | `SUPPORTED_MODEL_SONNET_3_7_EXTENDED` | 3 | | | `SUPPORTED_MODEL_SONNET_4` | 4 | | | `SUPPORTED_MODEL_SONNET_4_EXTENDED` | 5 | | | `SUPPORTED_MODEL_SONNET_4_5` | 8 | | | `SUPPORTED_MODEL_SONNET_4_5_EXTENDED` | 9 | | | `SUPPORTED_MODEL_SONNET_4_6` | 18 | | | `SUPPORTED_MODEL_SONNET_4_6_EXTENDED` | 19 | | | `SUPPORTED_MODEL_SONNET_5` | 32 | | | `SUPPORTED_MODEL_OPUS_4` | 6 | | | `SUPPORTED_MODEL_OPUS_4_EXTENDED` | 7 | | | `SUPPORTED_MODEL_OPUS_4_5` | 14 | | | `SUPPORTED_MODEL_OPUS_4_5_EXTENDED` | 15 | | | `SUPPORTED_MODEL_OPUS_4_6` | 16 | | | `SUPPORTED_MODEL_OPUS_4_6_EXTENDED` | 17 | | | `SUPPORTED_MODEL_OPUS_4_7` | 22 | | | `SUPPORTED_MODEL_OPUS_4_8` | 31 | | | `SUPPORTED_MODEL_HAIKU_4_5` | 21 | | | `SUPPORTED_MODEL_OPENAI_4O` | 10 | | | `SUPPORTED_MODEL_OPENAI_4O_MINI` | 11 | | | `SUPPORTED_MODEL_OPENAI_O1` | 12 | | | `SUPPORTED_MODEL_OPENAI_O1_MINI` | 13 | | | `SUPPORTED_MODEL_OPENAI_AUTO` | 23 | SUPPORTED\_MODEL\_OPENAI\_AUTO flags a request as OpenAI-bound without encoding a specific model slug. The actual model is chosen by the client (today: native Codex via \~/.codex/config.toml) and captured from the upstream Responses-API response.model field for metering and rate-card lookup. This keeps the proto stable across OpenAI model-catalog churn. Reserved numbers 24-30 are intentionally left free for future OpenAI routing sentinels if we ever need to distinguish sub-families. | # Get Prompt Source: https://ona.com/docs/api-reference/generated/agent/get-prompt Gets details about a specific prompt including name, description, `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Gets details about a specific prompt including name, description, and prompt content. Use this method to: * Retrieve prompt details for editing * Get prompt content for execution ### Examples * Get prompt details: ```yaml theme={null} promptId: "07e03a28-65a5-4d98-b532-8ea67b188048" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/GetPrompt ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/GetPrompt" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "promptId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.GetPromptRequest( prompt_id="", ) response = ona.services.agent.get_prompt(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetPromptRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(GetPromptRequestSchema, { promptId: "", }); const response = await ona.services.agent.getPrompt(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetPromptRequest{ PromptId: "", }) response, err := ona.Services.Agent.GetPrompt(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "promptId": "" } ``` ## Request `gitpod.v1.GetPromptRequest` | Field | Type | Required | Description | | ---------- | ------ | -------- | -------------------------------- | | `promptId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.GetPromptResponse` | Field | Type | Required | Description | | -------- | -------------------------------- | -------- | ----------- | | `prompt` | [Prompt](#type-gitpod-v1-prompt) | No | | ## Related types `gitpod.v1.Prompt` | Field | Type | Required | Description | | ---------- | ------------------------------------------------- | -------- | ----------- | | `id` | string | No | | | `metadata` | [PromptMetadata](#type-gitpod-v1-prompt-metadata) | No | | | `spec` | [PromptSpec](#type-gitpod-v1-prompt-spec) | No | | `gitpod.v1.PromptMetadata` | Field | Type | Required | Description | | ---------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------------- | | `organizationId` | string | No | organization\_id is the ID of the organization that contains the prompt Constraints: `string.uuid=true`. | | `name` | string | No | name is the human readable name of the prompt | | `description` | string | No | description is a description of what the prompt does | | `creator` | Subject | No | creator is the identity of the prompt creator | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | `gitpod.v1.PromptSpec` | Field | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | | `prompt` | string | No | prompt is the content of the prompt Constraints: `string.max_len=20000`. | | `isTemplate` | boolean | No | is\_template indicates if this prompt is a template | | `isCommand` | boolean | No | is\_command indicates if this prompt is a command | | `command` | string | No | command is the unique command string within the organization Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | is\_skill indicates if this prompt is a skill (workflow instructions for agents) | # List Agent Executions Source: https://ona.com/docs/api-reference/generated/agent/list-agent-executions Lists all agent runs matching the specified filter. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Lists all agent runs matching the specified filter. Use this method to track multiple agent runs and their associated resources. Results are ordered by their creation time with the newest first. ### Examples * List agent runs by agent ID: ```yaml theme={null} filter: agentIds: ["b8a64cfa-43e2-4b9d-9fb3-07edc63f5971"] pagination: pageSize: 10 ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/ListAgentExecutions ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/ListAgentExecutions" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "pagination": { "pageSize": 1 } }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 import gitpod.v1.pagination_pb2 as pagination_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.ListAgentExecutionsRequest( pagination=pagination_pb2.PaginationRequest( page_size=1, ), ) response = ona.services.agent.list_agent_executions(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { ListAgentExecutionsRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(ListAgentExecutionsRequestSchema, { pagination: { pageSize: 1, }, }); const response = await ona.services.agent.listAgentExecutions(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.ListAgentExecutionsRequest{ Pagination: &gitpodpb.PaginationRequest{ PageSize: 1, }, }) response, err := ona.Services.Agent.ListAgentExecutions(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "pagination": { "pageSize": 1 } } ``` ## Request `gitpod.v1.ListAgentExecutionsRequest` | Field | Type | Required | Description | | ------------ | -------------------------------------------------------------- | -------- | ----------- | | `pagination` | [PaginationRequest](#type-gitpod-v1-pagination-request) | No | | | `filter` | [Filter](#type-gitpod-v1-list-agent-executions-request-filter) | No | | ## Response `gitpod.v1.ListAgentExecutionsResponse` | Field | Type | Required | Description | | ----------------- | ---------------------------------------------------------- | -------- | ----------- | | `pagination` | [PaginationResponse](#type-gitpod-v1-pagination-response) | No | | | `agentExecutions` | array of [AgentExecution](#type-gitpod-v1-agent-execution) | No | | ## Related types `gitpod.v1.AgentExecution` | Field | Type | Required | Description | | ---------- | ---------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `id` | string | No | ID is a unique identifier of this agent run. No other agent run with the same name must be managed by this agent manager | | `metadata` | [Metadata](#type-gitpod-v1-agent-execution-metadata) | No | Metadata is data associated with this agent that's required for other parts of Gitpod to function | | `spec` | [Spec](#type-gitpod-v1-agent-execution-spec) | No | Spec is the configuration of the agent that's required for the runner to start the agent | | `status` | [Status](#type-gitpod-v1-agent-execution-status) | No | Status is the current status of the agent | `gitpod.v1.AgentExecution.Metadata` | Field | Type | Required | Description | | ------------------ | ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | No | | | `description` | string | No | | | `creator` | Subject | No | | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | | `role` | [AgentExecutionRole](#enum-gitpod-v1-agent-execution-role) | No | role is the role of the agent execution | | `workflowActionId` | string | No | workflow\_action\_id is set when this agent execution was created as part of a workflow. Used to correlate agent executions with their parent workflow execution action. Constraints: `ignore=1, string.uuid=true`. | | `annotations` | map of string to string | No | annotations are key-value pairs for tracking external context. | | `sessionId` | string | No | session\_id is the ID of the session this agent execution belongs to. | `gitpod.v1.AgentExecution.Spec` | Field | Type | Required | Description | | --------------- | ---------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `specVersion` | 64-bit integer string | No | version of the spec. The value of this field has no semantic meaning (e.g. don't interpret it as as a timestamp), but it can be used to impose a partial order. If a.spec\_version \< b.spec\_version then a was the spec before b. | | `session` | string | No | | | `desiredPhase` | [Phase](#enum-gitpod-v1-agent-execution-phase) | No | desired\_phase is the desired phase of the agent run | | `agentId` | string | No | Constraints: `string.uuid=true`. | | `codeContext` | AgentCodeContext | No | | | `limits` | Limits | No | | | `codexSettings` | CodexSettings | No | codex\_settings contains persisted desired/manual settings for the Codex app agent. | `gitpod.v1.AgentExecution.Status` | Field | Type | Required | Description | | -------------------------- | ----------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `statusVersion` | 64-bit integer string | No | version of the status. The value of this field has no semantic meaning (e.g. don't interpret it as as a timestamp), but it can be used to impose a partial order. If a.status\_version \< b.status\_version then a was the status before b. | | `session` | string | No | | | `phase` | [Phase](#enum-gitpod-v1-agent-execution-phase) | No | | | `failureMessage` | string | No | failure\_message contains the reason the agent run failed to operate. | | `warningMessage` | string | No | warning\_message contains warnings, e.g. when the LLM is overloaded. | | `failureReason` | [AgentExecutionFailureReason](#enum-gitpod-v1-agent-execution-failure-reason) | No | failure\_reason contains a structured reason code for the failure. | | `conversationUrl` | string | No | conversation\_url is the URL to the conversation (all messages exchanged between the agent and the user) of the agent run. | | `transcriptUrl` | string | No | transcript\_url is the URL to the LLM transcript (all messages exchanged between the agent and the LLM) of the agent run. | | `supportBundleUrl` | string | No | support\_bundle\_url is the URL to download a diagnostic bundle for this agent execution. | | `conversationUrls` | ConversationURLs | No | conversation\_urls contains the v2 conversation streaming endpoints. When present, clients should use these URLs instead of conversation\_url. | | `iterations` | 64-bit integer string | No | | | `inputTokensUsed` | 64-bit integer string | No | | | `outputTokensUsed` | 64-bit integer string | No | | | `contextWindowLength` | 64-bit integer string | No | | | `cachedCreationTokensUsed` | 64-bit integer string | No | | | `cachedInputTokensUsed` | 64-bit integer string | No | | | `contextWindowLimit` | 64-bit integer string | No | context\_window\_limit is the selected model's maximum context window size in tokens. | | `judgement` | string | No | judgement is the judgement of the agent run produced by the judgement prompt. | | `currentOperation` | CurrentOperation | No | current\_operation is the current operation of the agent execution. | | `usedEnvironments` | array of EnvironmentUsage | No | used\_environments is the list of environments that were used by the agent execution. | | `currentActivity` | string | No | current\_activity is the current activity description of the agent execution. | | `outputs` | map of string to OutputValue | No | outputs is a map of key-value pairs that can be set by the agent during execution. Similar to task execution outputs, but with typed values for structured data. Constraints: `map.keys.string.max_len=128, map.keys.string.min_len=1`. | | `supportedModel` | [SupportedModel](#enum-gitpod-v1-supported-model) | No | supported\_model is the LLM model being used by the agent execution. | | `llmCapabilities` | LLMCapabilities | No | llm\_capabilities describes provider capabilities for the selected LLM integration. | | `mode` | [AgentMode](#enum-gitpod-v1-agent-mode) | No | mode is the current operational mode of the agent execution. This is set by the agent when entering different modes (e.g., Ralph mode via /ona:ralph command). | | `mcpIntegrationStatuses` | array of MCPIntegrationStatus | No | mcp\_integration\_statuses contains the status of all MCP integrations used by this agent execution | | `waitingInfo` | WaitingInfo | No | waiting\_info is set when phase is PHASE\_WAITING\_FOR\_INPUT and the agent has registered interests (timers, sub-agent completions, user messages). | | `terminalId` | string | No | terminal\_id is the ID of the terminal running the agent, if the agent runs as a terminal service (runsOn: terminal). | | `goal` | Goal | No | goal projects the current agent goal, if any. | | `codexSettings` | CodexSettings | No | codex\_settings contains runtime effective settings reported by the Codex app agent. | | `subagents` | array of Subagent | No | | `gitpod.v1.ListAgentExecutionsRequest.Filter` | Field | Type | Required | Description | | ------------------- | ------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `agentIds` | array of string | No | Constraints: `repeated.max_items=25, repeated.min_items=0`. | | `projectIds` | array of string | No | Constraints: `repeated.items.string.uuid=true, repeated.max_items=25, repeated.min_items=0`. | | `environmentIds` | array of string | No | Constraints: `repeated.max_items=25, repeated.min_items=0`. | | `creatorIds` | array of string | No | Constraints: `repeated.max_items=25, repeated.min_items=0`. | | `statusPhases` | array of [Phase](#enum-gitpod-v1-agent-execution-phase) | No | Constraints: `repeated.max_items=25, repeated.min_items=0`. | | `roles` | array of [AgentExecutionRole](#enum-gitpod-v1-agent-execution-role) | No | Constraints: `repeated.items.enum.defined_only=true, repeated.max_items=25, repeated.min_items=0`. | | `annotations` | map of string to string | No | annotations filters by key-value pairs. Only executions containing all specified annotations (with matching values) are returned. | | `sessionIds` | array of string | No | session\_ids filters the response to only executions belonging to the specified sessions Constraints: `repeated.items.string.uuid=true, repeated.max_items=25, repeated.min_items=0`. | | `agentExecutionIds` | array of string | No | agent\_execution\_ids filters the response to only the specified executions. Useful for checking existence of a known set of execution IDs. Constraints: `repeated.items.string.uuid=true, repeated.max_items=100, repeated.min_items=0`. | `gitpod.v1.PaginationRequest` | Field | Type | Required | Description | | ---------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `pageSize` | integer | No | Page size is the maximum number of results to retrieve per page. Defaults to 25. Maximum 100. Constraints: `int32.gte=0, int32.lte=100`. | | `token` | string | No | Token for the next set of results that was returned as next\_token of a PaginationResponse | `gitpod.v1.PaginationResponse` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `nextToken` | string | No | Token passed for retrieving the next set of results. Empty if there are no more results | | Value | Number | Description | | ------------------------- | -----: | ----------------------------------- | | `PHASE_UNSPECIFIED` | 0 | The phase is not set. | | `PHASE_PENDING` | 10 | The agent run is pending. | | `PHASE_RUNNING` | 20 | The agent run is active. | | `PHASE_WAITING_FOR_INPUT` | 30 | The agent run is waiting for input. | | `PHASE_STOPPED` | 40 | The agent run is inactive. | AgentExecutionFailureReason represents the reason why an agent execution failed | Value | Number | Description | | ------------------------------------------------ | -----: | --------------------------------------------------------------------------------------------------------------------------------------------- | | `AGENT_EXECUTION_FAILURE_REASON_UNSPECIFIED` | 0 | | | `AGENT_EXECUTION_FAILURE_REASON_ENVIRONMENT` | 1 | The agent execution failed due to environment issues | | `AGENT_EXECUTION_FAILURE_REASON_SERVICE` | 2 | The agent execution failed due to service issues | | `AGENT_EXECUTION_FAILURE_REASON_LLM_INTEGRATION` | 3 | The agent execution failed due to LLM integration issues | | `AGENT_EXECUTION_FAILURE_REASON_INTERNAL` | 4 | **Deprecated.** Deprecated: The agent execution failed due to internal errors Use AGENT\_EXECUTION\_FAILURE\_REASON\_AGENT\_EXECUTION instead | | `AGENT_EXECUTION_FAILURE_REASON_AGENT_EXECUTION` | 5 | The agent execution failed due to agent execution errors | AgentExecutionRole represents the role of an agent execution | Value | Number | Description | | ---------------------------------- | -----: | -------------------------------------------------------------- | | `AGENT_EXECUTION_ROLE_UNSPECIFIED` | 0 | | | `AGENT_EXECUTION_ROLE_DEFAULT` | 1 | Default role for agent executions | | `AGENT_EXECUTION_ROLE_WORKFLOW` | 2 | Workflow role for agent executions that are part of a workflow | AgentMode defines the operational mode of an agent | Value | Number | Description | | ------------------------ | -----: | ----------------------------------------------------------------- | | `AGENT_MODE_UNSPECIFIED` | 0 | Default execution mode - standard agent behavior | | `AGENT_MODE_EXECUTION` | 1 | Execution mode - agent performs tasks and makes changes | | `AGENT_MODE_PLANNING` | 2 | Planning mode - agent focuses on analysis and planning | | `AGENT_MODE_RALPH` | 3 | Ralph mode - autonomous planning and implementation mode | | `AGENT_MODE_SPEC` | 4 | Spec mode - planning phase followed by interactive implementation | | `AGENT_MODE_GOAL` | 5 | Goal mode - agent treats the user input as a goal objective | SupportedModel enumerates the LLM models available for agent executions | Value | Number | Description | | ------------------------------------- | -----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `SUPPORTED_MODEL_UNSPECIFIED` | 0 | | | `SUPPORTED_MODEL_SONNET_3_5` | 1 | | | `SUPPORTED_MODEL_SONNET_3_7` | 2 | | | `SUPPORTED_MODEL_SONNET_3_7_EXTENDED` | 3 | | | `SUPPORTED_MODEL_SONNET_4` | 4 | | | `SUPPORTED_MODEL_SONNET_4_EXTENDED` | 5 | | | `SUPPORTED_MODEL_SONNET_4_5` | 8 | | | `SUPPORTED_MODEL_SONNET_4_5_EXTENDED` | 9 | | | `SUPPORTED_MODEL_SONNET_4_6` | 18 | | | `SUPPORTED_MODEL_SONNET_4_6_EXTENDED` | 19 | | | `SUPPORTED_MODEL_SONNET_5` | 32 | | | `SUPPORTED_MODEL_OPUS_4` | 6 | | | `SUPPORTED_MODEL_OPUS_4_EXTENDED` | 7 | | | `SUPPORTED_MODEL_OPUS_4_5` | 14 | | | `SUPPORTED_MODEL_OPUS_4_5_EXTENDED` | 15 | | | `SUPPORTED_MODEL_OPUS_4_6` | 16 | | | `SUPPORTED_MODEL_OPUS_4_6_EXTENDED` | 17 | | | `SUPPORTED_MODEL_OPUS_4_7` | 22 | | | `SUPPORTED_MODEL_OPUS_4_8` | 31 | | | `SUPPORTED_MODEL_HAIKU_4_5` | 21 | | | `SUPPORTED_MODEL_OPENAI_4O` | 10 | | | `SUPPORTED_MODEL_OPENAI_4O_MINI` | 11 | | | `SUPPORTED_MODEL_OPENAI_O1` | 12 | | | `SUPPORTED_MODEL_OPENAI_O1_MINI` | 13 | | | `SUPPORTED_MODEL_OPENAI_AUTO` | 23 | SUPPORTED\_MODEL\_OPENAI\_AUTO flags a request as OpenAI-bound without encoding a specific model slug. The actual model is chosen by the client (today: native Codex via \~/.codex/config.toml) and captured from the upstream Responses-API response.model field for metering and rate-card lookup. This keeps the proto stable across OpenAI model-catalog churn. Reserved numbers 24-30 are intentionally left free for future OpenAI routing sentinels if we ever need to distinguish sub-families. | # List Prompts Source: https://ona.com/docs/api-reference/generated/agent/list-prompts Lists all prompts matching the specified criteria. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Lists all prompts matching the specified criteria. Use this method to find and browse prompts across your organization. Results are ordered by their creation time with the newest first. ### Examples * List all prompts: Retrieves all prompts with pagination. ```yaml theme={null} pagination: pageSize: 10 ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/ListPrompts ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/ListPrompts" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "pagination": { "pageSize": 1 } }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 import gitpod.v1.pagination_pb2 as pagination_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.ListPromptsRequest( pagination=pagination_pb2.PaginationRequest( page_size=1, ), ) response = ona.services.agent.list_prompts(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { ListPromptsRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(ListPromptsRequestSchema, { pagination: { pageSize: 1, }, }); const response = await ona.services.agent.listPrompts(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.ListPromptsRequest{ Pagination: &gitpodpb.PaginationRequest{ PageSize: 1, }, }) response, err := ona.Services.Agent.ListPrompts(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "pagination": { "pageSize": 1 } } ``` ## Request `gitpod.v1.ListPromptsRequest` | Field | Type | Required | Description | | ------------ | ------------------------------------------------------- | -------- | ----------- | | `pagination` | [PaginationRequest](#type-gitpod-v1-pagination-request) | No | | | `filter` | [Filter](#type-gitpod-v1-list-prompts-request-filter) | No | | ## Response `gitpod.v1.ListPromptsResponse` | Field | Type | Required | Description | | ------------ | --------------------------------------------------------- | -------- | ----------- | | `pagination` | [PaginationResponse](#type-gitpod-v1-pagination-response) | No | | | `prompts` | array of [Prompt](#type-gitpod-v1-prompt) | No | | ## Related types `gitpod.v1.ListPromptsRequest.Filter` | Field | Type | Required | Description | | ---------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `isTemplate` | boolean | No | | | `isCommand` | boolean | No | | | `command` | string | No | | | `commandPrefix` | string | No | Constraints: `string.max_len=50`. | | `isSkill` | boolean | No | | | `excludePromptContent` | boolean | No | exclude\_prompt\_content omits the large spec.prompt text from the response. Other spec fields (is\_template, is\_command, command, is\_skill) are still returned. Use GetPrompt to retrieve the full prompt content when needed. | | `search` | string | No | search performs case-insensitive search across prompt name, description, and command. Constraints: `string.max_len=256`. | `gitpod.v1.PaginationRequest` | Field | Type | Required | Description | | ---------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `pageSize` | integer | No | Page size is the maximum number of results to retrieve per page. Defaults to 25. Maximum 100. Constraints: `int32.gte=0, int32.lte=100`. | | `token` | string | No | Token for the next set of results that was returned as next\_token of a PaginationResponse | `gitpod.v1.PaginationResponse` | Field | Type | Required | Description | | ----------- | ------ | -------- | --------------------------------------------------------------------------------------- | | `nextToken` | string | No | Token passed for retrieving the next set of results. Empty if there are no more results | `gitpod.v1.Prompt` | Field | Type | Required | Description | | ---------- | ------------------------------------------------- | -------- | ----------- | | `id` | string | No | | | `metadata` | [PromptMetadata](#type-gitpod-v1-prompt-metadata) | No | | | `spec` | [PromptSpec](#type-gitpod-v1-prompt-spec) | No | | `gitpod.v1.PromptMetadata` | Field | Type | Required | Description | | ---------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------------- | | `organizationId` | string | No | organization\_id is the ID of the organization that contains the prompt Constraints: `string.uuid=true`. | | `name` | string | No | name is the human readable name of the prompt | | `description` | string | No | description is a description of what the prompt does | | `creator` | Subject | No | creator is the identity of the prompt creator | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | `gitpod.v1.PromptSpec` | Field | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | | `prompt` | string | No | prompt is the content of the prompt Constraints: `string.max_len=20000`. | | `isTemplate` | boolean | No | is\_template indicates if this prompt is a template | | `isCommand` | boolean | No | is\_command indicates if this prompt is a command | | `command` | string | No | command is the unique command string within the organization Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | is\_skill indicates if this prompt is a skill (workflow instructions for agents) | # Agents Source: https://ona.com/docs/api-reference/generated/agent/overview Reference for the Agents API methods. ## Methods Creates a token for conversation access with a specific agent run. Creates a new prompt. Deletes an agent run. Deletes a prompt. Gets details about a specific agent run, including its metadata, specification, Gets details about a specific prompt including name, description, Lists all agent runs matching the specified filter. Lists all prompts matching the specified criteria. Sends user input to an active agent run. Starts (or triggers) an agent run using a provided agent. Stops an active agent execution. Updates an existing prompt. # Send To Agent Execution Source: https://ona.com/docs/api-reference/generated/agent/send-to-agent-execution Sends user input to an active agent run. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Sends user input to an active agent run. This method is used to provide interactive or conversation-based input to an agent. The agent can respond with output blocks containing text, file changes, or tool usage requests. ### Examples * Send a text message to an agent: ```yaml theme={null} agentExecutionId: "6fa1a3c7-fbb7-49d1-ba56-1890dc7c4c35" userInput: text: content: "Generate a report based on the latest logs." ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/SendToAgentExecution ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/SendToAgentExecution" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentExecutionId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.SendToAgentExecutionRequest( agent_execution_id="", ) response = ona.services.agent.send_to_agent_execution(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { SendToAgentExecutionRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(SendToAgentExecutionRequestSchema, { agentExecutionId: "", }); const response = await ona.services.agent.sendToAgentExecution(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.SendToAgentExecutionRequest{ AgentExecutionId: "", }) response, err := ona.Services.Agent.SendToAgentExecution(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentExecutionId": "" } ``` ## Request `gitpod.v1.SendToAgentExecutionRequest` | Field | Type | Required | Description | | ------------------ | -------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | | `userInput` | [UserInputBlock](#type-gitpod-v1-user-input-block) | No | | | `agentMessage` | [AgentMessage](#type-gitpod-v1-agent-message) | No | | | `wakeEvent` | [WakeEvent](#type-gitpod-v1-wake-event) | No | | | `controlInput` | [AgentControlInput](#type-gitpod-v1-agent-control-input) | No | | | `codexSettings` | [CodexSettings](#type-gitpod-v1-codex-settings) | No | codex\_settings contains per-turn desired settings for Codex app user\_input sends. | | `turnOptions` | [TurnOptions](#type-gitpod-v1-turn-options) | No | turn\_options contains options that apply to this submitted turn. | ## Response `gitpod.v1.SendToAgentExecutionResponse` This message has no fields. ## Related types `gitpod.v1.AgentControlInput` | Field | Type | Required | Description | | --------------------- | -------------------------------------------------------------------------------- | -------- | ----------- | | `compact` | [Compact](#type-gitpod-v1-agent-control-input-compact) | No | | | `goal` | [Goal](#type-gitpod-v1-agent-control-input-goal) | No | | | `deleteQueuedMessage` | [DeleteQueuedMessage](#type-gitpod-v1-agent-control-input-delete-queued-message) | No | | | `steerQueuedMessage` | [SteerQueuedMessage](#type-gitpod-v1-agent-control-input-steer-queued-message) | No | | | `moveQueuedMessage` | [MoveQueuedMessage](#type-gitpod-v1-agent-control-input-move-queued-message) | No | | `gitpod.v1.AgentControlInput.Compact` This message has no fields. `gitpod.v1.AgentControlInput.DeleteQueuedMessage` | Field | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------- | | `userInputId` | string | No | Constraints: `string.min_len=1`. | `gitpod.v1.AgentControlInput.Goal` | Field | Type | Required | Description | | ---------- | -------- | -------- | ----------- | | `pause` | Pause | No | | | `resume` | Resume | No | | | `complete` | Complete | No | | | `clear` | Clear | No | | | `set` | Set | No | | `gitpod.v1.AgentControlInput.MoveQueuedMessage` | Field | Type | Required | Description | | ------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------- | | `userInputId` | string | No | Constraints: `string.min_len=1`. | | `beforeUserInputId` | string | No | before\_user\_input\_id is the queued user input to insert before. Empty means move to the end. | `gitpod.v1.AgentControlInput.SteerQueuedMessage` | Field | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------- | | `userInputId` | string | No | Constraints: `string.min_len=1`. | AgentMessage is a message sent between agents (e.g. from a parent agent to a child agent execution, or vice versa). `gitpod.v1.AgentMessage` | Field | Type | Required | Description | | ------------------- | ------------------------------------------ | -------- | ----------------------------------------------------- | | `type` | [Type](#enum-gitpod-v1-agent-message-type) | No | | | `payload` | string | No | Free-form payload of the message. | | `role` | [Role](#enum-gitpod-v1-agent-message-role) | No | The role of the sender in the agent hierarchy. | | `senderExecutionId` | string | No | The execution ID of the agent that sent this message. | CodexSettings contains settings consumed only by the Codex app agent. `gitpod.v1.CodexSettings` | Field | Type | Required | Description | | ----------------- | -------------------------------------------------------------- | -------- | -------------------------------------- | | `model` | [CodexOpenAIModel](#enum-gitpod-v1-codex-open-ai-model) | No | Constraints: `enum.defined_only=true`. | | `reasoningEffort` | [CodexReasoningEffort](#enum-gitpod-v1-codex-reasoning-effort) | No | Constraints: `enum.defined_only=true`. | | `serviceTier` | [CodexServiceTier](#enum-gitpod-v1-codex-service-tier) | No | Constraints: `enum.defined_only=true`. | `gitpod.v1.TurnOptions` | Field | Type | Required | Description | | ------- | ------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `modes` | array of [AgentMode](#enum-gitpod-v1-agent-mode) | No | modes contains requested modes for this turn. Agents decide whether a mode remains active after the submitted turn and report durable state via AgentExecution.Status. Constraints: `repeated.max_items=4`. | `gitpod.v1.UserInputBlock` | Field | Type | Required | Description | | ----------- | ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------ | | `id` | string | No | | | `text` | [TextInput](#type-gitpod-v1-user-input-block-text-input) | No | **Deprecated.** | | `image` | [ImageInput](#type-gitpod-v1-user-input-block-image-input) | No | **Deprecated.** | | `inputs` | array of [Input](#type-gitpod-v1-user-input-block-input) | No | Constraints: `repeated.max_items=10`. | | `createdAt` | RFC 3339 timestamp | No | Timestamp when this block was created. Used for debugging and support bundles. | | `metadata` | [UserInputMetadata](#type-gitpod-v1-user-input-metadata) | No | Integration-specific metadata for this input. | ImageInput allows sending images to the agent. Client must provide the MIME type; backend validates against magic bytes. `gitpod.v1.UserInputBlock.ImageInput` | Field | Type | Required | Description | | ---------- | ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `data` | base64 string | No | Raw image data (max 4MB). Supported formats: PNG, JPEG. Constraints: `bytes.max_len=4194304, bytes.min_len=1`. | | `mimeType` | string | No | Constraints: `string.in=image/jpeg, string.in=image/png`. | | `dataRef` | string | No | Content-addressed reference to offloaded image data. Set by the runner when storing in the conversation store; data is cleared. Clients never send this field. | `gitpod.v1.UserInputBlock.Input` | Field | Type | Required | Description | | ------- | ---------- | -------------- | ----------- | | `text` | TextInput | One of `input` | | | `image` | ImageInput | One of `input` | | `gitpod.v1.UserInputBlock.TextInput` | Field | Type | Required | Description | | --------- | ------ | -------- | -------------------------------- | | `content` | string | No | Constraints: `string.min_len=1`. | UserInputMetadata carries integration-specific context for a user input. Internal only - not exposed in public SDKs. External API consumers should not set these fields; they are populated by integration handlers. `gitpod.v1.UserInputMetadata` | Field | Type | Required | Description | | -------- | ------------------------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `source` | string | No | Origin of this input - set by integration handlers to their host (e.g. "github.com", "slack.com"). Empty for non-integration callers. This field drives emission gating: when set, agent responses are only emitted to the matching integration. Treated as trusted input from integration handlers; not validated against registered hosts. | | `modes` | array of [AgentMode](#enum-gitpod-v1-agent-mode) | No | modes records the structured modes requested for this user input. When present, clients should prefer these modes over legacy prompt prefixes for rendering user-message labels. Constraints: `repeated.max_items=4`. | WakeEvent is sent by the backend to wake an agent when a registered interest fires. Delivered via SendToAgentExecution as a new oneof variant. `gitpod.v1.WakeEvent` | Field | Type | Required | Description | | --------------------- | --------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------- | | `interestId` | string | No | The interest ID that fired (from WaitingInfo.Interest.id). | | `timer` | [TimerFired](#type-gitpod-v1-wake-event-timer-fired) | No | | | `loopRetrigger` | [LoopRetrigger](#type-gitpod-v1-wake-event-loop-retrigger) | No | | | `environment` | [EnvironmentPhaseReached](#type-gitpod-v1-wake-event-environment-phase-reached) | No | | | `devcontainerRebuild` | [DevcontainerPhaseReached](#type-gitpod-v1-wake-event-devcontainer-phase-reached) | No | | `gitpod.v1.WakeEvent.DevcontainerPhaseReached` | Field | Type | Required | Description | | ---------------- | --------------- | -------- | ----------------------------------------------------- | | `environmentId` | string | No | | | `phase` | string | No | The devcontainer phase reached by the target session. | | `sessionId` | string | No | | | `failureMessage` | array of string | No | | `gitpod.v1.WakeEvent.EnvironmentPhaseReached` | Field | Type | Required | Description | | ---------------- | --------------- | -------- | ------------------------------------------------------------------------- | | `environmentId` | string | No | | | `phase` | string | No | The phase the environment reached (e.g. "running", "stopped", "deleted"). | | `failureMessage` | array of string | No | | `gitpod.v1.WakeEvent.LoopRetrigger` | Field | Type | Required | Description | | ----------------- | ----------------------- | -------- | ----------- | | `unmetConditions` | array of UnmetCondition | No | | | `outputs` | map of string to string | No | | `gitpod.v1.WakeEvent.TimerFired` | Field | Type | Required | Description | | --------- | ------------------ | -------- | --------------------------------------------------- | | `firedAt` | RFC 3339 timestamp | No | The actual time the timer was evaluated as expired. | Role identifies the sender's relationship in the parent/child hierarchy. | Value | Number | Description | | ------------------ | -----: | ---------------------------------- | | `ROLE_UNSPECIFIED` | 0 | | | `ROLE_PARENT` | 1 | The sender is the parent agent. | | `ROLE_CHILD` | 2 | The sender is a child (sub-agent). | | Value | Number | Description | | ------------------ | -----: | ------------------------------------------------------ | | `TYPE_UNSPECIFIED` | 0 | | | `TYPE_UPDATE` | 1 | Regular inter-agent update message. | | `TYPE_COMPLETE` | 2 | Signals that the sending agent has completed its task. | AgentMode defines the operational mode of an agent | Value | Number | Description | | ------------------------ | -----: | ----------------------------------------------------------------- | | `AGENT_MODE_UNSPECIFIED` | 0 | Default execution mode - standard agent behavior | | `AGENT_MODE_EXECUTION` | 1 | Execution mode - agent performs tasks and makes changes | | `AGENT_MODE_PLANNING` | 2 | Planning mode - agent focuses on analysis and planning | | `AGENT_MODE_RALPH` | 3 | Ralph mode - autonomous planning and implementation mode | | `AGENT_MODE_SPEC` | 4 | Spec mode - planning phase followed by interactive implementation | | `AGENT_MODE_GOAL` | 5 | Goal mode - agent treats the user input as a goal objective | CodexOpenAIModel is the static allowlist of concrete OpenAI models that the Codex app runtime can select through Ona's Codex picker. | Value | Number | Description | | ----------------------------------------- | -----: | --------------- | | `CODEX_OPEN_AI_MODEL_UNSPECIFIED` | 0 | | | `CODEX_OPEN_AI_MODEL_GPT_5_5` | 1 | | | `CODEX_OPEN_AI_MODEL_GPT_5_4` | 2 | | | `CODEX_OPEN_AI_MODEL_GPT_5_4_MINI` | 3 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX` | 4 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX_SPARK` | 5 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_2` | 6 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_6_SOL` | 7 | | | `CODEX_OPEN_AI_MODEL_GPT_5_6_TERRA` | 8 | | | `CODEX_OPEN_AI_MODEL_GPT_5_6_LUNA` | 9 | | CodexReasoningEffort is the static allowlist of reasoning efforts supported by the Codex app runtime. | Value | Number | Description | | ------------------------------------ | -----: | ----------- | | `CODEX_REASONING_EFFORT_UNSPECIFIED` | 0 | | | `CODEX_REASONING_EFFORT_LOW` | 1 | | | `CODEX_REASONING_EFFORT_MEDIUM` | 2 | | | `CODEX_REASONING_EFFORT_HIGH` | 3 | | | `CODEX_REASONING_EFFORT_EXTRA_HIGH` | 4 | | | `CODEX_REASONING_EFFORT_MAX` | 5 | | | `CODEX_REASONING_EFFORT_ULTRA` | 6 | | CodexServiceTier is the static allowlist of service tiers supported by the Codex app runtime. | Value | Number | Description | | -------------------------------- | -----: | ----------- | | `CODEX_SERVICE_TIER_UNSPECIFIED` | 0 | | | `CODEX_SERVICE_TIER_FAST` | 1 | | # Start Agent Source: https://ona.com/docs/api-reference/generated/agent/start-agent Starts (or triggers) an agent run using a provided agent. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Starts (or triggers) an agent run using a provided agent. Use this method to: * Launch an agent based on a known agent ### Examples * Start an agent with a project ID: ```yaml theme={null} agentId: "b8a64cfa-43e2-4b9d-9fb3-07edc63f5971" codeContext: projectId: "2d22e4eb-31da-467f-882c-27e21550992f" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/StartAgent ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/StartAgent" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.StartAgentRequest( agent_id="", ) response = ona.services.agent.start_agent(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { StartAgentRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(StartAgentRequestSchema, { agentId: "", }); const response = await ona.services.agent.startAgent(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.StartAgentRequest{ AgentId: "", }) response, err := ona.Services.Agent.StartAgent(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentId": "" } ``` ## Request `gitpod.v1.StartAgentRequest` | Field | Type | Required | Description | | ------------------ | ------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `agentId` | string | No | agent\_id identifies the agent to start. If omitted, the backend uses the configured default agent ID, or the Ona in-environment agent when no default is configured. Constraints: `ignore=1, string.uuid=true`. | | `codeContext` | [AgentCodeContext](#type-gitpod-v1-agent-code-context) | No | | | `name` | string | No | Constraints: `string.max_len=100`. | | `workflowActionId` | string | No | workflow\_action\_id is an optional reference to the workflow execution action that created this agent execution. Used for tracking and event correlation. Constraints: `string.uuid=true`. | | `mode` | [AgentMode](#enum-gitpod-v1-agent-mode) | No | mode specifies the operational mode for this agent execution If not specified, defaults to AGENT\_MODE\_EXECUTION | | `runnerId` | string | No | runner\_id specifies a runner for this agent execution. When set, the agent execution is routed to this runner instead of the runner associated with the environment. Constraints: `ignore=1, string.uuid=true`. | | `annotations` | map of string to string | No | annotations are key-value pairs for tracking external context (e.g., integration session IDs, GitHub issue references). Keys should follow domain/name convention (e.g., "agent-client-session/id"). | | `sessionId` | string | No | session\_id is the ID of the session this agent execution belongs to. If empty, a new session is created implicitly. Constraints: `ignore=1, string.uuid=true`. | | `codexSettings` | [CodexSettings](#type-gitpod-v1-codex-settings) | No | codex\_settings contains desired manual settings for the Codex app agent. | | `turnOptions` | [TurnOptions](#type-gitpod-v1-turn-options) | No | turn\_options contains options for the initial turn. It is not persisted as durable execution state. | ## Response `gitpod.v1.StartAgentResponse` | Field | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | ## Related types `gitpod.v1.AgentCodeContext` | Field | Type | Required | Description | | --------------- | ------------------------------------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `projectId` | string | No | Constraints: `string.uuid=true`. | | `environmentId` | string | No | Constraints: `string.uuid=true`. | | `contextUrl` | [ContextURL](#type-gitpod-v1-agent-code-context-context-url) | No | | | `pullRequest` | [PullRequest](#type-gitpod-v1-pull-request) | No | Pull request context - optional metadata about the PR being worked on This is populated when the agent execution is triggered by a PR workflow or when explicitly provided through the browser extension | `gitpod.v1.AgentCodeContext.ContextURL` | Field | Type | Required | Description | | -------------------- | ------ | -------- | -------------------------------- | | `url` | string | No | Constraints: `string.uri=true`. | | `environmentClassId` | string | No | Constraints: `string.uuid=true`. | CodexSettings contains settings consumed only by the Codex app agent. `gitpod.v1.CodexSettings` | Field | Type | Required | Description | | ----------------- | -------------------------------------------------------------- | -------- | -------------------------------------- | | `model` | [CodexOpenAIModel](#enum-gitpod-v1-codex-open-ai-model) | No | Constraints: `enum.defined_only=true`. | | `reasoningEffort` | [CodexReasoningEffort](#enum-gitpod-v1-codex-reasoning-effort) | No | Constraints: `enum.defined_only=true`. | | `serviceTier` | [CodexServiceTier](#enum-gitpod-v1-codex-service-tier) | No | Constraints: `enum.defined_only=true`. | PullRequest represents pull request metadata from source control systems. This message is used across workflow triggers, executions, and agent contexts to maintain consistent PR information throughout the system. `gitpod.v1.PullRequest` | Field | Type | Required | Description | | ------------ | ------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `id` | string | No | Unique identifier from the source system (e.g., "123" for GitHub PR #123) | | `title` | string | No | Pull request title | | `fromBranch` | string | No | Source branch name (the branch being merged from) | | `toBranch` | string | No | Target branch name (the branch being merged into) | | `url` | string | No | Pull request URL (e.g., "[https://github.com/owner/repo/pull/123](https://github.com/owner/repo/pull/123)") | | `author` | string | No | Author name as provided by the SCM system | | `repository` | Repository | No | | | `draft` | boolean | No | Whether this is a draft pull request | | `state` | [State](#enum-gitpod-v1-pull-request-state) | No | | | `headSha` | string | No | Current revision identity for the PR head commit. Used internally for workflow execution deduplication and excluded from customer SDKs. | `gitpod.v1.TurnOptions` | Field | Type | Required | Description | | ------- | ------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `modes` | array of [AgentMode](#enum-gitpod-v1-agent-mode) | No | modes contains requested modes for this turn. Agents decide whether a mode remains active after the submitted turn and report durable state via AgentExecution.Status. Constraints: `repeated.max_items=4`. | AgentMode defines the operational mode of an agent | Value | Number | Description | | ------------------------ | -----: | ----------------------------------------------------------------- | | `AGENT_MODE_UNSPECIFIED` | 0 | Default execution mode - standard agent behavior | | `AGENT_MODE_EXECUTION` | 1 | Execution mode - agent performs tasks and makes changes | | `AGENT_MODE_PLANNING` | 2 | Planning mode - agent focuses on analysis and planning | | `AGENT_MODE_RALPH` | 3 | Ralph mode - autonomous planning and implementation mode | | `AGENT_MODE_SPEC` | 4 | Spec mode - planning phase followed by interactive implementation | | `AGENT_MODE_GOAL` | 5 | Goal mode - agent treats the user input as a goal objective | CodexOpenAIModel is the static allowlist of concrete OpenAI models that the Codex app runtime can select through Ona's Codex picker. | Value | Number | Description | | ----------------------------------------- | -----: | --------------- | | `CODEX_OPEN_AI_MODEL_UNSPECIFIED` | 0 | | | `CODEX_OPEN_AI_MODEL_GPT_5_5` | 1 | | | `CODEX_OPEN_AI_MODEL_GPT_5_4` | 2 | | | `CODEX_OPEN_AI_MODEL_GPT_5_4_MINI` | 3 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX` | 4 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX_SPARK` | 5 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_2` | 6 | **Deprecated.** | | `CODEX_OPEN_AI_MODEL_GPT_5_6_SOL` | 7 | | | `CODEX_OPEN_AI_MODEL_GPT_5_6_TERRA` | 8 | | | `CODEX_OPEN_AI_MODEL_GPT_5_6_LUNA` | 9 | | CodexReasoningEffort is the static allowlist of reasoning efforts supported by the Codex app runtime. | Value | Number | Description | | ------------------------------------ | -----: | ----------- | | `CODEX_REASONING_EFFORT_UNSPECIFIED` | 0 | | | `CODEX_REASONING_EFFORT_LOW` | 1 | | | `CODEX_REASONING_EFFORT_MEDIUM` | 2 | | | `CODEX_REASONING_EFFORT_HIGH` | 3 | | | `CODEX_REASONING_EFFORT_EXTRA_HIGH` | 4 | | | `CODEX_REASONING_EFFORT_MAX` | 5 | | | `CODEX_REASONING_EFFORT_ULTRA` | 6 | | CodexServiceTier is the static allowlist of service tiers supported by the Codex app runtime. | Value | Number | Description | | -------------------------------- | -----: | ----------- | | `CODEX_SERVICE_TIER_UNSPECIFIED` | 0 | | | `CODEX_SERVICE_TIER_FAST` | 1 | | Current state of the pull request | Value | Number | Description | | ------------------- | -----: | ----------- | | `STATE_UNSPECIFIED` | 0 | | | `STATE_OPEN` | 1 | | | `STATE_CLOSED` | 2 | | | `STATE_MERGED` | 3 | | # Stop Agent Execution Source: https://ona.com/docs/api-reference/generated/agent/stop-agent-execution Stops an active agent execution. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Stops an active agent execution. Use this method to: * Stop an agent that is currently running * Prevent further processing or resource usage ### Examples * Stop an agent execution by ID: ```yaml theme={null} agentExecutionId: "6fa1a3c7-fbb7-49d1-ba56-1890dc7c4c35" ``` ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/StopAgentExecution ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/StopAgentExecution" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "agentExecutionId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.StopAgentExecutionRequest( agent_execution_id="", ) response = ona.services.agent.stop_agent_execution(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { StopAgentExecutionRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(StopAgentExecutionRequestSchema, { agentExecutionId: "", }); const response = await ona.services.agent.stopAgentExecution(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.StopAgentExecutionRequest{ AgentExecutionId: "", }) response, err := ona.Services.Agent.StopAgentExecution(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "agentExecutionId": "" } ``` ## Request `gitpod.v1.StopAgentExecutionRequest` | Field | Type | Required | Description | | ------------------ | ------ | -------- | -------------------------------- | | `agentExecutionId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.StopAgentExecutionResponse` This message has no fields. # Update Prompt Source: https://ona.com/docs/api-reference/generated/agent/update-prompt Updates an existing prompt. `Unary` · [`Agents`](/docs/api-reference/generated/agent/overview) Updates an existing prompt. Use this method to: * Modify prompt content or metadata * Change prompt type (template/command) ## Endpoint ```text theme={null} POST /api/gitpod.v1.AgentService/UpdatePrompt ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.AgentService/UpdatePrompt" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "promptId": "" }' ``` ```python Python theme={null} import gitpod.v1.agent_pb2 as agent_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = agent_pb2.UpdatePromptRequest( prompt_id="", ) response = ona.services.agent.update_prompt(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { UpdatePromptRequestSchema } from "@gitpod/sdk/gitpod/v1/agent_pb"; async function main() { const ona = createClientFromEnv(); const request = create(UpdatePromptRequestSchema, { promptId: "", }); const response = await ona.services.agent.updatePrompt(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.UpdatePromptRequest{ PromptId: "", }) response, err := ona.Services.Agent.UpdatePrompt(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "promptId": "" } ``` ## Request `gitpod.v1.UpdatePromptRequest` | Field | Type | Required | Description | | ---------- | ---------------------------------------------------------- | -------- | --------------------------------------------------------------- | | `promptId` | string | No | The ID of the prompt to update Constraints: `string.uuid=true`. | | `metadata` | [Metadata](#type-gitpod-v1-update-prompt-request-metadata) | No | Metadata updates | | `spec` | [Spec](#type-gitpod-v1-update-prompt-request-spec) | No | Spec updates | ## Response `gitpod.v1.UpdatePromptResponse` | Field | Type | Required | Description | | -------- | -------------------------------- | -------- | ----------- | | `prompt` | [Prompt](#type-gitpod-v1-prompt) | No | | ## Related types `gitpod.v1.Prompt` | Field | Type | Required | Description | | ---------- | ------------------------------------------------- | -------- | ----------- | | `id` | string | No | | | `metadata` | [PromptMetadata](#type-gitpod-v1-prompt-metadata) | No | | | `spec` | [PromptSpec](#type-gitpod-v1-prompt-spec) | No | | `gitpod.v1.PromptMetadata` | Field | Type | Required | Description | | ---------------- | ------------------ | -------- | -------------------------------------------------------------------------------------------------------- | | `organizationId` | string | No | organization\_id is the ID of the organization that contains the prompt Constraints: `string.uuid=true`. | | `name` | string | No | name is the human readable name of the prompt | | `description` | string | No | description is a description of what the prompt does | | `creator` | Subject | No | creator is the identity of the prompt creator | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | `gitpod.v1.PromptSpec` | Field | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- | | `prompt` | string | No | prompt is the content of the prompt Constraints: `string.max_len=20000`. | | `isTemplate` | boolean | No | is\_template indicates if this prompt is a template | | `isCommand` | boolean | No | is\_command indicates if this prompt is a command | | `command` | string | No | command is the unique command string within the organization Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | is\_skill indicates if this prompt is a skill (workflow instructions for agents) | `gitpod.v1.UpdatePromptRequest.Metadata` | Field | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------------------------------------------------------------ | | `name` | string | No | The name of the prompt Constraints: `string.max_len=255`. | | `description` | string | No | A description of what the prompt does Constraints: `string.max_len=500, string.min_len=1`. | `gitpod.v1.UpdatePromptRequest.Spec` | Field | Type | Required | Description | | ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------ | | `prompt` | string | No | The prompt content Constraints: `string.max_len=20000`. | | `isTemplate` | boolean | No | Whether this prompt is a template | | `isCommand` | boolean | No | Whether this prompt is a command | | `command` | string | No | The command string (unique within organization) Constraints: `string.max_len=50, string.pattern=^[a-zA-Z0-9_-]*$`. | | `isSkill` | boolean | No | Whether this prompt is a skill | # Create Team Credit Allocation Source: https://ona.com/docs/api-reference/generated/billing/create-team-credit-allocation Creates a credit allocation (budget) for a team. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Creates a credit allocation (budget) for a team. Allocations are soft budgets for reporting and alerting - not enforced at usage time. Over-allocation (sum of team budgets > org grant) is allowed. ### Examples * Create a team allocation: ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" teamId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" creditBudget: "500" ``` ### Authorization Requires `billing:create` permission on the organization. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/CreateTeamCreditAllocation ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/CreateTeamCreditAllocation" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "organizationId": "", "teamId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.CreateTeamCreditAllocationRequest( organization_id="", team_id="", ) response = ona.services.billing.create_team_credit_allocation(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { CreateTeamCreditAllocationRequestSchema } from "@gitpod/sdk/gitpod/v1/billing_pb"; async function main() { const ona = createClientFromEnv(); const request = create(CreateTeamCreditAllocationRequestSchema, { organizationId: "", teamId: "", }); const response = await ona.services.billing.createTeamCreditAllocation(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.CreateTeamCreditAllocationRequest{ OrganizationId: "", TeamId: "", }) response, err := ona.Services.Billing.CreateTeamCreditAllocation(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "organizationId": "", "teamId": "" } ``` ## Request `gitpod.v1.CreateTeamCreditAllocationRequest` | Field | Type | Required | Description | | ---------------------- | --------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `teamId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `creditBudget` | 64-bit integer string | No | credit\_budget is the allocated credit budget in whole credits. Constraints: `int64.gte=0`. | | `costBudgetMicrounits` | 64-bit integer string | No | cost\_budget\_microunits is the BYOK cost budget in micro-units of the currency. Constraints: `int64.gt=0`. | | `costBudgetCurrency` | [BillingCurrency](#enum-gitpod-v1-billing-currency) | No | Constraints: `enum.defined_only=true`. | ## Response `gitpod.v1.CreateTeamCreditAllocationResponse` | Field | Type | Required | Description | | ------------ | ----------------------------------------------------------------------- | -------- | ----------- | | `allocation` | [TeamCreditAllocationInfo](#type-gitpod-v1-team-credit-allocation-info) | No | | ## Related types TeamCreditAllocationInfo represents a team's monthly budget allocation. `gitpod.v1.TeamCreditAllocationInfo` | Field | Type | Required | Description | | ---------------------- | --------------------------------------------------- | -------- | -------------------------------------------------------------------------------- | | `id` | string | No | Constraints: `string.uuid=true`. | | `teamId` | string | No | Constraints: `string.uuid=true`. | | `organizationId` | string | No | Constraints: `string.uuid=true`. | | `creditBudget` | 64-bit integer string | No | credit\_budget is the allocated credit budget in whole credits. | | `createdAt` | RFC 3339 timestamp | No | | | `updatedAt` | RFC 3339 timestamp | No | | | `costBudgetMicrounits` | 64-bit integer string | No | cost\_budget\_microunits is the BYOK cost budget in micro-units of the currency. | | `costBudgetCurrency` | [BillingCurrency](#enum-gitpod-v1-billing-currency) | No | | | Value | Number | Description | | ------------------------------ | -----: | ----------- | | `BILLING_CURRENCY_UNSPECIFIED` | 0 | | | `BILLING_CURRENCY_USD` | 1 | | | `BILLING_CURRENCY_EUR` | 2 | | | `BILLING_CURRENCY_GBP` | 3 | | # Delete Enterprise AI User Budget Policy Source: https://ona.com/docs/api-reference/generated/billing/delete-enterprise-ai-user-budget-policy Deletes the organization default or a per-user monthly budget policy. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Deletes the organization default or a per-user monthly budget policy. ### Authorization Requires `billing:delete` permission on the organization. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/DeleteEnterpriseAIUserBudgetPolicy ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/DeleteEnterpriseAIUserBudgetPolicy" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "mode": "ENTERPRISE_AI_USER_BUDGET_MODE_CREDITS", "organizationId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.DeleteEnterpriseAIUserBudgetPolicyRequest( organization_id="", mode=billing_pb2.ENTERPRISE_AI_USER_BUDGET_MODE_CREDITS, ) response = ona.services.billing.delete_enterprise_ai_user_budget_policy(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { DeleteEnterpriseAIUserBudgetPolicyRequestSchema, EnterpriseAIUserBudgetMode } from "@gitpod/sdk/gitpod/v1/billing_pb"; async function main() { const ona = createClientFromEnv(); const request = create(DeleteEnterpriseAIUserBudgetPolicyRequestSchema, { organizationId: "", mode: EnterpriseAIUserBudgetMode.CREDITS, }); const response = await ona.services.billing.deleteEnterpriseAIUserBudgetPolicy(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.DeleteEnterpriseAIUserBudgetPolicyRequest{ OrganizationId: "", Mode: gitpodpb.EnterpriseAIUserBudgetMode_ENTERPRISE_AI_USER_BUDGET_MODE_CREDITS, }) response, err := ona.Services.Billing.DeleteEnterpriseAIUserBudgetPolicy(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "mode": "ENTERPRISE_AI_USER_BUDGET_MODE_CREDITS", "organizationId": "" } ``` ## Request `gitpod.v1.DeleteEnterpriseAIUserBudgetPolicyRequest` | Field | Type | Required | Description | | ---------------- | ---------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------- | | `organizationId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `mode` | [EnterpriseAIUserBudgetMode](#enum-gitpod-v1-enterprise-ai-user-budget-mode) | Yes | Constraints: `enum.defined_only=true, enum.not_in=0, required=true`. | | `userId` | string | No | Constraints: `string.uuid=true`. | ## Response `gitpod.v1.DeleteEnterpriseAIUserBudgetPolicyResponse` This message has no fields. ## Related types | Value | Number | Description | | -------------------------------------------- | -----: | ----------- | | `ENTERPRISE_AI_USER_BUDGET_MODE_UNSPECIFIED` | 0 | | | `ENTERPRISE_AI_USER_BUDGET_MODE_CREDITS` | 1 | | | `ENTERPRISE_AI_USER_BUDGET_MODE_BYOK` | 2 | | # Delete Team Credit Allocation Source: https://ona.com/docs/api-reference/generated/billing/delete-team-credit-allocation Deletes the credit allocation for a team. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Deletes the credit allocation for a team. ### Examples * Delete a team's allocation: ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" teamId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` ### Authorization Requires `billing:delete` permission on the organization. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/DeleteTeamCreditAllocation ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/DeleteTeamCreditAllocation" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "organizationId": "", "teamId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.DeleteTeamCreditAllocationRequest( organization_id="", team_id="", ) response = ona.services.billing.delete_team_credit_allocation(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { DeleteTeamCreditAllocationRequestSchema } from "@gitpod/sdk/gitpod/v1/billing_pb"; async function main() { const ona = createClientFromEnv(); const request = create(DeleteTeamCreditAllocationRequestSchema, { organizationId: "", teamId: "", }); const response = await ona.services.billing.deleteTeamCreditAllocation(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.DeleteTeamCreditAllocationRequest{ OrganizationId: "", TeamId: "", }) response, err := ona.Services.Billing.DeleteTeamCreditAllocation(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "organizationId": "", "teamId": "" } ``` ## Request `gitpod.v1.DeleteTeamCreditAllocationRequest` | Field | Type | Required | Description | | ---------------- | ------ | -------- | ----------------------------------------------- | | `organizationId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `teamId` | string | Yes | Constraints: `required=true, string.uuid=true`. | ## Response `gitpod.v1.DeleteTeamCreditAllocationResponse` This message has no fields. # Get Credit Usage Export Source: https://ona.com/docs/api-reference/generated/billing/get-credit-usage-export Returns a signed download URL for a CSV export of credit usage. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Returns a signed download URL for a CSV export of credit usage. The URL points to an HTTP endpoint that streams gzip-compressed CSV and is valid for five minutes. The download must be made by the same principal that requested it, carrying its own bearer token. The export range may cover up to a year. For organizations without enterprise credit usage enabled (no billing contract start date), the export instead contains BYOK cost usage with a different column set, and groupBy=RESOURCE is rejected. Use this method to: * Export per-user daily credit usage for external reporting * Export a per-environment and per-conversation resource breakdown ### Examples * Export January's daily summary: ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" dateRange: startTime: "2024-01-01T00:00:00Z" endTime: "2024-01-31T00:00:00Z" groupBy: CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY ``` ### Authorization Requires `billing:read_usage` permission on the organization. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/GetCreditUsageExport ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/GetCreditUsageExport" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "dateRange": { "endTime": "2026-01-01T00:00:00Z", "startTime": "2026-01-01T00:00:00Z" }, "organizationId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 import gitpod.v1.usage_pb2 as usage_pb2 import google.protobuf.timestamp_pb2 as timestamp_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.GetCreditUsageExportRequest( organization_id="", date_range=usage_pb2.DateRange( start_time=timestamp_pb2.Timestamp(seconds=1767225600), end_time=timestamp_pb2.Timestamp(seconds=1767225600), ), ) response = ona.services.billing.get_credit_usage_export(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetCreditUsageExportRequestSchema } from "@gitpod/sdk/gitpod/v1/billing_pb"; import { timestampFromDate } from "@bufbuild/protobuf/wkt"; async function main() { const ona = createClientFromEnv(); const request = create(GetCreditUsageExportRequestSchema, { organizationId: "", dateRange: { startTime: timestampFromDate(new Date("2026-01-01T00:00:00Z")), endTime: timestampFromDate(new Date("2026-01-01T00:00:00Z")), }, }); const response = await ona.services.billing.getCreditUsageExport(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetCreditUsageExportRequest{ OrganizationId: "", DateRange: &gitpodpb.DateRange{ StartTime: ×tamppb.Timestamp{Seconds: 1767225600}, EndTime: ×tamppb.Timestamp{Seconds: 1767225600}, }, }) response, err := ona.Services.Billing.GetCreditUsageExport(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "dateRange": { "endTime": "2026-01-01T00:00:00Z", "startTime": "2026-01-01T00:00:00Z" }, "organizationId": "" } ``` ## Request `gitpod.v1.GetCreditUsageExportRequest` | Field | Type | Required | Description | | ---------------- | ------------------------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `dateRange` | [DateRange](#type-gitpod-v1-date-range) | Yes | Date range to export. Both start and end dates are inclusive; time-of-day is ignored. Unlike GetCreditUsageReport, the range may cover up to a year. Constraints: `required=true`. | | `groupBy` | [CreditUsageExportGroupBy](#enum-gitpod-v1-credit-usage-export-group-by) | No | How to group the export data. Defaults to DAILY\_SUMMARY. | ## Response `gitpod.v1.GetCreditUsageExportResponse` | Field | Type | Required | Description | | ------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------- | | `downloadUrl` | string | No | Signed download URL for the CSV export. Valid for five minutes, and only for the principal that requested it. | ## Related types DateRange specifies a time period for queries. `gitpod.v1.DateRange` | Field | Type | Required | Description | | ----------- | ------------------ | -------- | ----------------------------------------------------------------------- | | `startTime` | RFC 3339 timestamp | Yes | Start time of the date range (inclusive). Constraints: `required=true`. | | `endTime` | RFC 3339 timestamp | Yes | End time of the date range (exclusive). Constraints: `required=true`. | How to group the credit usage export data. | Value | Number | Description | | -------------------------------------------- | -----: | --------------------------------------------- | | `CREDIT_USAGE_EXPORT_GROUP_BY_UNSPECIFIED` | 0 | Defaults to DAILY\_SUMMARY. | | `CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY` | 1 | Daily summary grouped by user. | | `CREDIT_USAGE_EXPORT_GROUP_BY_RESOURCE` | 2 | Breakdown by environment and agent execution. | # Get Credit Usage Report Source: https://ona.com/docs/api-reference/generated/billing/get-credit-usage-report Returns a daily credit usage report for an enterprise organization. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Returns a daily credit usage report for an enterprise organization. Each day reports org-wide credits by usage type, plus per-user, per-team, per-environment, and per-conversation breakdowns (top consumers with the remainder aggregated into an "Others" bucket) and a per-model breakdown of intelligence usage. Use this method to: * Chart daily credit consumption over a date range * Attribute credit usage to users, teams, environments, and conversations * Restrict the report to a single user or service account ### Examples * Get the report for January: Both dates are inclusive and the range must not exceed 31 days. ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" dateRange: startTime: "2024-01-01T00:00:00Z" endTime: "2024-01-31T00:00:00Z" ``` ### Authorization Requires `billing:read_usage` permission on the organization. A user without it can read their own usage by setting filter.subject to their own user identity; this self-access path is not available to service accounts. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/GetCreditUsageReport ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/GetCreditUsageReport" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "dateRange": { "endTime": "2026-01-01T00:00:00Z", "startTime": "2026-01-01T00:00:00Z" }, "organizationId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 import gitpod.v1.usage_pb2 as usage_pb2 import google.protobuf.timestamp_pb2 as timestamp_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.GetCreditUsageReportRequest( organization_id="", date_range=usage_pb2.DateRange( start_time=timestamp_pb2.Timestamp(seconds=1767225600), end_time=timestamp_pb2.Timestamp(seconds=1767225600), ), ) response = ona.services.billing.get_credit_usage_report(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetCreditUsageReportRequestSchema } from "@gitpod/sdk/gitpod/v1/billing_pb"; import { timestampFromDate } from "@bufbuild/protobuf/wkt"; async function main() { const ona = createClientFromEnv(); const request = create(GetCreditUsageReportRequestSchema, { organizationId: "", dateRange: { startTime: timestampFromDate(new Date("2026-01-01T00:00:00Z")), endTime: timestampFromDate(new Date("2026-01-01T00:00:00Z")), }, }); const response = await ona.services.billing.getCreditUsageReport(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetCreditUsageReportRequest{ OrganizationId: "", DateRange: &gitpodpb.DateRange{ StartTime: ×tamppb.Timestamp{Seconds: 1767225600}, EndTime: ×tamppb.Timestamp{Seconds: 1767225600}, }, }) response, err := ona.Services.Billing.GetCreditUsageReport(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "dateRange": { "endTime": "2026-01-01T00:00:00Z", "startTime": "2026-01-01T00:00:00Z" }, "organizationId": "" } ``` ## Request `gitpod.v1.GetCreditUsageReportRequest` | Field | Type | Required | Description | | ---------------- | --------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | Constraints: `required=true, string.uuid=true`. | | `dateRange` | [DateRange](#type-gitpod-v1-date-range) | Yes | Date range for the report. Both start and end dates are inclusive. Time-of-day is ignored; dates are truncated to midnight in the specified timezone. The range must not exceed 31 days. Constraints: `required=true`. | | `timezone` | string | No | IANA timezone name (e.g. "America/New\_York", "Europe/Berlin") used to bucket daily usage. When empty, defaults to "UTC". | | `filter` | [CreditUsageReportFilter](#type-gitpod-v1-credit-usage-report-filter) | No | Optional filter narrowing the returned data. When unset or empty, the response preserves the default behavior (top-N users + "Others"). See CreditUsageReportFilter for per-field response-scoping semantics. | ## Response `gitpod.v1.GetCreditUsageReportResponse` | Field | Type | Required | Description | | ------------- | --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- | | `updatedAt` | RFC 3339 timestamp | No | When the report data was last computed. | | `dailyUsage` | array of [DailyCreditUsage](#type-gitpod-v1-daily-credit-usage) | No | One entry per day in the requested date range. | | `periodStart` | RFC 3339 timestamp | No | Start of the billing period for this organization. Used by the frontend to filter out months before usage tracking began. | ## Related types AgentExecutionCreditUsage contains a single agent execution's credit usage for a day, broken down by type. `gitpod.v1.AgentExecutionCreditUsage` | Field | Type | Required | Description | | ------------------ | ---------------------- | -------- | -------------------------------------------------------- | | `agentExecutionId` | string | No | Empty when representing the "Others" aggregation bucket. | | `displayName` | string | No | | | `usage` | array of CreditsByType | No | | CreditUsageReportFilter narrows the data returned by GetCreditUsageReport. Wrapping filters in a message (rather than adding bare fields) lets future filters (team, environment, resource kind) be added without further breaking changes. `gitpod.v1.CreditUsageReportFilter` | Field | Type | Required | Description | | --------- | ---------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `subject` | [Subject](#type-gitpod-v1-subject) | No | Restrict the per-user breakdown to a single subject. The subject must be PRINCIPAL\_USER or PRINCIPAL\_SERVICE\_ACCOUNT and belong to the request's organization. When unset, the report returns the default top-N users + "Others" breakdown. When this field is set: - daily\_usage\[*].user\_usage contains rows only for the requested subject; no "Others" aggregation bucket is produced. - daily\_usage\[*].org\_usage, team\_usage, environment\_usage, and conversation\_usage are omitted (empty). Callers that need those sections should issue an unfiltered call. - period\_start and updated\_at remain populated. | CreditsByType contains credits consumed for a single usage type. `gitpod.v1.CreditsByType` | Field | Type | Required | Description | | ----------- | --------------------------------------- | -------- | ----------- | | `usageType` | [UsageType](#enum-gitpod-v1-usage-type) | No | | | `credits` | number | No | | DailyCreditUsage contains credit usage for a single day. `gitpod.v1.DailyCreditUsage` | Field | Type | Required | Description | | ------------------- | ---------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `date` | RFC 3339 timestamp | No | Start of the day (midnight in the requested timezone). | | `orgUsage` | array of [CreditsByType](#type-gitpod-v1-credits-by-type) | No | Org-wide usage broken down by type. | | `userUsage` | array of [UserCreditUsage](#type-gitpod-v1-user-credit-usage) | No | Per-user usage for this day (top users + "Others"). | | `teamUsage` | array of [TeamCreditUsage](#type-gitpod-v1-team-credit-usage) | No | Per-team usage for this day (top teams + "Others"). Empty team\_id represents the "Others" aggregation bucket. | | `environmentUsage` | array of [EnvironmentCreditUsage](#type-gitpod-v1-environment-credit-usage) | No | Per-environment usage for this day (top environments + "Others"). Empty environment\_id represents the "Others" aggregation bucket. | | `conversationUsage` | array of [AgentExecutionCreditUsage](#type-gitpod-v1-agent-execution-credit-usage) | No | Per-agent-execution usage for this day (top conversations + "Others"). Empty agent\_execution\_id represents the "Others" aggregation bucket. | | `usageByModel` | array of [EnterpriseAIUsageByModel](#type-gitpod-v1-enterprise-ai-usage-by-model) | No | Org-wide intelligence usage broken down by model. | DateRange specifies a time period for queries. `gitpod.v1.DateRange` | Field | Type | Required | Description | | ----------- | ------------------ | -------- | ----------------------------------------------------------------------- | | `startTime` | RFC 3339 timestamp | Yes | Start time of the date range (inclusive). Constraints: `required=true`. | | `endTime` | RFC 3339 timestamp | Yes | End time of the date range (exclusive). Constraints: `required=true`. | `gitpod.v1.EnterpriseAIUsageByModel` | Field | Type | Required | Description | | -------------------------- | ------------------------------------- | -------- | ----------------------------------------------------------------------- | | `model` | string | No | | | `usage` | EnterpriseAIUsage | No | | | `usageByTokenType` | array of EnterpriseAIUsageByTokenType | No | | | `unpricedUsage` | EnterpriseAIUsage | No | Usage excluded from spend because no matching BYOK rate was configured. | | `unpricedUsageByTokenType` | array of EnterpriseAIUsageByTokenType | No | | EnvironmentCreditUsage contains a single environment's credit usage for a day, broken down by type. `gitpod.v1.EnvironmentCreditUsage` | Field | Type | Required | Description | | --------------- | ---------------------- | -------- | -------------------------------------------------------- | | `environmentId` | string | No | Empty when representing the "Others" aggregation bucket. | | `displayName` | string | No | | | `usage` | array of CreditsByType | No | | `gitpod.v1.Subject` | Field | Type | Required | Description | | ----------- | -------------------------------------- | -------- | -------------------------------------------------------------------------------- | | `id` | string | No | id is the UUID of the subject Constraints: `ignore=1, string.uuid=true`. | | `principal` | [Principal](#enum-gitpod-v1-principal) | No | Principal is the principal of the subject Constraints: `enum.defined_only=true`. | TeamCreditUsage contains a single team's credit usage for a day, broken down by type. `gitpod.v1.TeamCreditUsage` | Field | Type | Required | Description | | ------------- | ---------------------- | -------- | -------------------------------------------------------- | | `teamId` | string | No | Empty when representing the "Others" aggregation bucket. | | `displayName` | string | No | | | `usage` | array of CreditsByType | No | | UserCreditUsage contains a single user's credit usage, broken down by type. `gitpod.v1.UserCreditUsage` | Field | Type | Required | Description | | -------------- | --------------------------------- | -------- | -------------------------------------------------------- | | `userId` | string | No | Empty when representing the "Others" aggregation bucket. | | `displayName` | string | No | | | `usage` | array of CreditsByType | No | | | `usageByModel` | array of EnterpriseAIUsageByModel | No | Intelligence usage broken down by model. | | Value | Number | Description | | --------------------------- | -----: | ----------- | | `PRINCIPAL_UNSPECIFIED` | 0 | | | `PRINCIPAL_ACCOUNT` | 1 | | | `PRINCIPAL_USER` | 2 | | | `PRINCIPAL_RUNNER` | 3 | | | `PRINCIPAL_ENVIRONMENT` | 4 | | | `PRINCIPAL_SERVICE_ACCOUNT` | 5 | | | `PRINCIPAL_RUNNER_MANAGER` | 6 | | UsageType identifies the category of usage. | Value | Number | Description | | ------------------------ | -----: | ----------- | | `USAGE_TYPE_UNSPECIFIED` | 0 | | | `USAGE_TYPE_ENVIRONMENT` | 1 | | | `USAGE_TYPE_AGENTIC` | 2 | | # Get Cumulative Credit Usage Source: https://ona.com/docs/api-reference/generated/billing/get-cumulative-credit-usage Returns cumulative credit usage for an organization and its teams. `Unary` · [`Billing`](/docs/api-reference/generated/billing/overview) Returns cumulative credit usage for an organization and its teams. Use this method to: * Get the total cumulative credit consumption as of a point in time * Get per-team cumulative usage with credit allocation (budget) comparison * Display team credit summaries on the usage page and team detail page * Display user budget utilization when user budgets are enabled ### Examples * Get current cumulative usage: ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" ``` * Get cumulative usage as of a specific date: ```yaml theme={null} organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" asOf: "2026-03-31T23:59:59Z" ``` ### Authorization Requires `billing:read_usage` permission on the organization. ## Endpoint ```text theme={null} POST /api/gitpod.v1.BillingService/GetCumulativeCreditUsage ``` Send a Bearer token as described in [Authentication](/docs/api-reference#authenticate-requests). If your organization uses a custom management-plane domain, replace `https://app.ona.com` with that domain. ## Request example ```bash cURL theme={null} export ONA_HOST=https://app.ona.com export ONA_API_KEY= curl --request POST \ --url "$ONA_HOST/api/gitpod.v1.BillingService/GetCumulativeCreditUsage" \ --header "Authorization: Bearer $ONA_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "organizationId": "" }' ``` ```python Python theme={null} import gitpod.v1.billing_pb2 as billing_pb2 from ona_sdk import create_client_from_env ona = create_client_from_env() request = billing_pb2.GetCumulativeCreditUsageRequest( organization_id="", ) response = ona.services.billing.get_cumulative_credit_usage(request) print(response) ``` ```typescript TypeScript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetCumulativeCreditUsageRequestSchema } from "@gitpod/sdk/gitpod/v1/billing_pb"; async function main() { const ona = createClientFromEnv(); const request = create(GetCumulativeCreditUsageRequestSchema, { organizationId: "", }); const response = await ona.services.billing.getCumulativeCreditUsage(request); console.log(response); } main().catch(console.error); ``` ```go Go theme={null} package main import ( "context" "fmt" "log" "connectrpc.com/connect" "github.com/gitpod-io/gitpod-sdk-go/sdk" gitpodpb "github.com/gitpod-io/gitpod-sdk-go/v1" ) func main() { ona, err := sdk.NewFromEnv() if err != nil { log.Fatal(err) } request := connect.NewRequest(&gitpodpb.GetCumulativeCreditUsageRequest{ OrganizationId: "", }) response, err := ona.Services.Billing.GetCumulativeCreditUsage(context.Background(), request) if err != nil { log.Fatal(err) } fmt.Println(response.Msg) } ``` ```json Request body theme={null} { "organizationId": "" } ``` ## Request `gitpod.v1.GetCumulativeCreditUsageRequest` | Field | Type | Required | Description | | ---------------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------- | | `organizationId` | string | Yes | organization\_id is the ID of the organization to get cumulative usage for. Constraints: `required=true, string.uuid=true`. | | `asOf` | RFC 3339 timestamp | No | as\_of is the point in time to compute cumulative usage up to. Defaults to now if not set. | ## Response `gitpod.v1.GetCumulativeCreditUsageResponse` | Field | Type | Required | Description | | --------------- | ---------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `orgUsage` | [CumulativeCreditUsage](#type-gitpod-v1-cumulative-credit-usage) | No | Org-wide cumulative usage, broken down by type and total. | | `teamUsage` | array of [TeamCumulativeCreditUsage](#type-gitpod-v1-team-cumulative-credit-usage) | No | Per-team cumulative usage with credit allocation comparison. Returns all teams (no top-N limit). | | `unteamedUsage` | [CumulativeCreditUsage](#type-gitpod-v1-cumulative-credit-usage) | No | Usage by members not assigned to any team. | | `periodStart` | RFC 3339 timestamp | No | Start of the cumulative calculation period. Cumulative totals are computed from this date forward. | | `userUsage` | array of [UserCreditBudgetUsage](#type-gitpod-v1-user-credit-budget-usage) | No | Per-user month-to-date usage for every user with usage in the period. The budget fields on each entry are populated only when a monthly budget applies to that user. This list is not paginated or capped; for large organizations prefer ListEnterpriseUserCreditUsage. | ## Related types CreditsByType contains credits consumed for a single usage type. `gitpod.v1.CreditsByType` | Field | Type | Required | Description | | ----------- | --------------------------------------- | -------- | ----------- | | `usageType` | [UsageType](#enum-gitpod-v1-usage-type) | No | | | `credits` | number | No | | CumulativeCreditUsage contains cumulative credit consumption totals. `gitpod.v1.CumulativeCreditUsage` | Field | Type | Required | Description | | -------------- | --------------------------------------------------------- | -------- | ------------------------------------------- | | `totalCredits` | number | No | Total credits consumed. | | `usageByType` | array of [CreditsByType](#type-gitpod-v1-credits-by-type) | No | Credits consumed broken down by usage type. | `gitpod.v1.EnterpriseAIUsageByModel` | Field | Type | Required | Description | | -------------------------- | ------------------------------------- | -------- | ----------------------------------------------------------------------- | | `model` | string | No | | | `usage` | EnterpriseAIUsage | No | | | `usageByTokenType` | array of EnterpriseAIUsageByTokenType | No | | | `unpricedUsage` | EnterpriseAIUsage | No | Usage excluded from spend because no matching BYOK rate was configured. | | `unpricedUsageByTokenType` | array of EnterpriseAIUsageByTokenType | No | | TeamCumulativeCreditUsage contains a team's cumulative credit usage and allocation. `gitpod.v1.TeamCumulativeCreditUsage` | Field | Type | Required | Description | | -------------- | ---------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `teamId` | string | No | | | `displayName` | string | No | | | `usage` | [CumulativeCreditUsage](#type-gitpod-v1-cumulative-credit-usage) | No | Cumulative credit usage for this team. | | `creditBudget` | 64-bit integer string | No | The team's credit allocation (budget) in whole credits, if set. Not set means no allocation has been configured for this team. | `gitpod.v1.UserCreditBudgetUsage` | Field | Type | Required | Description | | -------------------- | --------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `userId` | string | No | | | `displayName` | string | No | | | `monthToDateUsage` | [CumulativeCreditUsage](#type-gitpod-v1-cumulative-credit-usage) | No | | | `creditBudget` | 64-bit integer string | No | | | `budgetSource` | [EnterpriseAIUserBudgetPolicySource](#enum-gitpod-v1-enterprise-ai-user-budget-policy-source) | No | Constraints: `enum.defined_only=true`. | | `noCap` | boolean | No | | | `utilizationPercent` | number | No | | | `overBudget` | boolean | No | | | `isServiceAccount` | boolean | No | True when user\_id refers to a service account rather than a human user. The dashboard uses this to mark non-human accounts in admin tables. | | `usageByModel` | array of [EnterpriseAIUsageByModel](#type-gitpod-v1-enterprise-ai-usage-by-model) | No | Month-to-date intelligence usage broken down by model. | | Value | Number | Description | | ------------------------------------------------------ | -----: | ----------- | | `ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_UNSPECIFIED` | 0 | | | `ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_NONE` | 1 | | | `ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_ORGANIZATION` | 2 | | | `ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_USER` | 3 | | UsageType identifies the category of usage. | Value | Number | Description | | ------------------------ | -----: | ----------- | | `USAGE_TYPE_UNSPECIFIED` | 0 | | | `USAGE_TYPE_ENVIRONMENT` | 1 | | | `USAGE_TYPE_AGENTIC` | 2 | | # Billing Source: https://ona.com/docs/api-reference/generated/billing/overview BillingService provides billing and subscription management functionality. BillingService provides billing and subscription management functionality. ## Methods Creates a credit allocation (budget) for a team. Deletes the organization default or a per-user monthly budget policy. Deletes the credit allocation for a team. Returns a signed download URL for a CSV export of credit usage. Returns a daily credit usage report for an enterprise organization. Returns cumulative credit usage for an organization and its teams. Returns organization-level enterprise AI usage totals for reporting. Returns daily enterprise AI usage totals for the organization. Gets the configured and effective monthly budget policy for a user or org. Gets the credit allocation for a team. Lists enterprise AI usage grouped by team. Lists enterprise AI usage grouped by user with effective monthly budget data. Lists per-user month-to-date credit usage with effective monthly budgets. Sets the organization default or a per-user monthly budget policy. Updates the credit allocation for a team. # Migrate from SDK versions 0.x Source: https://ona.com/docs/api-reference/sdk-migration Migrate Python, TypeScript, and Go code from Ona SDK versions 0.x to versions 1.x. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Upgrade the SDK package and update your code in the same change. SDK versions 1.x are not drop-in compatible with versions 0.x. The migration does not change Ona resources or invalidate personal access tokens. If your application pins a 0.x version, migrate its code before upgrading the SDK dependency to 1.x. The distribution names remain `gitpod-sdk`, `@gitpod/sdk`, and `github.com/gitpod-io/gitpod-sdk-go`. Imports, environment variables, request types, responses, and error types change. Use the examples shipped in the [Python source distribution](https://pypi.org/project/gitpod-sdk/#files), [TypeScript package](https://unpkg.com/browse/@gitpod/sdk@latest/examples/), or [public Go module mirror](https://github.com/gitpod-io/gitpod-sdk-go). Do not use examples from the former language-specific SDK repositories. ## Review the breaking changes | Concern | Versions 0.x | Versions 1.x | | --------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- | | API key variable | `GITPOD_API_KEY` | `ONA_API_KEY` | | Custom API URL | Client-specific base URL option | `ONA_BASE_URL` or a constructor option | | Python client | `Gitpod` or `AsyncGitpod` from `gitpod` | `create_client_from_env` or `create_client` from `ona_sdk` | | TypeScript client | Default `Gitpod` export | Named `createClientFromEnv`, `createClient`, or `OnaClient` exports | | Go client | `gitpod.NewClient` and `option.*` | `sdk.NewFromEnv` and `sdk.*` options | | Request and response models | JSON models | Protobuf messages and Connect clients | | Environment operations | Service methods plus language-specific helpers | Resource clients and `Environment` handles | | Python concurrency | Synchronous and asynchronous clients | Synchronous client | | Runtime | Python 3.9+, browser and server/edge JavaScript runtimes, Go 1.22+ | Python 3.10+, Node.js 20+, Go 1.25+ | | Retries | Automatic retries for selected failures | No automatic application-level retries | | Errors | 0.x API error hierarchy | SDK workflow errors or Connect errors for direct RPCs | ## Find SDK 0.x usage Search the application before changing dependencies: ```bash theme={null} rg -n 'GITPOD_API_KEY|from gitpod import|AsyncGitpod|new Gitpod|gitpod.NewClient|gitpod-sdk-go/option' ``` Also inspect wrapper modules, dependency lockfiles, deployment secrets, retry configuration, and tests that mock 0.x response or error types. Keep this list as the migration checklist for the application. ## Upgrade the package Upgrade the package and commit the resulting lockfile or module changes: ```bash theme={null} python -m pip install --upgrade gitpod-sdk ``` ```bash theme={null} npm install @gitpod/sdk@latest ``` ```bash theme={null} go get github.com/gitpod-io/gitpod-sdk-go@latest go mod tidy ``` Do not upgrade a production dependency before the matching code changes are ready. The new release replaces classes and types under the existing distribution names. ## Rename authentication variables Rename `GITPOD_API_KEY` to `ONA_API_KEY` in deployment configuration, local environment files, and secret stores: ```bash theme={null} export ONA_API_KEY="" ``` During a staged rollout, you can expose the same personal access token under both names. Remove `GITPOD_API_KEY` after every workload uses an SDK version 1.x. For an organization with a custom management-plane domain, set the API URL explicitly: ```bash theme={null} export ONA_BASE_URL="https:///api" ``` The default is `https://app.ona.com/api`. ## Replace client construction and environment workflows Move environment lifecycle and environment operations to the high-level resource clients. These workflows replace manual environment-class selection, polling helpers, and command helpers used with SDK versions 0.x. Replace `Gitpod` or `AsyncGitpod` with `create_client_from_env`: ```python theme={null} # Before: SDK 0.x from gitpod import Gitpod client = Gitpod() environments = client.environments.list() ``` ```python theme={null} # After: SDK 1.x from ona_sdk import create_client_from_env ona = create_client_from_env() environments = ona.environments().list() ``` Create an environment and run a command through the returned handle: ```python theme={null} environment = ona.environments().create( "https://github.com/gitpod-io/template-golang-cli" ) try: result = environment.run_command( command="go test ./...", working_directory=environment.workspace_dir(), ) print(result.stdout) finally: ona.environments().delete(environment.id(), force=True) ``` The Python SDK version 1.x is synchronous. In an asynchronous application, call it through a worker thread instead of importing `AsyncGitpod`: ```python theme={null} import asyncio environment = await asyncio.to_thread( ona.environments().get, "", ) ``` Replace the default `Gitpod` class with a named client factory: ```typescript theme={null} // Before: SDK 0.x import Gitpod from "@gitpod/sdk"; const client = new Gitpod(); const environments = client.environments.list(); ``` ```typescript theme={null} // After: SDK 1.x import { createClientFromEnv } from "@gitpod/sdk"; const ona = createClientFromEnv(); const environments = ona.environments().list(); ``` Create an environment and run a command through the returned handle: ```typescript theme={null} const environment = await ona.environments().create({ contextUrl: "https://github.com/gitpod-io/template-golang-cli", }); try { const result = await environment.runCommand({ command: "go test ./...", workingDirectory: environment.workspaceDir(), }); console.log(result.stdout); } finally { await ona.environments().delete(environment.id(), { force: true }); } ``` Replace the 0.x root client and `option` package with the high-level `sdk` package: ```go theme={null} // Before: SDK 0.x client := gitpod.NewClient( option.WithBearerToken(os.Getenv("GITPOD_API_KEY")), ) ``` ```go theme={null} // After: SDK 1.x ona, err := sdk.NewFromEnv() if err != nil { return err } ``` Create an environment and run a command through the returned handle: ```go theme={null} environment, err := ona.Environments().Create(ctx, sdk.CreateEnvironmentOptions{ ContextURL: "https://github.com/gitpod-io/template-golang-cli", }) if err != nil { return err } defer ona.Environments().Delete(ctx, environment.ID(), sdk.DeleteEnvironmentOptions{Force: true}) status := environment.Proto().GetStatus() workspaceDir := status.GetDevcontainer().GetRemoteWorkspaceFolder() if workspaceDir == "" { workspaceDir = status.GetContent().GetContentLocationInMachine() } result, err := environment.RunCommand(ctx, sdk.RunCommandOptions{ Command: "go test ./...", WorkingDirectory: workspaceDir, }) if err != nil { return err } fmt.Print(result.Stdout) ``` High-level `create` calls wait for the environment to run. `stop` waits for the environment to stop, and `delete` cleans it up. Remove 0.x polling utilities that duplicate this behavior. ## Migrate direct API calls to Connect Use generated protobuf messages and Connect clients for API methods that the high-level workflows do not cover. Request fields now follow the public protobuf schema instead of the parameter objects from versions 0.x. Authenticated synchronous service clients are available through `ona.services`: ```python theme={null} from gitpod.v1.identity_pb2 import GetAuthenticatedIdentityRequest from ona_sdk import create_client_from_env ona = create_client_from_env() response = ona.services.identity.get_authenticated_identity( GetAuthenticatedIdentityRequest() ) print(response.organization_id) ``` Generated responses are protobuf messages, not Pydantic models. Replace helpers such as `to_dict()` and `to_json()` with protobuf-aware serialization where needed. Construct protobuf-es v2 messages with `create` and the generated request schema: ```typescript theme={null} import { create } from "@bufbuild/protobuf"; import { createClientFromEnv } from "@gitpod/sdk"; import { GetAuthenticatedIdentityRequestSchema } from "@gitpod/sdk/gitpod/v1/identity_pb"; const ona = createClientFromEnv(); const response = await ona.services.identity.getAuthenticatedIdentity( create(GetAuthenticatedIdentityRequestSchema), ); console.log(response.organizationId); ``` Import message types and service descriptors from generated package subpaths. Do not construct typed protobuf messages with bare object literals. Use the generated Connect clients under `v1/v1connect`. Configure the HTTP client with the same token used by the high-level SDK: ```go theme={null} token := os.Getenv("ONA_API_KEY") baseURL := os.Getenv("ONA_BASE_URL") if baseURL == "" { baseURL = "https://app.ona.com/api" } httpClient := oauth2.NewClient(ctx, oauth2.StaticTokenSource( &oauth2.Token{AccessToken: token}, )) identity := v1connect.NewIdentityServiceClient(httpClient, baseURL) response, err := identity.GetAuthenticatedIdentity( ctx, connect.NewRequest(&v1.GetAuthenticatedIdentityRequest{}), ) if err != nil { return err } fmt.Println(response.Msg.GetOrganizationId()) ``` This example uses `connectrpc.com/connect`, `golang.org/x/oauth2`, `github.com/gitpod-io/gitpod-sdk-go/v1`, and `github.com/gitpod-io/gitpod-sdk-go/v1/v1connect`. See the [API reference](https://ona.com/docs/api-reference) for the current public services and fields. ## Update pagination, timeouts, and errors Replace 0.x runtime helpers with their 1.x equivalents: * **Pagination:** High-level environment lists still fetch pages lazily. Iterate the Python generator, TypeScript async generator, or Go `iter.Seq2`. For direct RPCs, send `PaginationRequest.token` from the previous `PaginationResponse.next_token`. * **Timeouts:** Use `timeout` in Python, an `AbortSignal` or `defaultTimeoutMs` in TypeScript, and `context.Context` deadlines in Go. * **Errors:** Catch typed `SDKError` subclasses for high-level workflows. Direct calls use the language's Connect error type. Replace checks for 0.x types such as `APIStatusError`, `APIConnectionError`, and `gitpod.Error`. * **Retries:** Add retries at your application boundary only for operations that are safe to repeat. Do not assume the 0.x default of two retries still applies. ## Test the migrated application Before deploying: 1. Run the language type checker, compiler, and tests. 2. Test authentication with `ONA_API_KEY`. 3. Create, use, and delete a disposable environment. 4. Test expected error branches, timeouts, and pagination. 5. Test `ONA_BASE_URL` if the organization uses a custom domain. 6. Remove 0.x-only imports, helpers, error types, and the old `GITPOD_API_KEY` setting. Use the [Ona SDK guide](/docs/ona/integrations/sdk) for current installation and workflow examples. ## Troubleshooting The application still uses a 0.x import. Python code should import from `ona_sdk`, TypeScript should use named exports such as `createClientFromEnv`, and Go workflow code should import the `sdk` package. The Python SDK version 1.x is synchronous. Run SDK calls in a worker thread with `asyncio.to_thread`, or move the SDK work to a synchronous worker process. Build the request with the generated protobuf type for that RPC. In TypeScript, use `create(RequestSchema, fields)`. In Python and Go, instantiate the generated request message. Check the API reference because 0.x parameter names and helper types do not carry over. Confirm that the process receives `ONA_API_KEY`, not only `GITPOD_API_KEY`. For custom domains, also confirm that `ONA_BASE_URL` uses the management-plane domain and ends in `/api`. # Audit logs Source: https://ona.com/docs/ona/audit-logs/overview Audit logs provide a queryable record of all actions in your organization: who performed an operation, on which resource, and when. Use them for security monitoring, compliance reporting, and troubleshooting. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. ## Access requirements Organization admins and members with the [Audit Log Reader](/docs/ona/organizations/organization-roles#audit-log-reader) role can access audit logs. Regular members cannot access audit logs, even for resources they own. ## Entry structure Each entry contains: * **Actor**: Who (user, service account, runner, or system) * **Subject**: What resource, with its public type when one exists * **Action**: Operation performed (e.g., "Environment created") * **Timestamp**: When * **Organization**: Which org * **Kind**: The coarse event family used for querying and rendering ## What gets logged Audit logs focus on security-relevant and human-meaningful activity. This includes approved resource lifecycle and administration changes, relevant credential activity, and security activity reported from environments. | Category | Resources | | -------------- | ---------------------------------------------------------------------------------------------- | | Infrastructure | Environments, Runners, Projects, Environment Classes | | Execution | Tasks, Services, Workflows, Agents, and their executions | | Security | Users, Service Accounts, Tokens, Secrets, SSO configuration, and security policies | | Organization | [Policies](/docs/ona/organizations/policies/overview), Domain Verification, Custom Domains, Billing | | Integrations | SCM/LLM integrations and Prompts | Routine phase, status, heartbeat, reconciliation, bookkeeping, duplicate, and cascade activity is omitted. Not every database update produces an audit entry. New entries use one of these kinds: * `AUDIT_LOG_ENTRY_KIND_RESOURCE_CHANGE`: resource lifecycle and administration * `AUDIT_LOG_ENTRY_KIND_CREDENTIAL_ACCESS`: relevant credential issuance, retrieval, replacement, or propagation * `AUDIT_LOG_ENTRY_KIND_ENVIRONMENT_VETO`: activity reported by Veto from inside an environment Veto Exec enforcement entries are in preview and only appear for organizations where this preview is enabled. Veto Exec events appear as environment audit entries when enabled. Blocked and audited executions both use `AUDIT_LOG_ENTRY_KIND_ENVIRONMENT_VETO`; the action and `details.vetoExec.action` distinguish the outcome. The action includes the kernel-resolved filename and full executable digest when reported: * Filename and digest: `Veto Exec blocked: ()` * Filename only: `Veto Exec blocked: ` * Digest only: `Veto Exec blocked: ` * Neither: `Veto Exec blocked an executable` Audited events use `audited` in place of `blocked`. The entry timestamp records when Ona received the event. Veto Exec details include the reported event data except `process.cmdline`, which is omitted because it may contain credentials or other sensitive data. **Actor types:** | Type | Description | | --------------------------- | ------------------------- | | `PRINCIPAL_USER` | Human users | | `PRINCIPAL_SERVICE_ACCOUNT` | Service accounts | | `PRINCIPAL_RUNNER` | Runner infrastructure | | `PRINCIPAL_ENVIRONMENT` | Environment processes | | `PRINCIPAL_RUNNER_MANAGER` | Runner management systems | | `PRINCIPAL_ACCOUNT` | Account-level operations | ## Querying audit logs ### CLI The `ona` CLI (pre-installed in all environments) is the simplest way to query audit logs. ```bash theme={null} # View recent entries (default: 100) ona audit-logs # Specify limit ona audit-logs --limit=500 ``` **Filter by actor:** ```bash theme={null} # By user ID ona audit-logs --actor-id="d2c94c27-3b76-4a42-b88c-95a85e392c68" # By actor type ona audit-logs --actor-principal="user" ona audit-logs --actor-principal="service_account" ``` **Filter by subject:** ```bash theme={null} # By resource ID ona audit-logs --subject-id="01951d94-d6ac-7edf-9021-a044cfd1908f" # By resource type ona audit-logs --subject-type="environment" ona audit-logs --subject-type="project" ``` **Filter by time range:** ```bash theme={null} # Logs from a specific date onward ona audit-logs --from="2025-01-01T00:00:00Z" # Logs within a date range ona audit-logs --from="2025-01-01T00:00:00Z" --to="2025-01-31T23:59:59Z" ``` **Combine filters:** ```bash theme={null} ona audit-logs --subject-type="environment" --actor-principal="user" --limit=500 ``` **Export formats:** ```bash theme={null} # JSON ona audit-logs --format=json --limit=1000 > audit-logs.json # YAML ona audit-logs --format=yaml --limit=1000 > audit-logs.yaml ``` **Example output:** ``` SUBJECT ID SUBJECT TYPE ACTOR ID ACTOR PRINCIPAL ACTION CREATED AT 01951d94-d6ac-7edf-9021-a044cfd1908f RESOURCE_TYPE_ENVIRONMENT d2c94c27-3b76-4a42-b88c-95a85e392c68 PRINCIPAL_USER started environment 2025-02-21T12:10:05Z 0194f5dd-01ca-75f4-a200-74381ed43f86 RESOURCE_TYPE_PROJECT d2c94c27-3b76-4a42-b88c-95a85e392c68 PRINCIPAL_USER Project created 2025-02-21T11:45:22Z ``` ### API For programmatic access and SIEM integration, use the REST API. ```bash theme={null} export GITPOD_API_KEY="your-personal-access-token" ``` The examples use `https://app.gitpod.io`. If your organization uses a custom domain, replace this origin with your organization's dashboard domain. **Basic request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.EventService/ListAuditLogs \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"pagination": {"pageSize": 100}}' ``` **Filter by actor:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.EventService/ListAuditLogs \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "filter": { "actorIds": ["d2c94c27-3b76-4a42-b88c-95a85e392c68"], "actorPrincipals": ["PRINCIPAL_USER"] }, "pagination": {"pageSize": 100} }' ``` **Filter by subject:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.EventService/ListAuditLogs \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "filter": { "subjectTypes": ["RESOURCE_TYPE_ENVIRONMENT", "RESOURCE_TYPE_PROJECT"] }, "pagination": {"pageSize": 100} }' ``` **Pagination:** ```bash theme={null} # First request - save token curl https://app.gitpod.io/api/gitpod.v1.EventService/ListAuditLogs \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"pagination": {"pageSize": 100}}' \ | jq -r '.pagination.nextToken' > next_token.txt # Subsequent request - use token curl https://app.gitpod.io/api/gitpod.v1.EventService/ListAuditLogs \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d "{\"pagination\": {\"pageSize\": 100, \"token\": \"$(cat next_token.txt)\"}}" ``` **Response format:** ```json theme={null} { "entries": [ { "id": "01951d94-d6ac-7edf-9021-a044cfd1908f", "actorId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "actorPrincipal": "PRINCIPAL_USER", "subjectId": "0194f5dd-01ca-75f4-a200-74381ed43f86", "subjectType": "RESOURCE_TYPE_ENVIRONMENT", "action": "started environment", "kind": "AUDIT_LOG_ENTRY_KIND_RESOURCE_CHANGE", "createdAt": "2025-02-21T12:10:05Z" } ], "pagination": { "nextToken": "eyJpZCI6IjAxOTUxZDk0LWQ2YWMtN2VkZi05MDIxLWEwNDRjZmQxOTA4ZiJ9" } } ``` `ListAuditLogs` returns summary fields and the kind. Historical Veto Exec entries retain their deprecated blocked or audited kind. Other historical entries with a missing or unrecognized stored kind are returned as `AUDIT_LOG_ENTRY_KIND_UNSPECIFIED`; they are not removed from pagination. An entry whose internal subject has no public resource-type mapping uses `RESOURCE_TYPE_UNSPECIFIED` while retaining its subject ID. The response does not include the `details` payload. **Retrieve one entry with typed details:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.EventService/GetAuditLog \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"auditLogEntryId": "01951d94-d6ac-7edf-9021-a044cfd1908f"}' ``` For a Veto Exec entry, the response contains a `vetoExec` details case: ```json theme={null} { "entry": { "id": "01951d94-d6ac-7edf-9021-a044cfd1908f", "actorId": "0193e2f2-d0b5-7d52-87eb-235deadaf625", "actorPrincipal": "PRINCIPAL_ENVIRONMENT", "subjectId": "0193e2f2-d0b5-7d52-87eb-235deadaf625", "subjectType": "RESOURCE_TYPE_ENVIRONMENT", "action": "Veto Exec blocked: /usr/bin/curl (sha256:abcdef)", "createdAt": "2026-07-17T12:00:02Z", "kind": "AUDIT_LOG_ENTRY_KIND_ENVIRONMENT_VETO" }, "details": { "vetoExec": { "environmentId": "0193e2f2-d0b5-7d52-87eb-235deadaf625", "executable": "sha256:abcdef", "filename": "/usr/bin/curl", "action": "KERNEL_CONTROLS_ACTION_BLOCK", "process": { "pid": 1234, "tid": 1234, "name": "curl", "startedAt": "2026-07-17T12:00:00Z", "ppid": 1000, "pgid": 1000, "sid": 1000 }, "timestamp": "2026-07-17T12:00:01Z" } } } ``` The `details` field is optional. Clients must handle entries without details and unknown future detail types. ## Real-time event monitoring For real-time notifications instead of historical queries, use the **WatchEvents API**. This streaming endpoint pushes events as they occur. Use it for dashboards, automation triggers, and live monitoring. ### Key differences | Feature | ListAuditLogs API | WatchEvents API | | ------------ | ----------------------------------------- | ----------------------------------- | | **Purpose** | Historical analysis | Real-time monitoring | | **Access** | Organization Admins and Audit Log Readers | Users with read access to resources | | **Data** | Full audit trail with actor info | Resource changes only | | **Format** | Paginated queries | Streaming events | | **Use Case** | Compliance, security review | Dashboards, automation | ### WatchEvents with Python Install the official SDK: ```bash theme={null} pip install gitpod-sdk ``` The `GITPOD_API_KEY` environment variable should contain your [Personal Access Token](/docs/ona/integrations/personal-access-token). You only receive events for resources you have read access to. **Watch organization events:** ```python theme={null} import os from gitpod import Gitpod client = Gitpod(bearer_token=os.environ.get("GITPOD_API_KEY")) # Stream organization-wide events (projects, runners, environments) for event in client.events.watch(organization=True): print(f"{event.operation} on {event.resource_type}: {event.resource_id}") ``` **Watch environment-specific events:** ```python theme={null} # Stream events for a specific environment (includes tasks, services) for event in client.events.watch(environment_id="01951d94-d6ac-7edf-9021-a044cfd1908f"): print(f"Environment event: {event.operation} on {event.resource_type}") ``` **Async usage:** ```python theme={null} import asyncio from gitpod import AsyncGitpod client = AsyncGitpod(bearer_token=os.environ.get("GITPOD_API_KEY")) async def watch_events(): async for event in await client.events.watch(organization=True): print(f"{event.operation} on {event.resource_type}") asyncio.run(watch_events()) ``` ### Event operations * `RESOURCE_OPERATION_CREATE` - Resource created * `RESOURCE_OPERATION_UPDATE` - Resource modified * `RESOURCE_OPERATION_UPDATE_STATUS` - Status changed only * `RESOURCE_OPERATION_DELETE` - Resource deleted ### Other languages For languages without an official SDK, use gRPC/Connect-compatible clients: **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.EventService/WatchEvents` **Headers:** * `Content-Type: application/json` * `Accept: application/jsonl` * `Authorization: Bearer YOUR_API_KEY` **Request body (organization scope):** ```json theme={null} {"organization": true} ``` **Request body (environment scope):** ```json theme={null} {"environmentId": "01951d94-d6ac-7edf-9021-a044cfd1908f"} ``` See the [WatchEvents API reference](https://ona.com/docs/api-reference/resources/events/methods/watch/) for details. ## Common use cases ### Security monitoring ```bash theme={null} # Monitor secret operations ona audit-logs --subject-type="secret" --subject-type="user_secret" --subject-type="organization_secret" # Track SSO changes ona audit-logs --subject-type="sso_config" # Review token management ona audit-logs --subject-type="personal_access_token" ``` ### Compliance reporting ```bash theme={null} # Export user actions ona audit-logs --actor-principal="user" --format=json --limit=10000 > user-actions.json # Track group changes ona audit-logs --subject-type="group" --format=json > group-changes.json ``` ### Troubleshooting ```bash theme={null} # Recent environment changes ona audit-logs --subject-type="environment" --limit=500 # Project configuration updates ona audit-logs --subject-type="project" --actor-principal="user" --limit=500 # Workflow execution history ona audit-logs --subject-type="workflow_execution" --limit=500 ``` ### Resource lifecycle tracking ```bash theme={null} # Runner lifecycle ona audit-logs --subject-type="runner" --limit=500 # Environment creation/deletion patterns ona audit-logs --subject-type="environment" --limit=1000 ``` ## Best practices **Regular monitoring** * Export audit logs periodically to external storage for long-term retention * Integrate with your SIEM for centralized security monitoring * Establish baseline patterns and investigate anomalies **Access control** * Grant Organization Admin role only to users who need audit log access * Use dedicated service accounts for automated log collection * Rotate Personal Access Tokens regularly **Filtering & analysis** * Prioritize monitoring security-sensitive resource types * Combine multiple filter criteria to narrow results * Export to JSON/YAML for integration with analysis tools ## Limitations * **Retention**: Audit logs are retained according to your organization's data retention policy * **Rate limits**: API requests subject to standard rate limiting * **Filter limits**: Maximum 25 values per filter type per request * **Pagination**: Maximum 100 entries per page # Best practices Source: https://ona.com/docs/ona/best-practices Best practices for using Ona environments, agents, and guardrails effectively in your development workflow. Ona works out of the box, but it gets better as you configure it. This page walks through best practices in the order most teams adopt them, from writing your first prompt to automating recurring work. Start with the basics and add more as your workflow matures. ## Write effective prompts Include a goal, context, constraints, and success criteria. The more precise the prompt, the fewer corrections you need. A good prompt has four parts: 1. **Goal**: What are you trying to change or build? 2. **Context**: Which files, docs, errors, or examples matter? 3. **Constraints**: What conventions, patterns, or boundaries to follow? 4. **Done when**: What should be true when the task is complete? Example: ```text theme={null} Goal: Add rate limiting to the /api/upload endpoint. Context: See src/middleware/rateLimit.ts for the existing rate limiter used on /api/auth. The upload endpoint is in src/routes/upload.ts. Constraints: Use the same express-rate-limit library and configuration pattern as the auth endpoint. Limit to 10 requests per minute per user. Done when: The rate limiter is applied, a 429 response is returned when the limit is exceeded, and the existing upload tests still pass. ``` For simple tasks, goal and context are enough. For anything larger, all four parts help Ona stay scoped. ### Be explicit Ona performs best with explicit instructions, to the point of over-specification. Clear instructions increase the duration of autonomous work. | Not great | Good | | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | add a new database entity foo | add a database entity foo for the backend which has a name, description and magic value. Users will search for the magic value, but name and desc are only shown. The magic value cannot be changed and is a number from 1 to 100. | | add a new endpoint to our backend that allows users to get all of their purchases | Take a look at purchase.go. This file contains the definition for an endpoint that returns a single purchase by ID. Please note how authorization is done and how the tests in purchase\_test.go look - these are in line with our best practices. Add a new endpoint (GET /purchases) in the same file to get all of a user's purchases following the same authorization and testing best practices. | | explain the codebase | Analyze this codebase and explain its general structure, architecture, and key components. What are the most important things a developer should know to get started? Include information about the tech stack, main directories, entry points, and any critical patterns or conventions used. | | the sidebar height changes when sessions start | Understand how:
• we currently keep a stable height for sidebar entries despite font weight changes
• the progress counter pill changes the height of the sidebar item
• we could avoid that height change in line with existing patterns.

Implement that fix. | ### Give Ona context Ona understands intent, but it cannot read minds. Give it the context it needs. | Method | How | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | **URLs** | Point Ona at documentation, API references, or design specs. It reads web pages directly. | | **Screenshots** | [Attach images](/docs/ona/agents/image-attachments) by dropping them into the prompt box, using the paperclip button, or pasting from clipboard. | | **File references** | Type `@` followed by at least 3 characters to search for files in your environment. | | **Shell commands** | `!pwd` runs a command directly. The output becomes part of the agent's context. | | **TODOs** | Steer the plan at any point: `Add a todo item to review and simplify your code` | *** ## Plan before building For anything non-trivial, plan first. The cheapest way is **Plan mode**. Ona writes a `spec.md` you approve before any code is written. Skipping the planning step is the single most common reason agent runs go off the rails. The longer the task, the more planning pays off. ### Use Plan mode Plan mode adds a structured planning phase to a session. Ona asks clarifying questions, gathers requirements, writes a `spec.md`, and waits for your approval before writing any code. 1. In the session input or on the home screen, open the mode dropdown next to the send button and switch from **Agent** to **Plan**. 2. Describe the task. Ona asks follow-up questions as clickable multiple-choice options. Pick a choice, type a custom answer, or skip. 3. When Ona has enough context, it writes a `spec.md` with the full implementation plan. 4. Review the spec, then click **Build** in the next-steps prompt (or press `Cmd+Enter`) to start implementation against that plan. Use Plan mode whenever the task spans more than one or two files, touches an unfamiliar part of the codebase, or has design ambiguity. For trivial edits, stay in Agent mode. ### Explore-plan-build for ad-hoc work When you don't want a full spec but still want planning rigor, the explore-plan-build pattern works well: 1. **Explore:** Have Ona understand the system. *"Examine the authentication flow, including failure modes, security features, database connections, and audit logging. Give me a report of your findings."* 2. **Plan:** Design the change. *"We need to add audit logs to every login attempt. Ensure this doesn't impact failure rates and maintains compatibility with all SSO providers. Design a change that achieves this."* 3. **Build:** *"Implement it."* Ona already has the context and plan. Ask Ona to write the design to a markdown file, then iterate on it in VS Code. Whenever you update the file, tell Ona to incorporate your changes. This creates a collaborative design loop where you maintain control while using Ona's capabilities. For larger changes, ask Ona to reflect on its work after building: *"Review and critique your changes. How can you simplify things?"* *** ## Teach agents your codebase Put durable guidance in AGENTS.md and devcontainer.json. Once a prompting pattern works, stop repeating it manually. ### Write an AGENTS.md [AGENTS.md](https://agents.md/) is a readme for agents. Ona pulls this file into context for every session, making it an ideal place for: * Common commands (how to test, rebuild generated code) * Key files and parts of the system * Code style guide locations * Branch naming conventions Keep it short and concise. You can refer to other files and Ona will read them when necessary. Here's an example from our own repo: ```markdown title="AGENTS.md" theme={null} ## System Architecture For architectural understanding, refer to the .llm/ directory which contains a high-level overview, entity glossary, and tech stack documentation. ## Feature work - use feature branches from main for pushing work following this naming pattern: - [2-3 initials from git config user.name]/[numeric-part-of-issue-ID]-[2-3 word shorthand] - should not be more than 24 characters total IMPORTANT: Always run git config user.name first to get the actual name ## Commit messages - Follow Conventional Commits: [scope]: - Types: feat, fix, build, chore, ci, docs, style, refactor, perf, test ## Go Conventions - Accept interfaces, return concrete types - Always wrap errors with fmt.Errorf and %w - Every Ent query must use .Select() to fetch only needed columns ## Code generation - ALWAYS use leeway scripts to generate code, e.g. `leeway run api/def:generate` instead of running `buf generate` directly. ``` Agents follow direct, explicit instructions. Use all-caps *IMPORTANT* and *ALWAYS* sparingly to emphasize rules that must not be missed. See [Teach agents your codebase](/docs/ona/agents-md) for the full guide. ### Tools, tasks, and services [`devcontainer.json`](/docs/ona/configuration/devcontainer/overview) describes the tools needed to work on a codebase. Developers and agents share this setup. Use [Microsoft Dev Container images](https://containers.dev/templates) and align tool versions with the CI pipeline. `.ona/config.yaml` extends it with [tasks and services](/docs/ona/configuration/tasks-and-services/overview) that automate setup and recurring tasks. Agents can use these tasks and services and add their own, such as serving previews. *** ## Extend with integrations Connect Linear, Slack, and your SCM at the organization level. Use MCP for everything else. Ona has first-class integrations that connect at the organization level, with no MCP configuration or API keys required. Set them up under **Organization Settings > Integrations**. | Integration | What it enables | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | | [**Linear**](/docs/ona/integrations/configure-linear) | Create/update issues, search tickets, link code changes. Powers templates like [10x engineer](https://ona.com/templates). | | **Slack** | Notifications, standup updates, weekly digests, direct interaction from channels. | | **GitHub / GitLab / Bitbucket** | Code checkout, pull requests, CI log access. Connect under **Organization Settings > Integrations**. | For tools beyond first-class integrations, Ona supports [stdio MCP servers](https://modelcontextprotocol.io/docs/learn/architecture#transport-layer) configured in `.ona/mcp-config.json`. See the configuration guides for [Atlassian (Jira)](/docs/ona/integrations/configure-atlassian), [Sentry](/docs/ona/integrations/configure-sentry), and [Notion](/docs/ona/integrations/configure-notion). User and organization secrets provide secure means to store API keys, as compared to committing them to the repository. ### Add a "Build with Ona" badge Add a badge to your repository README to give contributors a one-click link to open the project in an Ona environment. ![Build with Ona](https://ona.com/build-with-ona.svg) ```markdown theme={null} [![Build with Ona](https://ona.com/build-with-ona.svg)](https://app.ona.com/#) ``` See the [README button](/docs/ona/integrations/readme-button) guide for the full snippet and an HTML version. *** ## Encode expertise in skills Once a workflow becomes repeatable, turn it into a skill. Skills are organization-wide prompts the agent applies proactively. Skills settings interface showing available skills [Skills](https://app.ona.com/settings/agent-skills) encode how your team operates. The agent discovers and applies them proactively, and they can optionally be made available as slash commands. Use them to raise pull requests, review code, and write documentation. Built-in slash commands: * `/clear` resets the session (asks for confirmation) * `/model` opens the Codex model picker in active Codex conversations * `/goal` toggles Codex goal mode in active Codex conversations when organization policy and current capabilities allow it * `/fast` toggles Codex fast mode in active Codex conversations when the selected model, configured LLM integration, and organization policy allow it * `/skills` lists available skills (available to org admins) * `/support-bundle` produces a support bundle for when Ona doesn't work as intended ### Capture your best reviewers Capture the review style of your best reviewers by analyzing their last 30 days of PR reviews, identifying patterns, and transforming those insights into a `/review-like-[name]` skill. See the [Encode a reviewer's style](/docs/ona/workflows#encode-a-reviewers-style) workflow. See [Organization-level skills](/docs/ona/skills) for how to create skills (including [example skills we use at Ona](/docs/ona/skills#example-skills-we-use-at-ona)), and [AGENTS.md skills](/docs/ona/agents-md#skills-for-repository-specific-workflows) for repository-specific workflows. *** ## Ship code effectively Be precise about what you want changed. Point to existing patterns instead of specifying every detail. The most common pitfall is under-specification. Instead of *"fix the frontend tests"*, be precise: *"Fix the flaky frontend tests for the login page where the button selectors aren't being found correctly."* The key pattern is learning from existing code: *"Add a test case to the agent tests that verifies the out-of-token failure mode. Understand the existing test cases and add one that's highly consistent."* ### Raising the pull request Encode your team's PR standards in a [`/create-pr`](/docs/ona/skills#example-skills-we-use-at-ona) skill. Type `/create-pr` and Ona commits to an appropriately named branch, links to the relevant issue, generates a description, and follows all team conventions. See the [Raise a pull request](/docs/ona/workflows#raise-a-pull-request) workflow. ### Adapt your review process A [`/code-review`](/docs/ona/skills#example-skills-we-use-at-ona) skill automates the mechanical parts: gathering diffs, checking conventions, and posting inline comments. * **Draft PRs as a pressure valve**: Push early and often. Let reviewers peek into work-in-progress while agents continue iterating. * **Tests matter more than implementation details**: With AI-generated code, tests define the expected behavior. Prioritize reviewing them. * **Consistency through context**: Maintain coding guidelines as markdown files in your repositories. The agent handles mechanical consistency checks, freeing reviewers for architectural decisions. ### Treat documentation as code A [`/technical-writing`](/docs/ona/skills#example-skills-we-use-at-ona) skill guides writers so everyone writes in one voice. Make the skill interactive instead of trying to one-shot the result. Encode your team's critical terminology (e.g. "Dev Container" not "devcontainer", "environments" not "workspaces"). *** ## Automate recurring work Start from a template. Connect integrations. Let background agents handle the work you do every day. Ona Automations [Automations](/docs/ona/automations/configure-automations) run on schedules or triggers (new issues, pull requests, webhooks) so work gets done even when you're not at your desk. Each automation runs in its own isolated environment with full access to your codebase, tools, and integrations. The fastest way to start is from a [template](https://ona.com/templates): * **10x engineer**: Daily, picks your top Linear issue, implements it, runs tests, and opens a draft PR * **Scan recent commits for bugs**: Proposes minimal fixes in a draft PR * **Sentry error triage and fix**: Traces errors to source, applies a fix, and opens a PR * **CVE mitigation and dependency updates**: Updates dependencies, runs tests, and opens a PR * **Draft weekly release notes**: Groups the week's merged PRs by category with summaries Each automation can run multiple agents concurrently across your projects. Configure concurrency limits and max actions per batch to control scope. Monitor status, success rates, and run history from the Automations dashboard. ### Ask Ona "Ask Ona" can become as natural as "Google it" for your team. New developers can use Ona as an onboarding companion instead of consuming senior engineers' time. Teams can also generate [weekly digests](/docs/ona/workflows#generate-a-weekly-digest) and [measure agent adoption](/docs/ona/workflows#measure-agent-adoption). *** ## Optimize your flow Run agents in parallel, one environment per task. Let the agent handle 90% of the work; finish the last 10% yourself. ### Go parallel Press Cmd+Enter (Ctrl+Enter on non-Mac) to start an agent and stay on the Home page, firing off tasks one after another. Each task gets its own environment: completely isolated, no file conflicts. ### 90% agent, 10% human Don't make fine adjustments through the agent. Sometimes opening a text editor and moving that line is faster. * Use the agent for the bulk of the changes. Start with precise instructions and encourage questions. * Finish and refine in VS Code web. The diff view is useful for initial review. * Start an adjustment (e.g. a refactoring) and ask Ona to understand and complete the changes. 90/10 rule illustration showing agent handling 90% of work while human handles 10% ### Progressive engagement The complexity of the change determines how deep you go: * **Simple changes**: The session summary is enough to raise a PR directly. * **Medium changes**: VS Code Web for manual edits combined with agents. * **Deep work**: A desktop IDE, only when establishing a new pattern manually. ### Preview before you ship Ona will try to provide a preview when it thinks that's helpful. You can also ask explicitly: ```text theme={null} Provide a preview for the front end changes you just made. ``` The generated URL can be shared with colleagues. Previews are useful for mobile development (open the link on your phone) and for [before vs after comparisons](/docs/ona/workflows#compare-before-vs-after). Ona providing a preview of frontend changes ### Commit early, commit often Git acts as a checkpoint system. Commit any changes that are functional, even if incomplete. Ona can rewrite history or squash commits later. The larger the change, the more often you want Ona to commit. Be explicit: *"Commit all your changes, once"* or *"Keep committing whenever you think is a good time"* or *"Do not commit or push."* ### Stay in control Join the session at any time to course correct. Click Stop or press ESC, then send a corrective message. Use `/clear` to reset the session while keeping the environment (files, database state, networking). The /clear command interface for resetting a session **On mobile**: Open [app.ona.com](https://app.ona.com) on your phone. Agents are autonomous, so mobile works well for checking in, reviewing outcomes, and firing off new tasks. ### Set guardrails * **[Command deny list](/docs/ona/command-deny-list)**: Block risky commands across the organization. For example, deny `aws *` to prevent accidental production operations. * **Agent policies**: In **Settings → Organization → Agents**, control which agent families members can use and disable Codex goal mode when persistent objectives are not appropriate for your organization. * **[Executable deny list](/docs/ona/organizations/policies/executable-deny-list)**: Block binaries by content hash at the kernel level. Cannot be bypassed by renaming or symlinking. Powered by [Veto](https://ona.com/stories/introducing-veto-security-for-the-next-era-of-software). *** ## Common mistakes * **Overloading prompts with durable rules.** Move them into [AGENTS.md](/docs/ona/agents-md) or a [skill](/docs/ona/skills). * **Not telling the agent how to verify its work.** Include build, test, and lint commands in AGENTS.md. * **Skipping planning on complex tasks.** For multi-step changes, switch to [Plan mode](#plan-before-building) and approve the spec before building. * **Using one environment for multiple tasks.** Strive for [one environment per task](#go-parallel). * **Micro-adjusting through the agent.** Open VS Code and move that line yourself. Follow the [90/10 rule](#90-agent-10-human). * **Automating before the workflow is reliable.** Turn it into a [skill](#encode-expertise-in-skills) first, then an [automation](#automate-recurring-work). * **Watching the agent step by step.** Start a task, work on something else, come back to review. Use [parallel tasks](#go-parallel). # AI cost usage API Source: https://ona.com/docs/ona/billing/cost-usage-api Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. The AI cost usage API exposes the BYOK (bring-your-own-key) spend data behind **Settings → Cost & Budgets**: organization totals, per-team and per-user attribution with budgets, and a daily time series. Use it to export AI spend to finance tools, find your top spenders, or track budget utilization. All four endpoints report BYOK token spend only. Usage from Ona Intelligence (Ona-managed models) is not included, and the `credits` field is never populated. For budget concepts, see [User budgets](/docs/ona/billing/user-budgets). ## Ona Intelligence or BYOK? Choose the right API Ona meters AI usage one of two ways, depending on how your organization is set up. The two models have separate APIs: | Your setup | How usage is metered | Use | | ----------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------- | | **BYOK** (your own provider keys) | Spend in your billing currency, via BYOK rate cards | **This API** | | **Ona Intelligence** (Ona-managed models) | Credits (OCUs) consumed as you use environments and AI | **[Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api)** | **Not sure which applies to you?** Open **Settings → Cost & Budgets**: if usage is shown as **spend in a currency** (USD, EUR, or GBP), you are on BYOK (use this API); if it is shown in **credits**, you are using Ona Intelligence (use the Ona Intelligence usage API). The APIs also tell you directly: these cost endpoints return empty usage for organizations on Ona Intelligence, and the Ona Intelligence usage API returns `FAILED_PRECONDITION` with `enterprise credit usage is not enabled` for BYOK-only organizations. ## Authentication All endpoints accept a Bearer token: a [personal access token](/docs/ona/integrations/personal-access-token) (acts as you) or a [service account token](/docs/ona/organizations/service-accounts) (owned by the organization, recommended for ongoing automation). ```bash theme={null} export GITPOD_API_KEY="your-token" ``` Organization admins and members with the [Billing Viewer](/docs/ona/organizations/organization-roles#billing-viewer) role can read all usage. Other members can read their own usage by setting `filter.subject` to themselves on the per-user endpoints. ## Request format Every endpoint is a POST with a JSON body: ```text theme={null} POST https://app.gitpod.io/api/gitpod.v1.BillingService/ ``` | Parameter | Required | Description | | ---------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `organizationId` | Yes | Your organization ID. | | `dateRange` | Yes | `startTime` and `endTime` as RFC-3339 timestamps. Both dates are inclusive and the range must not exceed 31 days. Time-of-day is ignored; dates are truncated to midnight in the request timezone. | | `timezone` | No | IANA timezone name used to bucket usage (for example `Europe/London`). Defaults to `UTC`. | | `pagination` | List endpoints | `pageSize` and `token` for paging through results. | Responses follow three conventions: * Costs are reported as `costMicrounits`: millionths of the billing `currency` unit, so `"84500000"` with `BILLING_CURRENCY_USD` is \$84.50. Currencies are `BILLING_CURRENCY_USD`, `BILLING_CURRENCY_EUR`, or `BILLING_CURRENCY_GBP`. * 64-bit integer fields (costs, token counts, limits) are returned as JSON strings, per protobuf JSON encoding. Parse them as integers. * `calculatedAt` is the time through which usage has been calculated. Usage after that timestamp may still be processing, and fields with zero values are omitted from responses. ## Organization usage summary Returns organization-wide spend and token counts for the date range, the monthly budget when one applies, and a per-model breakdown. Usage that no configured BYOK rate matched is reported separately as `unpricedUsage`. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/GetEnterpriseAIUsageSummary` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetEnterpriseAIUsageSummary \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"} }' ``` **Response:** ```json theme={null} { "calculatedAt": "2026-07-09T11:58:02Z", "usage": { "costMicrounits": "84500000", "currency": "BILLING_CURRENCY_USD", "tokens": { "inputTokens": "48200000", "outputTokens": "6100000", "cacheTokens": "310400000", "totalTokens": "364700000" } }, "budget": { "source": "ENTERPRISE_AI_USAGE_BUDGET_SOURCE_ORGANIZATION", "monthlyCostLimitMicrounits": "250000000", "currency": "BILLING_CURRENCY_USD", "monthToDateUsage": { "costMicrounits": "84500000", "currency": "BILLING_CURRENCY_USD" }, "utilizationPercent": 33.8 }, "usageByModel": [ { "model": "gpt-5.6-terra", "usage": { "costMicrounits": "61200000", "currency": "BILLING_CURRENCY_USD", "tokens": { "inputTokens": "31500000", "outputTokens": "4400000", "cacheTokens": "228000000", "totalTokens": "263900000" } }, "usageByTokenType": [ { "tokenType": "BYOK_RATE_CARD_TOKEN_TYPE_INPUT", "usage": { "costMicrounits": "18900000", "currency": "BILLING_CURRENCY_USD" } }, { "tokenType": "BYOK_RATE_CARD_TOKEN_TYPE_OUTPUT", "usage": { "costMicrounits": "26400000", "currency": "BILLING_CURRENCY_USD" } }, { "tokenType": "BYOK_RATE_CARD_TOKEN_TYPE_CACHE_READ", "usage": { "costMicrounits": "15900000", "currency": "BILLING_CURRENCY_USD" } } ] } ] } ``` `budget` is unset when no monthly budget applies to the organization. Token types are `BYOK_RATE_CARD_TOKEN_TYPE_INPUT`, `BYOK_RATE_CARD_TOKEN_TYPE_OUTPUT`, `BYOK_RATE_CARD_TOKEN_TYPE_CACHE_READ`, and `BYOK_RATE_CARD_TOKEN_TYPE_CACHE_WRITE`. ## Per-team usage Returns spend per team, with each team's monthly budget when one applies. Filter to specific teams with `filter.teamIds` (up to 100). **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseAITeamUsage` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseAITeamUsage \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"}, "pagination": {"pageSize": 50} }' ``` **Response:** ```json theme={null} { "pagination": {}, "calculatedAt": "2026-07-09T11:58:02Z", "teamUsage": [ { "teamId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Platform", "usage": { "costMicrounits": "31800000", "currency": "BILLING_CURRENCY_USD", "tokens": { "inputTokens": "18400000", "outputTokens": "2300000", "cacheTokens": "119000000", "totalTokens": "139700000" } }, "budget": { "source": "ENTERPRISE_AI_USAGE_BUDGET_SOURCE_TEAM", "monthlyCostLimitMicrounits": "50000000", "currency": "BILLING_CURRENCY_USD", "utilizationPercent": 63.6 } } ] } ``` ## Per-user usage Returns spend for each user and service account with attributed usage, including each subject's effective monthly budget. Usage not attributed to a user or service account is excluded, so the sum across subjects can be less than the organization totals. Budget fields (`monthToDateUsage`, `utilizationPercent`, `overBudget`) are computed from usage inside the requested date range measured against the monthly limit. Send a range that starts on the first day of the month for true month-to-date figures. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseAIUserUsage` **Request** (top spenders first): ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseAIUserUsage \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"}, "sort": {"field": "SORT_FIELD_USAGE", "order": "SORT_ORDER_DESC"}, "pagination": {"pageSize": 50} }' ``` **Response:** ```json theme={null} { "pagination": {}, "totalCount": 24, "calculatedAt": "2026-07-09T11:58:02Z", "userUsage": [ { "userId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Ada Lovelace", "monthToDateUsage": { "costMicrounits": "9400000", "currency": "BILLING_CURRENCY_USD", "tokens": { "inputTokens": "5200000", "outputTokens": "700000", "cacheTokens": "34100000", "totalTokens": "40000000" } }, "monthlyCostLimitMicrounits": "10000000", "currency": "BILLING_CURRENCY_USD", "budgetSource": "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_ORGANIZATION", "utilizationPercent": 94, "overBudget": false, "isServiceAccount": false } ] } ``` Sort fields: `SORT_FIELD_USAGE` (default, spend), `SORT_FIELD_DISPLAY_NAME`, `SORT_FIELD_BUDGET`, `SORT_FIELD_BUDGET_USED`. Subjects without a budget sort last on the budget fields. `noCap` is true for subjects explicitly exempted from budget limits. To restrict the list to one user or service account: ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseAIUserUsage \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"}, "filter": {"subject": {"id": "", "principal": "PRINCIPAL_USER"}} }' ``` ## Daily time series Returns one entry per day with spend totals and per-user, per-team, and per-model breakdowns. Per-user entries cover the top spenders, with the rest grouped into an "Others" bucket (empty `userId`). When `filter.subject` is set, the response contains only that subject's usage: daily totals and the team breakdown are omitted, and the model breakdown covers the subject only. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/GetEnterpriseAIUsageTimeSeries` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetEnterpriseAIUsageTimeSeries \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-07T00:00:00Z"}, "timezone": "Europe/London" }' ``` **Response:** ```json theme={null} { "calculatedAt": "2026-07-09T11:58:02Z", "dailyUsage": [ { "date": "2026-06-01T00:00:00Z", "usage": { "costMicrounits": "2900000", "currency": "BILLING_CURRENCY_USD", "tokens": { "inputTokens": "1600000", "outputTokens": "210000", "cacheTokens": "10400000", "totalTokens": "12210000" } }, "userUsage": [ { "userId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Ada Lovelace", "usage": { "costMicrounits": "1200000", "currency": "BILLING_CURRENCY_USD" } }, { "userId": "", "displayName": "Others", "usage": { "costMicrounits": "1700000", "currency": "BILLING_CURRENCY_USD" } } ], "teamUsage": [ { "teamId": "b0e12f6c-4c67-429d-a4a6-d9838b5da047", "displayName": "Platform", "usage": { "costMicrounits": "1100000", "currency": "BILLING_CURRENCY_USD" } } ], "usageByModel": [ { "model": "gpt-5.6-terra", "usage": { "costMicrounits": "2100000", "currency": "BILLING_CURRENCY_USD" } } ] } ] } ``` # Ona Intelligence usage API Source: https://ona.com/docs/ona/billing/ona-intelligence-usage-api Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. The Ona Intelligence usage API exposes the credit consumption data behind **Settings → Cost & Budgets**: daily usage broken down by type and by user, team, environment, and conversation; cumulative period totals with team allocations and per-user budgets; and a CSV export. Use it to export usage to finance tools, attribute spend across teams, or track budget utilization. ## Ona Intelligence or BYOK? Choose the right API Ona meters AI usage one of two ways, depending on how your organization is set up. The two models have separate APIs: | Your setup | How usage is metered | Use | | ----------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------- | | **Ona Intelligence** (Ona-managed models) | Credits (OCUs) consumed as you use environments and AI | **This API** | | **BYOK** (your own provider keys) | Spend in your billing currency, via BYOK rate cards | **[AI cost usage API](/docs/ona/billing/cost-usage-api)** | **Not sure which applies to you?** Open **Settings → Cost & Budgets**: if usage is shown in **credits**, you are using Ona Intelligence (use this API); if it is shown as **spend in a currency** (USD, EUR, or GBP), you are on BYOK (use the cost usage API). The APIs also tell you directly: this API returns `FAILED_PRECONDITION` with `enterprise credit usage is not enabled` for BYOK-only organizations, and the cost endpoints return empty usage for organizations on Ona Intelligence. ## Authentication All endpoints accept a Bearer token: a [personal access token](/docs/ona/integrations/personal-access-token) (acts as you) or a [service account token](/docs/ona/organizations/service-accounts) (owned by the organization, recommended for ongoing automation). ```bash theme={null} export GITPOD_API_KEY="your-token" ``` Organization admins and members with the [Billing Viewer](/docs/ona/organizations/organization-roles#billing-viewer) role can read all usage. Other members can read their own usage on the report endpoint by setting `filter.subject` to their own user identity (this self-access path is for user tokens, not service accounts). ## Request format Every endpoint is a POST with a JSON body: ```text theme={null} POST https://app.gitpod.io/api/gitpod.v1.BillingService/ ``` | Parameter | Required | Description | | ---------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `organizationId` | Yes | Your organization ID. | | `dateRange` | Report, export | `startTime` and `endTime` as RFC-3339 timestamps. Both dates are inclusive; time-of-day is ignored. The report is capped at 31 days; the export may cover up to a year. | | `asOf` | Cumulative, list | Point in time to compute month-to-date usage up to. Defaults to now. | | `timezone` | No | IANA timezone name (for example `Europe/London`) used to bucket daily usage. Defaults to `UTC`. | | `pagination` | List | `pageSize` and `token` for paging. | Response conventions: * Credits are floating-point values (for example `12.5`). Budgets (`creditBudget`) are whole credits. * `usageType` is `USAGE_TYPE_ENVIRONMENT` (environment runtime) or `USAGE_TYPE_AGENTIC` (agent activity). * Token counts are returned as JSON strings, per protobuf JSON encoding. * Fields at their default value are omitted. `creditBudget`, `utilizationPercent`, and `overBudget` appear on a user only when a budget applies, `overBudget` and `isServiceAccount` only when true, and an unset budget or zero usage leaves the field out entirely. * `periodStart` marks the start of the billing period; usage before it is excluded. ## Daily usage report Returns one entry per day: org-wide credits by usage type, plus per-user, per-team, per-environment, and per-conversation breakdowns (top consumers with the rest grouped into an "Others" bucket), and a per-model breakdown of agent usage. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/GetCreditUsageReport` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetCreditUsageReport \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"} }' ``` **Response:** ```json theme={null} { "updatedAt": "2026-07-09T12:00:00Z", "periodStart": "2026-01-01T00:00:00Z", "dailyUsage": [ { "date": "2026-06-01T00:00:00Z", "orgUsage": [ { "usageType": "USAGE_TYPE_ENVIRONMENT", "credits": 41.5 }, { "usageType": "USAGE_TYPE_AGENTIC", "credits": 918.25 } ], "userUsage": [ { "userId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Ada Lovelace", "usage": [{ "usageType": "USAGE_TYPE_AGENTIC", "credits": 930.49 }] }, { "userId": "", "displayName": "Others", "usage": [{ "usageType": "USAGE_TYPE_ENVIRONMENT", "credits": 33.0 }] } ], "teamUsage": [ { "teamId": "b0e12f6c-4c67-429d-a4a6-d9838b5da047", "displayName": "Platform", "usage": [{ "usageType": "USAGE_TYPE_AGENTIC", "credits": 622.31 }] } ], "environmentUsage": [ { "environmentId": "0191e4b2-6b3c-7973-a78b-68dc4a6da6b2", "displayName": "my-service", "usage": [{ "usageType": "USAGE_TYPE_ENVIRONMENT", "credits": 22.4 }] } ], "conversationUsage": [ { "agentExecutionId": "019ee14b-2596-771d-82d2-ef9d3d16465d", "displayName": "Add pagination to the users table", "usage": [{ "usageType": "USAGE_TYPE_AGENTIC", "credits": 231.87 }] } ], "usageByModel": [ { "model": "gpt-5.6-terra", "usage": { "credits": 930.49, "tokens": { "inputTokens": "166562", "outputTokens": "898901", "cacheTokens": "154015590", "totalTokens": "155081053" } }, "usageByTokenType": [ { "tokenType": "BYOK_RATE_CARD_TOKEN_TYPE_CACHE_READ", "usage": { "credits": 892.86, "tokens": { "cacheTokens": "148810014", "totalTokens": "148810014" } } }, { "tokenType": "BYOK_RATE_CARD_TOKEN_TYPE_OUTPUT", "usage": { "credits": 5.39, "tokens": { "outputTokens": "898901", "totalTokens": "898901" } } } ] } ] } ] } ``` An empty `userId` (or `teamId`, `environmentId`, `agentExecutionId`) marks the "Others" bucket. Each `userUsage` entry also carries a `usageByModel` breakdown with the same shape as the day-level one shown here; `teamUsage`, `environmentUsage`, and `conversationUsage` do not. Token types (`BYOK_RATE_CARD_TOKEN_TYPE_INPUT`, `_OUTPUT`, `_CACHE_READ`, `_CACHE_WRITE`) apply to both Ona Intelligence and BYOK usage. To restrict the report to one subject, set `filter.subject`: ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetCreditUsageReport \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"}, "filter": {"subject": {"id": "", "principal": "PRINCIPAL_USER"}} }' ``` When `filter.subject` is set, each day's `userUsage` contains only that subject (no "Others" bucket), and the org, team, environment, and conversation breakdowns are omitted. ## Cumulative period usage Returns period-to-date totals for the organization, each team (with its credit allocation), members not on any team, and per-user month-to-date usage with budgets. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/GetCumulativeCreditUsage` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetCumulativeCreditUsage \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{"organizationId": ""}' ``` **Response:** ```json theme={null} { "periodStart": "2026-01-01T00:00:00Z", "orgUsage": { "totalCredits": 1840.75, "usageByType": [ { "usageType": "USAGE_TYPE_ENVIRONMENT", "credits": 1290.5 }, { "usageType": "USAGE_TYPE_AGENTIC", "credits": 550.25 } ] }, "teamUsage": [ { "teamId": "b0e12f6c-4c67-429d-a4a6-d9838b5da047", "displayName": "Platform", "usage": { "totalCredits": 620.0, "usageByType": [{ "usageType": "USAGE_TYPE_AGENTIC", "credits": 240.0 }] }, "creditBudget": "1000" } ], "unteamedUsage": { "totalCredits": 90.0 }, "userUsage": [ { "userId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Ada Lovelace", "monthToDateUsage": { "totalCredits": 120.5, "usageByType": [{ "usageType": "USAGE_TYPE_AGENTIC", "credits": 120.5 }] }, "creditBudget": "150", "budgetSource": "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_ORGANIZATION", "utilizationPercent": 80.3, "usageByModel": [ { "model": "gpt-5.6-terra", "usage": { "credits": 120.5, "tokens": { "inputTokens": "103422", "outputTokens": "63100", "cacheTokens": "35707859", "totalTokens": "35874381" } } } ] } ] } ``` `teamUsage` returns all teams (no top-N limit). The `userUsage` list is not paginated or capped; for large organizations prefer the paginated list endpoint below. Each user carries a `usageByModel` breakdown; budget fields appear only when a monthly budget applies (`overBudget` only when the user is over it), and `noCap` is `true` for users exempted from limits. ## Per-user usage list Returns per-user month-to-date usage with budgets, paginated. Ordered by total credits descending by default so the highest spenders appear first. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseUserCreditUsage` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/ListEnterpriseUserCreditUsage \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "sort": {"field": "SORT_FIELD_USAGE", "order": "SORT_ORDER_DESC"}, "pagination": {"pageSize": 50} }' ``` **Response:** ```json theme={null} { "totalCount": 24, "pagination": { "nextToken": "d2c94c27-3b76-4a42-b88c-95a85e392c68" }, "userUsage": [ { "userId": "d2c94c27-3b76-4a42-b88c-95a85e392c68", "displayName": "Ada Lovelace", "monthToDateUsage": { "totalCredits": 1320.37, "usageByType": [ { "usageType": "USAGE_TYPE_ENVIRONMENT", "credits": 177.78 }, { "usageType": "USAGE_TYPE_AGENTIC", "credits": 1142.59 } ] }, "creditBudget": "500", "budgetSource": "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_USER", "utilizationPercent": 264.07, "overBudget": true, "usageByModel": [ { "model": "gpt-5.6-terra", "usage": { "credits": 1142.59, "tokens": { "inputTokens": "166562", "outputTokens": "898901", "cacheTokens": "154015590", "totalTokens": "155081053" } } } ] } ] } ``` The page token (`nextToken`) is the last user's ID. `budgetSource` is `ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_ORGANIZATION`, `_USER`, or `_NONE`. Sort fields: `SORT_FIELD_USAGE` (default, total credits), `SORT_FIELD_DISPLAY_NAME`, `SORT_FIELD_BUDGET`, `SORT_FIELD_BUDGET_USED`. The default usage ordering paginates over any number of users. The other three sorts compute the order in memory and are limited to organizations with at most 10,000 users; beyond that, use `SORT_FIELD_USAGE`. Because month-to-date figures are recomputed per request, hold `asOf` stable across a paginated walk to keep page tokens valid. ## CSV export Returns a short-lived, signed download URL for a gzip-compressed CSV. The download must be made by the same principal that requested it, carrying its own bearer token. **Endpoint:** `POST https://app.gitpod.io/api/gitpod.v1.BillingService/GetCreditUsageExport` **Request:** ```bash theme={null} curl https://app.gitpod.io/api/gitpod.v1.BillingService/GetCreditUsageExport \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $GITPOD_API_KEY" \ -d '{ "organizationId": "", "dateRange": {"startTime": "2026-06-01T00:00:00Z", "endTime": "2026-06-30T00:00:00Z"}, "groupBy": "CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY" }' ``` **Response:** ```json theme={null} { "downloadUrl": "https://app.gitpod.io/billing/credit-usage-export/" } ``` Then download within five minutes, sending your token: ```bash theme={null} curl -L -H "Authorization: Bearer $GITPOD_API_KEY" "$DOWNLOAD_URL" | gunzip > credit-usage.csv ``` `groupBy` is `CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY` (per-user daily summary, the default) or `CREDIT_USAGE_EXPORT_GROUP_BY_RESOURCE` (per-environment and per-conversation breakdown). # Billing Source: https://ona.com/docs/ona/billing/overview Manage billing for Core Ona Cloud organizations. This page covers self-serve billing for **Core** organizations using Ona Cloud. New self-serve organizations start on Core. All payments are processed securely by Stripe. Ona never sees your card details. Enterprise organizations use a separate billing model. In the dashboard, **Settings → Billing** does not show self-serve billing controls for Enterprise tier organizations. For enterprise billing changes, contact your account representative. Manage billing at **Settings → Billing**. Ona billing settings page showing subscription status, payment method, and credit balance ## Access requirements Organization members can view Core billing details. Members with the [Billing Viewer](/docs/ona/organizations/organization-roles#billing-viewer) role can also view organization usage reports. Only organization admins can change subscriptions, payment methods, credit top-ups, and automatic top-up settings. ## What this page covers Use this page if you need to set up or manage Core billing: * sign up for Core * manage your Core subscription * buy or automatically top up Ona Cloud credits * handle failed payments or cancellation For how usage is measured and how credits are consumed, continue to [Cost & Budgets](/docs/ona/billing/usage). ## Coupon codes If you have a coupon or credit code, enter it on the billing page **before** signing up for Core. The coupon field appears during the Core signup flow at **Settings → Billing**. ## Core subscription Core provides enhanced features and monthly credits. See [Cost & Budgets](/docs/ona/billing/usage) for how credits are consumed. **To sign up:** Go to **Settings → Billing**, select Core, choose your monthly credit allocation, and enter payment details. If you connect Codex to your ChatGPT account, OpenAI manages that ChatGPT plan. Ona billing still covers your Ona subscription, top-ups, and environment usage. | Credits | Behavior | | ------------------ | ---------------------------- | | Monthly allocation | Reset at each billing period | | Unused credits | Don't roll over | | Top-up credits | Valid for up to one year | Plan selection interface showing different monthly credit allocation options for Core subscription You cannot change your Core plan variant after subscribing. To change, cancel and resubscribe with a different allocation. ## Credit top-up Purchase additional credits at **Settings → Billing** → **Top-up**. Top-up credits are available immediately and valid for up to one year. Credit top-up dialog showing options to purchase additional credits ## Automatic credit top-up Avoid running out of credits by enabling automatic top-ups. When your balance drops below 20 OCUs, Ona charges your default payment method and adds credits to your account. **To enable:** Go to **Settings → Billing**, toggle **Enable auto top-up**, and select a top-up amount. A cooldown between top-ups prevents duplicate charges. Auto top-up requires [Core plan](https://ona.com/pricing) or higher. ## Failed payments You have **7 days** to resolve failed payments before your account is locked. To fix: **Settings → Billing** → **Access Stripe Portal** → update payment method. After the grace period: * Your account is locked. You cannot start new environments until payment is resolved. * Remaining Core credits are forfeited * You can resubscribe at any time to restore access ## Cancellation 1. Navigate to **Settings > Billing** 2. Click **Manage** under your current plan 3. Click **Cancel plan** and confirm Your subscription remains active until the end of the current billing period. After it expires, you cannot start new environments until you resubscribe. ## Stripe portal Access your Stripe portal from **Settings → Billing** → **Access Stripe Portal** to: * Update payment methods and billing address * Add tax IDs (VAT, etc.) * Download invoices and receipts ## Enterprise These billing controls do not apply to Enterprise tier organizations. For enterprise billing changes, [contact sales](https://ona.com/contact/sales) or work with your account representative. ## Next steps * [Cost & Budgets](/docs/ona/billing/usage) - Understand credit consumption # Cost & Budgets Source: https://ona.com/docs/ona/billing/usage Understand usage and OCU billing for Core Ona Cloud organizations. This page covers usage for **Core** organizations using Ona Cloud. Enterprise organizations use a separate usage view and billing model. In Enterprise, usage is billed in credits rather than OCUs, and **Settings → Cost & Budgets** opens the enterprise view instead of the OCU view described here. See [User budgets](/docs/ona/billing/user-budgets) for per-user budgeting in Enterprise. An **OCU (Ona Compute Unit)** measures resource consumption for Core plans. Your subscription balance is consumed in OCUs as you use environments and AI features. ## Access requirements Organization admins and members with the [Billing Viewer](/docs/ona/organizations/organization-roles#billing-viewer) role can view **Settings → Cost & Budgets**. Billing Viewers can read usage data, but cannot add credits, change budgets, or update billing settings. ## Consumption rates ### Environments OCUs are consumed while environments are running, based on size: | Environment | Resources | Rate | | --------------- | ------------------- | ----------- | | Standard | 4 vCPUs / 16GB RAM | 1 OCU/hour | | GPU-accelerated | 16 vCPUs / 64GB RAM | 7 OCUs/hour | ### Agentic tasks Approximate OCU consumption for AI tasks: | Task | OCUs | | -------------------------------- | ---- | | Explain a small codebase | 1 | | Explain a large codebase | 3 | | Create a new web app | 4 | | Add a feature to medium codebase | 8 | ### Codex with a connected ChatGPT plan If you [connect Codex to your ChatGPT account](/docs/ona/integrations/configure-codex), Codex model requests use your ChatGPT plan instead of Ona-managed model credits. Ona does not charge OCUs for that Codex model usage. The environment still consumes OCUs while it is running. OpenAI manages ChatGPT-side rate limits and usage limits. ## Tracking your usage To see how your organization is spending credits, go to **Settings → Cost & Budgets**. The Cost & Budgets page gives you a clear picture of your credit consumption over the last 7 or 30 days. Cost & Budgets page showing credit balance and daily consumption chart At the top, a credit summary shows your total balance, how many credits you've used, and how many are still available. Below that, a daily consumption chart breaks down your spending over time so you can spot trends or unexpected spikes. If your credits are running low, a banner appears with an estimate of how many days you have left at your current pace so you can top up or adjust your usage before you hit zero. Enterprise organizations can query this data programmatically with the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api), or the [AI cost usage API](/docs/ona/billing/cost-usage-api) for organizations that bring their own provider keys (BYOK). ## Credit expiration * **Core subscription credits** renew monthly as long as your subscription is active. They do not roll over. * **Top-up credits** are valid for up to 1 year while you have an active subscription. Without an active subscription, top-up credits expire when the subscription ends. * **Usage order**: Subscription credits are consumed first, then top-up credits. Bonus/gift credits are used last and typically have a longer expiration. ## Running low on credits? * [Enable auto top-up](/docs/ona/billing/overview#automatic-credit-top-up) to add credits automatically when your balance is low * [Top up credits](/docs/ona/billing/overview#credit-top-up) for a one-time purchase * [Review Core subscription options](/docs/ona/billing/overview#core-subscription) for more monthly credits ## Next steps * [Billing overview](/docs/ona/billing/overview) - Manage subscriptions and payments * [Organizations overview](/docs/ona/organizations/overview) - Understand where usage is owned and administered # User budgets Source: https://ona.com/docs/ona/billing/user-budgets Set monthly usage budgets for individual users in Enterprise organizations. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Cost & Budgets page showing monthly usage and per-user budget utilization. User budgets give every member of your organization a monthly allowance for environment and AI usage. Admins see each user's spend against their budget on the **Cost & Budgets** page, and users see their own utilization while they work. Budgets are **soft**: they exist for reporting and visibility and are **not enforced** at usage time. A user who exceeds their budget can keep creating environments and running agents. To attribute and budget usage by team instead, see [Teams](/docs/ona/organizations/teams). ## Budget types | Budget type | Applies to | Unit | | ------------------ | -------------------------------------------------------- | ------------------------------------------- | | Credit budget | Environment usage and AI usage are billed in Ona credits | Credits per month | | Cost budget (BYOK) | Model usage billed through your own provider keys | Amount per month in your rate card currency | Organizations with credit billing manage credit budgets in the **User credit usage** section of the Cost & Budgets page. Organizations that bring their own keys manage cost budgets in the **User AI usage** section. Budgets reset at the start of each calendar month. Changing a budget applies going forward and does not change historical usage or budget history. ## Access requirements Organization admins can set, change, and remove budgets. Members with the [Billing Viewer](/docs/ona/organizations/organization-roles#billing-viewer) role can see usage and budgets but cannot change them. ## Set a default budget for all users The default budget applies to every user who does not have an individual override. 1. Go to **Settings → Cost & Budgets** 2. Open the user usage section 3. In the default budget row, click **Set budget** 4. Enter the monthly amount and save When you change the default and some users have individual overrides, check **Apply to all users** to remove those overrides at the same time. ## Set a budget for one user An individual budget overrides the organization default for that user. 1. Go to **Settings → Cost & Budgets** 2. Open the user usage section 3. In the user's row, click the budget value, or **Set budget** if none is set 4. Enter the monthly amount and save To remove an individual override, open the same dialog and click **Remove override**. The user falls back to the organization default. ## Track utilization Each row on the Cost & Budgets page shows the user's month-to-date spend, their effective budget, and the percentage used. Users over 100% are highlighted. You can sort the table by budget or budget used to find the heaviest consumers. Users see their own budget utilization in the chat input while working with the agent, as a percentage of their monthly budget. CSV exports of credit usage include each user's budget, so you can report on utilization outside Ona. Click **Export CSV** on the Cost & Budgets page. ## API access Query usage, per-team and per-user attribution, and budget utilization programmatically. Use the [Ona Intelligence usage API](/docs/ona/billing/ona-intelligence-usage-api) if your organization is billed in credits, or the [AI cost usage API](/docs/ona/billing/cost-usage-api) if you bring your own provider keys (BYOK). Each page opens with a short guide to tell which applies to you. ## FAQ Nothing is blocked. Budgets are soft limits: the user's row is highlighted as over budget on the Cost & Budgets page and their own indicator shows usage above 100%, but they can continue to create environments and use AI features. Use the Cost & Budgets page to follow up with heavy consumers. No. Budgets are a fixed monthly allowance. Utilization starts at zero at the beginning of each calendar month. Yes. Service accounts appear in the user usage table alongside members, and you can set a budget on a service account's row the same way. They are independent views of the same usage. [Team budgets](/docs/ona/organizations/teams#per-team-credit-budgets) aggregate usage per team, while user budgets track each individual. Both are soft limits. # Command deny list Source: https://ona.com/docs/ona/command-deny-list Block specific commands from being executed by agents. Block specific commands from being executed by agents. Use deny lists to prevent dangerous operations, enforce security policies, and maintain compliance. This is part of [Guardrails](/docs/ona/guardrails/overview). Agents settings page showing Command Deny List text area with blocked command patterns ## How it works 1. A user provides input to an agent 2. Agent decides to execute a command 3. System checks command against deny list 4. Command is executed (if allowed) or blocked with error message ### Pattern matching | Pattern | Effect | | ----------- | ------------------------------------------------ | | `shutdown` | Blocks exactly "shutdown" | | `shutdown*` | Blocks "shutdown", "shutdown -h", "shutdown now" | | `rm *` | Blocks all `rm` commands with arguments | **Slash commands** (`/clear`, `/support-bundle`) are not blocked by deny lists. They are converted to prompts before reaching the agent. **Bash commands** (prefixed with `!`) are subject to deny list filtering. ## Configuration Go to [Settings → Agents → Policies](https://app.ona.com/settings/agent-policies). Only administrators can access. 1. Add patterns to **Command Deny List** (one per line) 2. Save changes Changes apply to new agent sessions. Existing sessions must be restarted. ### Example patterns ``` # Block package management apt * yum * dnf * # Block cloud provider CLIs aws * gcloud * ``` ## Effect on users When blocked, users see: ``` command execution prohibited: command matches deny pattern: rm *. Do not attempt to retry this command as it is blocked by security policy ``` * **Manual commands unaffected**: Users can still run commands directly in terminal * **Agent only**: Only agent execution is restricted * **No retries**: Agent is instructed not to retry blocked commands ## Security considerations **Protects against:** * Accidental destructive commands * Malicious prompt injection * Compliance violations * Resource abuse **Does not protect against:** * Direct user commands in terminal * Application-level actions * Slash commands (cannot be blocked via deny lists) For kernel-level binary blocking that applies to all processes (not only the agent), see the [executable deny list](/docs/ona/organizations/policies/executable-deny-list). ## Best practices * Start with broad patterns (`aws *` instead of listing variants) * Test in a non-production environment first * Document why patterns were added * Review and update periodically ## Testing 1. Create a new environment 2. Ask the agent to run a blocked command 3. Verify the error message appears ## Getting help Enterprise customers can contact your account representative. # OpenID Connect (OIDC) Source: https://ona.com/docs/ona/configuration/oidc Access cloud providers and third-party services from Ona environments using OIDC tokens, without static credentials. Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. Ona issues OIDC tokens that environments, users, and service accounts can exchange for short-lived credentials from cloud providers and third-party services. This eliminates static secrets, API keys, and long-lived credentials. OIDC tokens work with both Ona Cloud and self-hosted runners. ## Enable V3 tokens V3 tokens are the current token format. They include flat, structured claims per principal type and a customizable `sub` claim. To enable V3 tokens for your organization: 1. Open the [OIDC Token Configuration](https://app.gitpod.io/settings/security/oidc) page in your organization settings 2. Select **V3** as the token version 3. Optionally configure extra sub claim fields 4. Save Switching from V2 to V3 changes the `sub` claim format. Update your cloud provider trust policies before switching. See [V2 tokens](#v2-tokens) for the old format. ## Token structure V3 tokens contain flat claims specific to the requesting principal. Every token includes the standard JWT claims (`iss`, `sub`, `aud`, `exp`, `iat`) plus principal-specific claims. ### Environment tokens Issued when code running inside an environment requests a token. ```json theme={null} { "iss": "https://app.gitpod.io", "sub": "organization_id:a1b2c3d4-...:project_id:c9d0e1f2-...", "aud": ["sts.amazonaws.com"], "exp": 1711929600, "iat": 1711926000, "environment_id": "e5f6a7b8-0000-4000-8000-000000000004", "organization_id": "a1b2c3d4-0000-4000-8000-000000000001", "project_id": "c9d0e1f2-0000-4000-8000-000000000005", "runner_id": "f3a4b5c6-0000-4000-8000-000000000007", "creator_principal": "user", "creator_id": "b3c4d5e6-0000-4000-8000-000000000003", "creator_email": "dev@example.com", "creator_name": "Jane Doe", "creator_idp": "https://accounts.google.com", "creator_idp_claims": { "groups": ["engineering"] }, "environment_initializers": [ { "git": { "remote_uri": "https://github.com/org/repo.git" }, "context_url": "https://github.com/org/repo" } ] } ``` ### User tokens Issued when a user requests a token directly (e.g., via the CLI outside an environment). ```json theme={null} { "iss": "https://app.gitpod.io", "sub": "organization_id:a1b2c3d4-...:user_id:b3c4d5e6-...", "aud": ["sts.amazonaws.com"], "exp": 1711929600, "iat": 1711926000, "account_id": "d7e8f9a0-0000-4000-8000-000000000002", "user_id": "b3c4d5e6-0000-4000-8000-000000000003", "organization_id": "a1b2c3d4-0000-4000-8000-000000000001", "email": "dev@example.com", "name": "Jane Doe", "idp": "https://accounts.google.com", "idp_claims": { "groups": ["engineering"] } } ``` ### Service account tokens Issued when a service account requests a token. ```json theme={null} { "iss": "https://app.gitpod.io", "sub": "organization_id:a1b2c3d4-...:service_account_id:f0a1b2c3-...", "aud": ["sts.amazonaws.com"], "exp": 1711929600, "iat": 1711926000, "service_account_id": "f0a1b2c3-0000-4000-8000-000000000006", "organization_id": "a1b2c3d4-0000-4000-8000-000000000001", "name": "ci-bot" } ``` ### Account tokens Issued for account-level operations (not scoped to an organization). ```json theme={null} { "iss": "https://app.gitpod.io", "sub": "account_id:d7e8f9a0-...", "aud": ["sts.amazonaws.com"], "exp": 1711929600, "iat": 1711926000, "account_id": "d7e8f9a0-0000-4000-8000-000000000002", "email": "admin@example.com", "name": "Jane Admin", "idp": "https://accounts.google.com", "idp_claims": { "groups": ["engineering", "platform"] } } ``` ### Runner tokens Issued for runner-level operations. ```json theme={null} { "iss": "https://app.gitpod.io", "sub": "organization_id:a1b2c3d4-...:runner_id:f3a4b5c6-...", "aud": ["sts.amazonaws.com"], "exp": 1711929600, "iat": 1711926000, "runner_id": "f3a4b5c6-0000-4000-8000-000000000007", "organization_id": "a1b2c3d4-0000-4000-8000-000000000001", "runner_name": "us-east-prod" } ``` ## Subject claim (`sub`) The V3 `sub` claim uses a `key:value` pair format separated by colons: ``` organization_id::project_id: ``` Each principal type has default sub claim keys: | Principal | Default sub claim | | ----------------------------- | --------------------------------------------------- | | Environment (with project) | `organization_id::project_id:` | | Environment (without project) | `organization_id:` | | User | `organization_id::user_id:` | | Service Account | `organization_id::service_account_id:` | | Account | `account_id:` | | Runner | `organization_id::runner_id:` | ### Customizing the sub claim You can add extra fields to the `sub` claim to create more specific trust policies. Configure extra sub fields on the [OIDC Token Configuration](https://app.gitpod.io/settings/security/oidc) page. Available extra sub fields: | Field | Description | Principals | | -------------------------------------------------- | ------------------------------------------ | ------------------------------------- | | `creator_id` | ID of the user who created the environment | Environment | | `creator_principal` | Principal type of the creator | Environment | | `creator_email` | Email of the creator | Environment | | `creator_name` | Name of the creator | Environment | | `creator_idp` | Identity provider URL of the creator | Environment | | `account_id` | Account ID | Account, User | | `user_id` | User ID | User | | `organization_id` | Organization ID | All (already in default sub for most) | | `project_id` | Project ID | Environment | | `runner_id` | Runner ID | Runner, Environment | | `environment_id` | Environment ID | Environment | | `email` | Email of the principal | User, Account | | `name` | Name of the principal | User, Account, ServiceAccount | | `idp` | Identity provider URL | User, Account | | `runner_name` | Name of the runner | Runner | | `service_account_id` | Service account ID | ServiceAccount | | `environment_initializers.git.remote_uri` | Git remote URI | Environment | | `environment_initializers.git.upstream_remote_uri` | Upstream git remote URI | Environment | | `environment_initializers.context_url` | Context URL | Environment | For example, adding `creator_email` produces a sub like: ``` organization_id::environment_id::creator_email:dev@example.com ``` This lets you write trust policies that restrict access to environments created by a specific developer. ## Setting up OIDC authentication Setting up OIDC authentication involves three steps: 1. **Register Ona as an identity provider** with your cloud provider or third-party service. Use `https://app.gitpod.io` as the issuer URL. 2. **Configure trust rules** that define which token claims are required for access. Use the `sub` claim and other flat claims to implement fine-grained access control. 3. **Exchange the token** from within an Ona environment using the CLI. The cloud provider validates the token against Ona's JWKS endpoint and issues short-lived credentials. ## Provider-specific guides * [AWS](/docs/ona/identity/aws-oidc) * [Azure](/docs/ona/identity/azure-oidc) * [GCP](/docs/ona/identity/gcp-oidc) * [HashiCorp Vault](/docs/ona/identity/vault-oidc) ## CLI usage Retrieve a token using `ona idp token`: ```bash theme={null} ona idp token --audience sts.amazonaws.com ``` Decode the token to inspect claims: ```bash theme={null} ona idp token --audience sts.amazonaws.com --decode ``` Use `ona idp login` for provider-specific authentication: ```bash theme={null} # AWS ona idp login aws --role-arn arn:aws:iam::123456789012:role/OnaRole # HashiCorp Vault ona idp login vault --role my-role ``` ## OIDC discovery endpoint Ona exposes a standard OIDC discovery endpoint at: ``` https://app.gitpod.io/.well-known/openid-configuration ``` The JSON Web Key Set (JWKS) for verifying token signatures is at: ``` https://app.gitpod.io/.well-known/jwks.json ``` The discovery endpoint returns the full list of supported claims, including all V3 claims: ```json theme={null} { "issuer": "https://app.gitpod.io", "authorization_endpoint": "https://app.gitpod.io/auth/oauth2/authorize", "token_endpoint": "https://app.gitpod.io/auth/oauth2/token", "jwks_uri": "https://app.gitpod.io/.well-known/jwks.json", "scopes_supported": ["openid"], "response_types_supported": ["code", "id_token", "token"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256"], "claims_supported": [ "sub", "iss", "aud", "exp", "iat", "org", "gsub", "account_id", "user_id", "organization_id", "project_id", "runner_id", "runner_manager_id", "environment_id", "service_account_id", "environment_initializers", "creator_principal", "creator_id", "creator_email", "creator_name", "creator_idp", "creator_idp_claims", "email", "name", "idp", "idp_claims", "runner_name" ], "code_challenge_methods_supported": ["S256"] } ``` ## V2 tokens V2 is the previous token format. New integrations should use V3 tokens. V2 tokens remain fully supported and will continue to work. They do not receive new claims or features. V2 tokens use a different `sub` claim format and include fewer claims. If your organization currently uses V2 tokens, existing integrations will continue to function without changes. ### V2 subject claim format The V2 `sub` claim uses a path-based format: * **Users:** `org:/user:` * **Runners:** `org:/rnr:` * **Environments without a project:** `org:/env:` * **Environments from a project:** `org:/prj:/env:` ### V2 token example ```json theme={null} { "aud": "example.org", "exp": 1740517845, "iat": 1740514245, "iss": "https://app.gitpod.io", "org": "0191e223-1c3c-7607-badf-303c98b52d2f", "sub": "org:0191e223-1c3c-7607-badf-303c98b52d2f/prj:019527e4-75d5-704d-a5a4-a2b52cf56198/env:019527e4-75d5-704d-a5a4-a2b52cf56196", "gsub": { "principal": "environment", "id": "019527e4-75d5-704d-a5a4-a2b52cf56196" } } ``` ### V2 access control You can match on the `sub` claim prefix to control access: * **All environments in an org:** match `org:/*` * **Environments from a project:** match `org:/prj:/*` * **A specific environment:** match the full `sub` value For V2-specific cloud provider setup, see the [V2 AWS guide](/docs/ona/integrations/aws). **Read more:** * [\[Auth0 docs\] OpenID Connect Protocol](https://auth0.com/authenticate/protocols/openid-connect-protocol) # Custom domain Source: https://ona.com/docs/ona/custom-domain Set up a custom domain for your Ona management plane with TLS termination Available on the Enterprise plan. [Contact sales](https://ona.com/contact/sales) to learn more. This guide walks you through setting up a custom domain for your Ona management plane, enabling you to access Ona services through your own domain name with TLS termination. ## Overview The setup involves two main steps: 1. **Register the custom domain** in your organization settings 2. **Configure cloud infrastructure** to route traffic to the Ona management plane You can choose between **AWS** or **GCP** for your infrastructure: * **AWS**: Uses VPC Endpoints and Network Load Balancer * **GCP**: Uses Private Service Connect (PSC) and regional HTTPS Load Balancer ## Prerequisites Before you begin, ensure you have: * Admin access to your Ona organization settings * **Single Sign-On (SSO) configured** - Custom domains require SSO to be set up. See the [SSO documentation](/docs/ona/sso/overview) for setup instructions. * A registered domain name (e.g., `ona.example.com`) * Browser access to `https://app.gitpod.io` to authenticate built-in integrations. If your network cannot allow this access, create a [custom organization MCP integration](/docs/ona/mcp#custom-organization-mcp-integrations) from your custom domain so its OAuth callback uses that domain. - An AWS account with appropriate permissions - An AWS Certificate Manager (ACM) certificate with Subject Alternative Names (SANs) covering **both**: * Main domain: `ona.example.com` * VSCode subdomain: `vscode.ona.example.com` * A GCP project with billing enabled * A VPC network and routable subnet (recommended /28 CIDR) * A regional proxy-only subnet in your VPC (required for regional HTTPS load balancers) * A regional SSL certificate (can be GCP-managed, but must be regional) * Terraform installed locally **About the VSCode subdomain:** The `vscode` subdomain (e.g., `vscode.ona.example.com`) serves a static VS Code Web application. This static content has no access to user data, source code, or any other resources unless the user is authenticated. Authentication is required before any user-specific data becomes accessible. ## Step 1: Register custom domain with Ona Register your custom domain name with the management plane through the Ona dashboard. 1. Navigate to **Settings** → **Login & Identity** → **Login Configuration** 2. Click **Set Up** in the Custom Domain section Organization settings Login Configuration page showing Custom Domain setup option ### Configure domain Select your cloud provider (AWS or GCP) and enter the required information: * **AWS Account ID**: The 12-digit AWS account ID where you will set up the infrastructure (Load Balancer, VPC Endpoint). Find this in the AWS Management Console under **My Account**. * **Domain name**: Your custom domain (e.g., `ona.example.com`). > Note: The AWS account ID you specify here must match the account where you create the VPC Endpoint. This is validated when requests come through your custom domain. AWS custom domain configuration form with fields for AWS Account ID and domain name * **GCP Project ID**: The GCP project ID where you will deploy the infrastructure. Find this in the GCP Console under **Project Info**. * **Domain name**: Your custom domain (e.g., `ona.example.com`). > Note: The GCP project ID you specify here must match the project where you create the PSC endpoint. This is validated when requests come through your custom domain. GCP custom domain configuration form with fields for GCP Project ID and domain name After registering your custom domain, you'll need to complete the cloud infrastructure setup below. **There is no automatic validation** - the configuration is verified only when requests are made through your custom domain. ## Step 2: Configure cloud infrastructure Choose your cloud provider and follow the corresponding setup instructions. Now that the domain is registered with Ona, you need to set up the AWS infrastructure to route traffic from your domain to the Ona management plane. #### 2.1 Prepare your certificate Ensure you have an AWS Certificate Manager (ACM) certificate that covers **both your custom domain and the VSCode subdomain**. This certificate will be used for TLS termination on the Load Balancer. Your certificate must include both domains as Subject Alternative Names (SANs): * `ona.example.com` * `vscode.ona.example.com` The certificate must be provisioned in the same AWS region where you'll create your Network Load Balancer. If your certificate doesn't cover the VSCode subdomain, VS Code Browser integration will fail with certificate errors. *** #### 2.2 Create security groups Create two separate security groups: one for the Network Load Balancer and another for the VPC endpoint. **Load Balancer security group** Create a security group with the following rules: * **Inbound**: HTTPS (443) from your desired source (e.g., your corporate network, internet). * **Outbound**: HTTPS (443) to the VPC Endpoint security group (to be created below). **VPC Endpoint security group** Create a security group with the following rules: * **Inbound**: HTTPS (443) from the Load Balancer security group (created above). * **Outbound**: All traffic (or as per your security requirements). Note the security group IDs for both; you'll need them for the following configuration. *** #### 2.3 Create VPC endpoint Create a VPC Endpoint to connect to the Ona management plane service. **Configuration** 1. **Navigate to VPC Console** → **Endpoints** → **Create Endpoint** 2. **Service Configuration**: * **Service category**: Select `Endpoint services that use NLBs and GWLBs`. * **Service name**: `com.amazonaws.vpce.us-east-1.vpce-svc-00fa18d41fdd25cad`. * Click **Verify service**. Create VPC Endpoint *Create VPC Endpoint* > ⚠️ Important: If you are in a region other than `us-east-1`, you must: > > * Enable **cross-region VPC endpoint**. > * Specify `us-east-1` as the service region. > * The VPC endpoint service is available in the following Availability Zone IDs: > > ``` > use1-az1 > use1-az2 > ``` > > Note: AWS maps Availability Zone names (e.g., `us-east-1a`, `us-east-1b`) differently per account, so the name shown in your console may vary. Use the **AZ ID** (e.g., `use1-az1`) to identify the correct zone. You can find the AZ ID mapping for your account in the **EC2 > Subnets** console or by running `aws ec2 describe-availability-zones --region us-east-1`. 3. **VPC and Subnets**: * Select the VPC and subnets where you want your VPC endpoint to be created. * Select at least 2 Availability Zones for high availability. VPC Endpoint Network Settings *VPC Endpoint Network Settings* 4. **Security Groups**: * Select the security group created earlier for the VPC endpoint. 5. **Create Endpoint** and wait for it to become **Available**. 6. **Note the Private IP Addresses**: * Once the VPC Endpoint is available, navigate to the **Subnets** tab. * Note down all the private IP addresses assigned to the endpoint (one per subnet/AZ). VPC Endpoint Private IPs *VPC Endpoint Private IPs* *** #### 2.4 Create target group Create a Target Group to route traffic from the Load Balancer to the VPC Endpoint. **Configuration** 1. **Navigate to EC2 Console** → **Target Groups** → **Create Target Group** 2. **Basic Configuration**: * **Target type**: IP addresses. * **Target group name**: Give it a descriptive name (e.g., `ona-vpce-targets`). * **Protocol**: TCP. * **Port**: 443. * **VPC**: Select the same VPC. Target Group Configuration *Target Group Configuration* 3. **Health Checks**: * **Protocol**: TCP. * Leave the default health check settings. 4. **Register Targets**: * Click **Next**. * Add each private IP address from the VPC Endpoint (noted in step 2.3). * **Port**: 443 for each IP. * Click **Include as pending below**. * Click **Create target group**. Register Target IPs *Register Target IPs* *** #### 2.5 Create Network Load Balancer Create a Network Load Balancer (NLB) to handle incoming traffic. **Configuration** 1. **Navigate to EC2 Console** → **Load Balancers** → **Create Load Balancer** 2. **Choose Load Balancer Type**: * Select **Network Load Balancer**. Choose Load Balancer Type *Choose Load Balancer Type* 3. **Configure Load Balancer**: * **Name**: Give it a descriptive name (e.g., `ona-custom-domain-lb`). * **Scheme**: Choose **Internal** or **Internet-facing** based on your access requirements. * **IP address type**: IPv4. * **VPC**: Select the VPC of your VPC endpoint. * **Availability Zones**: Select the same Availability Zones chosen for the VPC endpoint (must be at least 2). 4. **Select the Security Group**: Load Balancer Security Groups *Load Balancer Security Groups* * Select the security group created earlier for the load balancer. 5. **Configure Listener**: * **Protocol**: TLS. * **Port**: 443. * **Default action**: Forward to the target group created in step 2.4. * **Default SSL/TLS server certificate**: Select the ACM certificate you prepared. * ⚠️ **ALPN policy**: Select **HTTP/2 preferred** as the ALPN policy. This is important for optimal performance when connecting to the management plane. Listener Configuration *Listener Configuration* 6. **Create Load Balancer**. #### 2.6 Route runner API traffic privately If you create AWS runners from your custom domain, the runner connects back to the management plane URL it receives during setup, for example `https://ona.example.com/api`. The custom-domain path already goes through your Network Load Balancer. To keep runner API traffic private, use split-horizon DNS so the runner VPC resolves your custom domain to the private load-balancer endpoint instead of the public DNS record or external proxy path. Do not point `ona.example.com` directly at the custom-domain VPC endpoint. The AWS custom-domain endpoint expects traffic from your Network Load Balancer after TLS termination and Proxy Protocol v2 handling. A runner connects with HTTPS, so bypassing the load balancer would skip the certificate you manage in ACM and the request would not be handled correctly. Use one of these DNS patterns: * **Runner in the same VPC**: create a private DNS record for `ona.example.com` that aliases to the internal Network Load Balancer DNS name. * **Runner in a different VPC**: associate the private hosted zone with the runner VPC, or configure Route 53 Resolver forwarding so the runner VPC resolves `ona.example.com` to the internal Network Load Balancer DNS name. This keeps the same load-balancer and VPC endpoint architecture as user traffic, but makes runners reach it through private DNS and private routing. Ensure the runner subnets can route to the internal Network Load Balancer and that the load balancer security group allows HTTPS (443) from the runner security group or runner subnet CIDR. Now that the domain is registered with Ona, you need to set up the GCP infrastructure to route traffic from your domain to the Ona management plane using Private Service Connect (PSC). The GCP setup uses a Terraform module that creates: * A Private Service Connect (PSC) endpoint to connect to the Ona service * A regional HTTPS Load Balancer with TLS termination * A 300 second backend service timeout for long-running agent and editor streams * Automatic project ID header injection for authentication #### 2.1 Prepare your certificate Create a regional SSL certificate in GCP Certificate Manager. The certificate must be regional (not global) to work with the regional HTTPS load balancer. Your certificate must cover **both your custom domain and the VSCode subdomain**: * `ona.example.com` * `vscode.ona.example.com` ```bash theme={null} # Example: Create a GCP-managed regional certificate with both domains gcloud certificate-manager certificates create ona-custom-domain-cert \ --domains="ona.example.com,vscode.ona.example.com" \ --location=us-central1 ``` If your certificate doesn't cover the VSCode subdomain, VS Code Browser integration will fail with certificate errors. Note the full certificate resource ID, which follows this format: ``` projects/YOUR_PROJECT_ID/locations/REGION/certificates/CERT_NAME ``` *** #### 2.2 Prepare network prerequisites Ensure your VPC has the following: 1. **A routable subnet** with available IP addresses (recommended /28 CIDR minimum) 2. **A regional proxy-only subnet** - required for regional HTTPS load balancers To create a proxy-only subnet if you don't have one: ```bash theme={null} gcloud compute networks subnets create proxy-only-subnet \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-central1 \ --network=YOUR_VPC_NAME \ --range=10.129.0.0/23 ``` *** #### 2.3 Deploy with Terraform Use the Ona GCP Terraform module to deploy the infrastructure. The custom domain sub-module is available at: [gitpod-io/terraform-google-ona-runner](https://github.com/gitpod-io/terraform-google-ona-runner/tree/main/modules/custom-domain-client-infra) Use a module version that sets the regional backend service timeout to `300` seconds. If you manage equivalent load balancer resources outside the module, set the backend service timeout to at least `300` seconds so long-running agent and editor streams are not closed by the load balancer. **Configure authentication** ```bash theme={null} gcloud auth application-default login ``` **Create a Terraform configuration** Create a new directory for the custom domain configuration: ```bash theme={null} mkdir ona-custom-domain && cd ona-custom-domain ``` Create a `main.tf` that references the custom domain sub-module and wires variables through: ```hcl theme={null} # main.tf module "custom_domain" { source = "gitpod-io/ona-runner/google//modules/custom-domain-client-infra" version = "~> 1.0" project_id = var.project_id region = var.region vpc_network = var.vpc_network subnet_name = var.subnet_name domain_name = var.domain_name certificate_manager_cert_id = var.certificate_manager_cert_id load_balancer_type = var.load_balancer_type } ``` Create a `variables.tf`: ```hcl theme={null} # variables.tf variable "project_id" { type = string } variable "region" { type = string } variable "vpc_network" { type = string } variable "subnet_name" { type = string } variable "domain_name" { type = string } variable "certificate_manager_cert_id" { type = string } variable "load_balancer_type" { type = string } ``` Create a `terraform.tfvars` and fill in your values: ```hcl theme={null} # terraform.tfvars project_id = "your-gcp-project-id" region = "us-central1" # Network Configuration vpc_network = "default" subnet_name = "default" # Domain and SSL Configuration domain_name = "ona.example.com" certificate_manager_cert_id = "projects/your-gcp-project-id/locations/us-central1/certificates/ona-custom-domain-cert" # Load Balancer Type: "internal" (private) or "external" (public) load_balancer_type = "internal" ``` **Deploy the infrastructure** ```bash theme={null} terraform init terraform plan terraform apply ``` **Verify the deployment** ```bash theme={null} # Get the load balancer IP terraform output load_balancer_ip # Check PSC connection status gcloud compute forwarding-rules describe gitpod-custom-domain-psc \ --region=us-central1 \ --format="get(pscConnectionStatus)" ``` The PSC connection status should show `ACCEPTED` once the connection is established. *** ## Step 3: Configure DNS Point your custom domain to the Load Balancer. You need to create **two DNS records**: one for the main custom domain and one for the VSCode subdomain. 1. **Get Load Balancer DNS Name**: * In the Load Balancer details, copy the **DNS name**. Load Balancer DNS Name *Load Balancer DNS Name* 2. **Create DNS Records**: * In your DNS provider (Route 53, Cloudflare, etc.), create the following records: **Main custom domain record:** * **Name**: Your custom domain (e.g., `ona.example.com`). * **Type**: CNAME (or ALIAS if using Route 53). * **Value**: Load Balancer DNS name. **VSCode subdomain record:** * **Name**: `vscode.` prefix with your custom domain (e.g., `vscode.ona.example.com`). * **Type**: CNAME (or ALIAS if using Route 53). * **Value**: Load Balancer DNS name (same as above). > Note: Both DNS records must point to the same Load Balancer. The VSCode subdomain is required for VS Code Browser integration to work properly with your custom domain. If the Network Load Balancer is internal, create both records, including `vscode.ona.example.com`, in private DNS that is reachable from your users' networks and runner VPCs. Both records must resolve through the internal Network Load Balancer DNS name to its private IP addresses. Do not publish records that point users to an internal load balancer unless those users resolve DNS and route traffic from connected private networks. Create **two DNS records**: one for the main custom domain and one for the VSCode subdomain. Both records must point to the Load Balancer IP address. 1. **Get Load Balancer IP**: ```bash theme={null} terraform output load_balancer_ip ``` 2. **Create DNS Records**: * In your DNS provider, create the following A records: **Main custom domain record:** * **Name**: Your custom domain (e.g., `ona.example.com`). * **Type**: A. * **Value**: Load Balancer IP address. **VSCode subdomain record:** * **Name**: `vscode.` prefix with your custom domain (e.g., `vscode.ona.example.com`). * **Type**: A. * **Value**: Load Balancer IP address (same as above). **Example using Cloud DNS:** ```bash theme={null} gcloud dns record-sets create ona.example.com. \ --zone=your-dns-zone \ --type=A \ --ttl=300 \ --rrdatas="LOAD_BALANCER_IP" gcloud dns record-sets create vscode.ona.example.com. \ --zone=your-dns-zone \ --type=A \ --ttl=300 \ --rrdatas="LOAD_BALANCER_IP" ``` > Note: Both DNS records must point to the same Load Balancer IP address. The VSCode subdomain is required for VS Code Browser integration to work with your custom domain. If using an internal Load Balancer (`load_balancer_type = "internal"`), create both records in private DNS and point them to the Load Balancer's private IP address. Ensure your DNS is accessible from within your VPC or configure appropriate DNS forwarding. For external load balancers, use your public DNS provider. *** ## Step 4: Verify setup 1. Wait for DNS propagation (typically 5-15 minutes). 2. Access your custom domain in a browser: `https://ona.example.com`. 3. Verify that: * TLS certificate is valid. * You can reach the Ona management plane. * No certificate warnings appear. *** ## Step 5: Update your SSO configuration Update your SSO configuration to allow the new redirect URL using your custom domain: ``` https://ona.example.com/auth/oidc/callback ``` This step is **required** - authentication will fail without updating the SSO callback URL. See the [SSO documentation](/docs/ona/sso/overview) for provider-specific instructions. *** ## Step 6: Recreate your runner Recreate each runner from your custom domain. This is the recommended path because the runner API endpoint is written into the runner infrastructure during setup. 1. Open Ona from your custom domain, for example `https://ona.example.com`. 2. Create a new runner from **Settings** -> **Runners**. 3. Deploy the runner by following the setup guide for [AWS](/docs/ona/runners/aws/setup) or [GCP](/docs/ona/runners/gcp/setup). 4. Create new environments on the new runner. 5. After environments on the old runner are stopped or no longer needed, delete the old runner. Existing environments can only be accessed from the endpoint that created them. If an environment was created from `https://app.gitpod.io`, open it from `https://app.gitpod.io`. If it was created from your custom domain, open it from your custom domain. Mixing endpoints can cause editor, browser, and port connection issues. If Ona detects that you opened an environment from another domain, a warning at the top of the environment links to the domain that created it. ### Migrate your runner instead Migrate an existing runner only when you cannot recreate it. Migration changes the runner's management-plane API endpoint, but it does not move existing environments between endpoints. Existing environments must still be opened from the endpoint they were created from, which is why recreating the runner is recommended. Keep the runner ID unchanged when you migrate a runner. Update both the runner API endpoint and the runner token. The runner token includes the issuer for the endpoint that created it. If you update only the API endpoint, the runner can fail OIDC discovery with an issuer mismatch. Use the endpoint you are moving the runner to when creating the new runner token: * To move from `https://app.gitpod.io` to your custom domain, use `https://ona.example.com/api`. * To move back to the default domain, use `https://app.gitpod.io/api`. Create a new runner exchange token. Use a [personal access token](/docs/ona/integrations/personal-access-token) for an organization admin or another token with permission to administer runners. Create the personal access token from the same management-plane domain you are moving the runner to. When moving to your custom domain, do not use a personal access token created from `https://app.gitpod.io`. For example, open `https://ona.example.com/settings/personal-access-tokens` and use that token as `ONA_TOKEN` in the command below. ```bash theme={null} export API_ENDPOINT="https://ona.example.com/api" export RUNNER_ID="" read -rsp "Ona API token: " ONA_TOKEN; echo EXCHANGE_TOKEN="$( curl -fsS \ -H "Authorization: Bearer ${ONA_TOKEN}" \ -H "Content-Type: application/json" \ -H "Connect-Protocol-Version: 1" \ --data "{\"runnerId\":\"${RUNNER_ID}\"}" \ "${API_ENDPOINT}/gitpod.v1.RunnerService/CreateRunnerToken" \ | jq -er '.exchangeToken' )" ``` The exchange token is one-time use and expires after 24 hours. Creating a new exchange token does not expire previously issued runner tokens. Update the CloudFormation stack that manages the runner: 1. Open the runner's CloudFormation stack in the AWS Console. 2. Click **Update**. 3. Select **Use existing template** unless you are also upgrading the runner template. 4. In **Ona Configuration**, set **Ona API Endpoint** to the target endpoint, for example `https://ona.example.com/api`. 5. Set **Runner Token** to the `EXCHANGE_TOKEN` value from the command above. 6. Keep **Runner ID** unchanged. 7. Review the change set and complete the stack update. 8. Wait for the ECS services to stabilize, then verify the runner status from the target endpoint. If you automate the CloudFormation update, pass the current value for every unchanged parameter and update only `APIEndpoint` and `ExchangeToken`. Update the Terraform configuration and rotate the runner token secret: 1. In the runner Terraform directory, update `api_endpoint`: ```hcl theme={null} api_endpoint = "https://ona.example.com/api" ``` 2. Add a new Secret Manager version for the runner token. The GCP runner module creates the token secret as `-runner-token`, where `runner_name` is the Terraform variable you used for the runner. If you cannot use the `gcloud` CLI, add a new version to the same secret in the Google Cloud Console and use this JSON as the secret value: ```json theme={null} { "join_token": "", "created_by": "manual-migration" } ``` Replace `` with the `EXCHANGE_TOKEN` value from the command above. ```bash theme={null} export GCP_PROJECT="" export RUNNER_NAME="" export SECRET_NAME="${RUNNER_NAME}-runner-token" jq -nc --arg token "$EXCHANGE_TOKEN" \ '{join_token:$token, created_by:"manual-migration"}' \ | gcloud secrets versions add "$SECRET_NAME" \ --project="$GCP_PROJECT" \ --data-file=- ``` 3. Re-initialize Terraform and apply the endpoint change: ```bash theme={null} terraform init -upgrade terraform plan -out=tfplan terraform apply tfplan ``` 4. Review the plan before applying. The endpoint change should roll the runner and proxy instance templates or managed instance groups. 5. Verify the runner status from the target endpoint. Updating `runner_token` in `terraform.tfvars` alone is not enough for existing GCP runners, because the module ignores changes to the initial Secret Manager secret version after creation. *** ## Step 7: Enforce custom domain access (Optional) After completing the setup, you can optionally enable a policy to require all users to access Ona exclusively through your custom domain: 1. Navigate to **Settings** → **Login & Identity** → **Login Configuration**. 2. Enable **Enforce custom domain access**. When enabled: * All users, including organization admins, will be blocked from accessing via the default domain (`app.gitpod.io`). * This ensures all traffic goes through your controlled infrastructure. Users who are currently logged in with an active session can continue using the default domain until their session expires. The enforcement only applies to new login attempts. Before enabling this policy, verify that your custom domain setup is fully functional. *** ## Troubleshooting If you cannot connect to your custom domain: 1. Verify DNS propagation using `dig` or `nslookup`. 2. Check that the Load Balancer is in an **Active** state. 3. Verify the target group or backend service shows healthy targets. 4. Ensure security group rules (AWS) or firewall rules (GCP) allow traffic from your source. If you see certificate warnings: 1. Verify the ACM certificate covers **both** your main domain and the VSCode subdomain (`ona.example.com` and `vscode.ona.example.com`). 2. Check that the certificate is attached to the Load Balancer listener. 3. Ensure the certificate is valid and not expired. 4. If using VS Code Browser, verify the certificate includes both the main domain and the VSCode subdomain in its Subject Alternative Names (SANs). 1. Verify the Certificate Manager certificate covers your custom domain. 2. Ensure the certificate is regional (not global) and in the same region as your load balancer. 3. Check that the certificate is attached to the HTTPS proxy. 4. Verify the certificate status is `ACTIVE`: ```bash theme={null} gcloud certificate-manager certificates describe YOUR_CERT_NAME \ --location=REGION ``` If you experience slow connections: 1. Verify the ALPN policy is set to **HTTP/2 preferred** on the Load Balancer listener. 2. Check that you've selected at least 2 Availability Zones for high availability. 3. Verify the VPC Endpoint is in an **Available** state. 1. Check the backend service health status: ```bash theme={null} gcloud compute backend-services get-health ona-custom-domain-backend \ --region=REGION ``` 2. Verify the PSC endpoint is in an **ACCEPTED** state. 3. Verify the regional backend service timeout is at least `300` seconds: ```bash theme={null} gcloud compute backend-services describe ona-custom-domain-backend \ --region=REGION \ --format="value(timeoutSec)" ``` 4. If the timeout is lower than `300`, update it: ```bash theme={null} gcloud compute backend-services update ona-custom-domain-backend \ --region=REGION \ --timeout=300 ``` 5. Check load balancer logs for any errors. **AWS Account ID mismatch** If you see "AWS account ID mismatch" errors: 1. Verify the VPC Endpoint was created in the same AWS account registered in your custom domain settings. 2. Check the AWS account ID in **Settings** → **Login & Identity** → **Login Configuration** → **Domain & Access**. 3. If the account ID is incorrect, edit the custom domain configuration to update it. **VPC Endpoint connection issues** If you see "Failed to resolve VPC Endpoint ID" errors: 1. Verify the VPC Endpoint is connected to the Ona VPC Endpoint Service. 2. Check that **Proxy Protocol v2** is enabled on the Network Load Balancer target group. 3. Ensure the VPC Endpoint is in an **Available** state. 4. Verify the target group shows healthy targets. **PSC connection not accepted** If the PSC connection status is not `ACCEPTED`: 1. Check that your GCP project ID matches what was registered in the custom domain settings. 2. Contact [Ona support](https://ona.com/support) or reach out to your account executive to verify the service attachment is configured to accept connections from your project. **GCP Project ID mismatch** If you see "GCP project ID mismatch" errors: 1. Verify the infrastructure was deployed in the same GCP project registered in your custom domain settings. 2. Check the GCP project ID in **Settings** → **Login & Identity** → **Login Configuration** → **Domain & Access**. 3. The `X-Gitpod-GCP-ID` header is automatically injected by the load balancer - ensure the Terraform configuration uses the correct `project_id` variable. **Proxy-only subnet issues** If the load balancer fails to create: 1. Verify you have a regional proxy-only subnet in your VPC: ```bash theme={null} gcloud compute networks subnets list \ --filter="purpose=REGIONAL_MANAGED_PROXY" \ --regions=REGION ``` 2. If missing, create one as described in the prerequisites. For additional support, Enterprise customers can reach out to your account manager. # Veto - Datawall Source: https://ona.com/docs/ona/guardrails/datawall Detect confidential data leaving Ona environments over the network using kernel-level fingerprinting. Datawall is not yet available. It will require an [Enterprise plan](https://ona.com/pricing). This page describes planned functionality. Datawall is a Veto control for detecting confidential data leaving an Ona environment over the network. It runs below the agent, at the kernel level, so the process attempting the transfer cannot disable or inspect the mechanism that is evaluating it. ## When to use Datawall Use Datawall when you want stronger protections around code, credentials, tickets, prompts, or other sensitive material that enters an environment and should not leave it unchecked. Typical use cases: * environments handling confidential repositories or internal documentation * agents reading tickets, MCP responses, or secrets that should not be copied out * teams that need an explicit exfiltration control in addition to identity, policy, and audit logs ## How Datawall works When confidential data enters the environment, Ona registers that material for monitoring. The kernel fingerprints it and compares outbound network traffic against those fingerprints. This is designed to catch transfers across common network paths, including: * HTTP and HTTPS * SSH-based traffic such as `git push` and `scp` * traffic relayed through helper processes * common encoding transforms such as base64, hex, and URL encoding ## What Datawall detects well | Scenario | Detected | | ----------------------------------------------------------- | -------- | | Agent sends data verbatim over HTTP or HTTPS | Yes | | Agent encodes data before sending | Yes | | Agent relays data through a child process | Yes | | Agent writes data to disk and another process sends it | Yes | | Agent sends data over SSH | Yes | | Agent encrypts data at the application layer before sending | Yes | | Agent splits data across multiple requests | Partial | | Agent paraphrases or rewrites the data | No | ## Operating and investigating Every detection produces a structured event that is written to environment logs and reported to the management plane. Review the event to understand: * which action triggered the match * where the traffic was going * which process attempted the transfer * when the detection occurred ## Related pages * [Veto overview](/docs/ona/guardrails/veto) * [Executable deny list](/docs/ona/organizations/policies/executable-deny-list) * [Guardrails overview](/docs/ona/guardrails/overview) # Guardrails Source: https://ona.com/docs/ona/guardrails/overview Understand the identity, policy, enforcement, and audit controls that govern Ona environments and agents.
1 0 3 f a 1 0 b 9 c 2 e 7 0 d a 5 1 0 d 7 e 2 8 1 f 3 0 b 4 0 1 c 6 0 1 b 3 f 0 a 9 d 1 7 7 e 0 1 a 4 1 0 d 9 5 0 c 8 1 1 0 8 b 3 0 1 f 5 0 e 6 a 0 2 d 1 0 9 c 6 0 a 1 e 0 b 3 7 f 0 4 1 f 0 1 7 b 0 2 d 8 1 c 5 3 0 1 a e 0 1 d 8 0 4 f 6 0 9 1 b 0 5 1 0 c 9 0 f 7 1 a 3 e 6 0 1 0 7 a 4 0 1 e b 2 0 d 8 0 d 1 3 0 b 1 0 f 8 c 5 9 1 a 9 1 0 c 5 0 1 a 2 0 3 e 7 f 6 0 1 e 0 8 d 0 1 b 4 a 0 2 5 c 5 a 0 7 1 f 3 0 e 6 1 d 0 b 8 b 0 2 e 9 1 0 c 4 0 f 7 a 1 3 0 f 8 1 0 b 6 d 0 3 1 a 5 c 0 4 1 0 d a 0 9 1 7 e 0 2 b 0 f 1 c 3 0 f 8 0 5 1 a d 0 e 6 1 e 0 7 b 1 0 a 4 c 0 8 1 0 9 d 0 8 1 4 d 0 e 1 0 b 6 f 3 a 0
Introducing Veto
Kernel-level enforcement engine for AI agents. Block unauthorized executables and detect confidential data exfiltration — all enforced below the agent's reach.
Guardrails are the controls that let teams adopt Ona without giving up administrative or security oversight. They span identity, organization policy, kernel-level enforcement, and auditability. Use this section when you are answering questions like: * who can access Ona and how they sign in * what environments and agents are allowed to do * which defaults apply across the organization * how to investigate or explain agent behavior later ## What guardrails cover Ona uses several layers of control: | Layer | What it controls | Start here | | ------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | Identity | Who can sign in and what access model you use | [SSO](/docs/ona/sso/overview), [SCIM](/docs/ona/scim/overview), [OIDC](/docs/ona/configuration/oidc) | | Policy | Which defaults, limits, and restrictions apply across the organization | [Organization policies](/docs/ona/organizations/policies/overview) | | Runtime enforcement | What can execute and what data can leave an environment | [Veto](/docs/ona/guardrails/veto), [Command deny list](/docs/ona/command-deny-list) | | Auditability | What happened, when, and under which identity | [Audit logs](/docs/ona/audit-logs/overview) | ## How to roll guardrails out Most teams do not turn on every control at once. A practical rollout usually looks like this: 1. Connect [identity](/docs/ona/sso/overview) so access is tied to your existing org model. 2. Apply a small set of [organization policies](/docs/ona/organizations/policies/overview) for environment limits, lifecycle, and standardization. 3. Add runtime controls where you have clear risk boundaries: * [command deny list](/docs/ona/command-deny-list) for broad command restrictions * [Veto executable deny list](/docs/ona/organizations/policies/executable-deny-list) for kernel-level executable blocking * [Datawall](/docs/ona/guardrails/datawall) for confidential data leaving the environment (coming soon) 4. Review [audit logs](/docs/ona/audit-logs/overview) as part of rollout so admins know how to inspect outcomes and policy changes. ## Which controls to choose first Start with the control that matches the risk you are trying to reduce: * **Access and provisioning risk**: start with [SSO](/docs/ona/sso/overview), [SCIM](/docs/ona/scim/overview), and [organization roles](/docs/ona/organizations/organization-roles) * **Resource sprawl or inconsistent setups**: start with [organization policies](/docs/ona/organizations/policies/overview) * **Risky commands or binaries**: start with [command deny list](/docs/ona/command-deny-list) or [Veto executable deny list](/docs/ona/organizations/policies/executable-deny-list) * **Source code or credential exfiltration concerns**: review [Veto](/docs/ona/guardrails/veto) and [Datawall](/docs/ona/guardrails/datawall) (coming soon) * **Compliance and post-incident review**: start with [audit logs](/docs/ona/audit-logs/overview) ## Related pages * [Veto overview](/docs/ona/guardrails/veto) * [Organization policies](/docs/ona/organizations/policies/overview) * [Identity](/docs/ona/sso/overview) * [Audit logs](/docs/ona/audit-logs/overview) # Veto Source: https://ona.com/docs/ona/guardrails/veto Kernel-level enforcement engine that protects AI agent environments from unauthorized execution and data exfiltration. Veto is Ona's kernel-level enforcement engine for AI agents. It runs as a Linux Security Module (LSM) inside the environment kernel, below the agent, below userspace. The LLM cannot bypass or disable it. AI agents reason about security boundaries and work around them. Traditional runtime security operates above the agent, making it observable and evadable. Veto moves enforcement below the agent's reach. ## Capabilities ## Kernel-level enforcement When enforcement operates above the agent, the agent can discover and circumvent it. Path-based deny lists fall to renamed binaries. Userspace sandboxes can be disabled. Proxy-based DLP is avoided by encoding data differently. Veto enforces at the syscall level. The agent cannot unload the LSM, modify its configuration, or observe whether an action was flagged. The kernel is the last trust boundary before hardware. ## Watch: Claude Code vs. Veto Leonardo walks through how Claude Code bypasses traditional guardrails and how Veto enforces controls from inside the kernel.