Skip to content

feat: AI Agents - #1025

Draft
nimish-ks wants to merge 90 commits into
mainfrom
feat--agents
Draft

nimish-ks wants to merge 90 commits into
mainfrom
feat--agents

Conversation

@nimish-ks

Copy link
Copy Markdown
Member

Summary

Adds Agents: AI coding agents (Claude Code, Codex, Cursor, and others) can use an organisation's Integration Credentials through the Phase CLI proxy without ever seeing the real secrets. The agent is handed decoy values; the proxy swaps in the real credential on the way out and reports what it did back to the console.

This PR is the console side: data model, APIs, access control and UI. AWS and PostgreSQL are the first supported services.

Backend

  • Data model: 11 new models and migration 0141_agents: Agent, AgentWorkflow, AgentMembership, AgentWorkflowMembership, AgentConnection, AgentWorkflowGrant, AgentToken, AgentSession, AgentDecoy, AgentRequest, AgentEvent. It also adds ProviderCredentials.revision (backfilled per row) and three audit-log resource types.
  • Service registry (api/utils/agent_config): JSON definitions for AWS and PostgreSQL. Each definition is validated when the module loads, and the registry publishes the capabilities a CLI must support.
  • Runtime REST API (/v1/agents/) for the CLI proxy:
    • sessions: open, refresh, discover, rotate, revoke
    • service capabilities and agent context
    • proxy activity events
    • Agent requests, where an agent asks a human to set up or replace a credential
    • Agent tokens
  • GraphQL management API for the console: Agents, Workflows, members, Connections, grants, tokens, sessions, requests and the activity log.
  • Access control:
    • Roles gain an agent_permissions section.
    • Agent tokens are scoped to one Workflow.
    • Network access policies apply to Agent tokens.
    • Org SSO enforcement covers Agent operations.
    • Agent endpoints are rate limited.
  • Offboarding: removing, deactivating (SCIM) or deleting a member revokes the Agent tokens and sessions they created.
  • Audit log: Agent, Connection and request management actions are logged.

Integration credentials

  • Sealed secrets. Secret fields are write-only: the API returns only non-sensitive fields (hosts, IDs, regions) and the names of stored secrets. Leaving a secret blank on edit keeps it.
  • Moving a secret requires re-entering it. Changing a field that decides where a secret is sent (such as a Postgres host or Vault address) requires re-entering the secret.
  • AWS External ID: the edit form offers Generate/Regenerate with Copy, since the stored value can't be shown.
  • New PostgreSQL credential type, used by Agents.
  • Update rules:
    • An edit is rejected if the credential changed since the form loaded.
    • Names are capped at 64 characters.
    • PostgreSQL fields are validated.
    • PostgreSQL Agent Connections follow their credential's host, port and database.
    • Running Agent sessions refresh so rotated secrets reach them.
    • A credential used by an Agent Connection can't be deleted.

Frontend

  • Agents section: overview, Agents, Connections and Requests tabs. Each Agent has a page with tabs for Workflows, Sessions, Logs, Tokens and Members.
  • Integrations page moved: /[team]/integrations/credentials is now /[team]/integrations, and the tab is renamed "Integrations". A temporary redirect keeps old links working, including query strings.
  • Credential editor with sealed fields.
  • Role editor: new Agent permissions section.

Reviewer notes

Agents

  • Own permission section. Roles now have three maps: organisation (permissions), app (app_permissions) and agent (agent_permissions). Agents, AgentConnections and AgentRequests are organisation-level. AgentWorkflows, AgentMemberships, AgentTokens and AgentSessions are agent-level, which leaves room for team-owned Agents later. See permission_key_for in api/utils/access/roles.py.
  • Roles stay backwards compatible. agent_permissions is optional when creating or updating a role, so existing API clients keep working. A custom role without it grants nothing within Agents. Managed roles come from the Python templates, so no data migration is needed; their meta.version was bumped.
  • Starting an Agent runtime requires AgentSessions: create plus assignment to that Workflow; Owner and Admin don't need the assignment. Both are re-checked each time credentials are handed to a running session. There is no separate execute permission.
  • Network access policies. Agent REST endpoints use the same IsIPAllowed check as the rest of the API. The only change is that Agent tokens now resolve to their organisation (3 lines in api/utils/access/middleware.py, with a test).
  • Open-source code, not ee/:
    • REST: api/views/agents/
    • GraphQL: backend/graphene/agents/
    • Service definitions: api/utils/agent_config/services/v1/*.json
  • _same_text_id() in api/models.py backs the checks that related Agent rows belong to the same organisation or Workflow. IDs are TextField(default=uuid4), so an unsaved object's id is a UUID while a loaded one is a str, and plain == would say they differ.
  • Activity events are scrubbed by the CLI before they are sent. The console validates their shape and size but doesn't scrub them again.

Integration credentials

  • Sealed-field lists. Each provider in api/services.py lists its non_sensitive_credentials (shown and editable) and endpoint_credentials (fields that decide where the secret is sent). Every other field is sealed. The frontend reads the same lists from the API (utils/syncing/general.ts).
  • PostgreSQL Connections copy their endpoint from the credential. Editing a credential that Connections use updates those Connections in the same save, with a new host-rule version, and refreshes their sessions.

Integrations page

  • Old links redirect. The redirect lives in frontend/next.config.js. The docs still use the old "Third-party credentials" wording; update them, then remove the redirect.

@nimish-ks
nimish-ks marked this pull request as draft September 20, 2026 09:38
Loads the Agent service definitions in api/utils/agent_config/services/v1
(AWS and PostgreSQL), validates each one when the module is imported,
fills in defaults, and publishes the capabilities the CLI negotiates
against when a session opens.
Secret fields of an Integration Credential are now write-only. The API
returns only the non-sensitive fields (hosts, IDs, regions) plus the names
of the stored secrets; leaving a secret blank on edit keeps the stored
value. Changing a field that decides where a secret is sent (for example a
Postgres host or Vault address) requires re-entering the secret. The AWS
External ID gets a Generate/Regenerate action with copy, since the stored
value can no longer be shown.

Credential updates also check the revision the editor started from, cap
the name at 64 characters, validate PostgreSQL fields, move PostgreSQL
Agent Connections along with their credential, and refresh live Agent
sessions so rotated secrets reach running agents. A credential used by an
Agent Connection can't be deleted.
REST API under /v1/agents/ used by the Phase CLI proxy: open, refresh,
discover, rotate and revoke sessions, service capabilities and context,
proxy activity events, and Agent requests (asking a human to set up or
replace a credential). GraphQL queries and mutations back the console:
Agents, Workflows, memberships, Connections, grants, tokens, sessions,
requests and the activity log.

Both live in the open-source tree (api/views/agents, backend/graphene/agents).
Sessions last an hour per refresh and at most a day.
The GraphQL SSO middleware finds the organisation from resolver arguments.
It now recognises the Agent argument names, Agent session UIDs and Agent
tokens, so Agent operations are held to the organisation's SSO
requirement. A test fails if any Agent mutation takes no argument that
resolves to an organisation.
Removing a member through the REST API, deactivating them through SCIM, or
deleting their account now revokes the Agent tokens and sessions they
created and their Agent memberships. Members are still soft-deleted.
Every permission section offers the same read/create/update/delete
columns, so PermissionSection owns that list instead of each dialog
passing it in.
ProviderCredentialCard has no importers since the integrations page moved
to the credentials table, and asyncDraftGuard's test outlived its module.
Tests that touch the database (the Agent and sealed-credential tests) need
Postgres. The test job now starts a Postgres service container, the same
image as the dev compose, which GitHub discards when the job ends. Mocked
tests are unaffected, and every migration is applied on each run.
Creating the test database runs migrate, and its post_migrate hook
schedules the licence checker as an RQ job, which needs a Redis-compatible
server. The test job now starts Valkey 7.2, the release that forked from
the Redis 7.2 the compose files run. The Django cache stays in memory.
The server keypair is derived from SERVER_SECRET as hex. conftest set it
twice with setdefault, so the first, non-hex value won and the valid
64-character default further down never applied. The database-backed
Agent and credential tests are the first to derive the real keypair; the
dev env supplies a real secret, which hid this locally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant