Argo CD — API Surface#

API types#

REST (grpc-gateway), gRPC, CLI (Cobra), WebSocket (terminal), Webhook (inbound), Plugin/Extension (proxy + CMP sidecar)


gRPC API#

Proto files#

All proto files live under server/<service>/, with generated client stubs in pkg/apiclient/<service>/:

Proto fileDomain
server/application/application.protoApplication lifecycle
server/applicationset/applicationset.protoApplicationSet factory
server/cluster/cluster.protoManaged clusters
server/project/project.protoAppProject (RBAC boundary)
server/repository/repository.protoGit/Helm/OCI repos
server/repocreds/repocreds.protoCredential templates
server/session/session.protoAuth sessions
server/account/account.protoUsers + API tokens
server/settings/settings.protoArgo CD configuration
server/certificate/certificate.protoTLS certs + SSH known hosts
server/gpgkey/gpgkey.protoGnuPG keys
server/notification/notification.protoNotification introspection
server/version/version.protoVersion info
reposerver/repository/repository.protoInternal: manifest rendering
cmpserver/plugin/plugin.protoInternal: CMP sidecar protocol
commitserver/commit/commit.protoInternal: GitOps hydration write-back

External services (registered in server/server.go)#

All 13 public services are registered with both gRPC and grpc-gateway (REST):

// server/server.go:986-998
versionpkg.RegisterVersionServiceServer(grpcS, ...)
clusterpkg.RegisterClusterServiceServer(grpcS, ...)
applicationpkg.RegisterApplicationServiceServer(grpcS, ...)
applicationsetpkg.RegisterApplicationSetServiceServer(grpcS, ...)
notificationpkg.RegisterNotificationServiceServer(grpcS, ...)
repositorypkg.RegisterRepositoryServiceServer(grpcS, ...)
repocredspkg.RegisterRepoCredsServiceServer(grpcS, ...)
sessionpkg.RegisterSessionServiceServer(grpcS, ...)
settingspkg.RegisterSettingsServiceServer(grpcS, ...)
projectpkg.RegisterProjectServiceServer(grpcS, ...)
accountpkg.RegisterAccountServiceServer(grpcS, ...)
certificatepkg.RegisterCertificateServiceServer(grpcS, ...)
gpgkeypkg.RegisterGPGKeyServiceServer(grpcS, ...)

Key RPCs by service#

ApplicationService (the richest service — ~25 RPCs):

  • List, Watch — stream application events
  • Create, Get, Update, UpdateSpec, Patch, Delete
  • Sync, Rollback, TerminateOperation
  • GetManifests, GetManifestsWithFiles (streaming upload)
  • ManagedResources, ResourceTree, WatchResourceTree (streaming)
  • ServerSideDiff — compute diff without applying
  • GetResource, PatchResource, DeleteResource — sub-resource ops
  • ListResourceActions, RunResourceAction, RunResourceActionV2
  • PodLogs (streaming), ListLinks, ListResourceLinks
  • RevisionMetadata, RevisionChartDetails, GetOCIMetadata

ProjectService:

  • Create, List, Get, GetDetailedProject, GetGlobalProjects, Update, Delete
  • CreateToken, DeleteToken — project-scoped API tokens
  • GetSyncWindowsState, ListEvents, ListLinks

ClusterService:

  • List, Create, Get, Update, Delete, RotateAuth, InvalidateCache

RepositoryService (large — includes write-repo variants):

  • List, Get, GetWrite, ListRepositories, ListWriteRepositories
  • Create, CreateRepository, CreateWriteRepository, Update, UpdateRepository, UpdateWriteRepository
  • Delete, DeleteRepository, DeleteWriteRepository
  • ValidateAccess, ValidateWriteAccess
  • ListRefs, ListOCITags, ListApps, GetAppDetails, GetHelmCharts

SessionService: Create (login), Delete (logout), GetUserInfo

AccountService: CanI, UpdatePassword, ListAccounts, GetAccount, CreateToken, DeleteToken

NotificationService: ListTriggers, ListServices, ListTemplates

Internal services (not exposed externally)#

RepoServerService (reposerver/repository/repository.proto):

  • GenerateManifest, GenerateManifestWithFiles, TestRepository, ResolveRevision
  • ListRefs, ListOCITags, ListApps, ListPlugins
  • GetAppDetails, GetRevisionMetadata, GetOCIMetadata, GetRevisionChartDetails
  • GetHelmCharts, GetGitFiles, GetGitDirectories
  • UpdateRevisionForPaths — cache invalidation

CMPService (cmpserver/plugin/plugin.proto):

  • GenerateManifest (streaming upload + response)
  • CheckPluginConfiguration, MatchRepository, GetParametersAnnouncement

CommitService (commitserver/commit/commit.proto):

  • CommitHydratedManifests — write resolved manifests back to Git (hydration mode)

Interceptors#

Unary chain (server/server.go:967-979):

bug21955Workaround → logging → prometheus metrics → JWT auth (grpc_auth)
→ user-agent version check → payload logging (sensitive methods excluded)
→ k8s error code normalization → git error code normalization → recovery (panic)

Stream chain (same set minus the workaround):

logging → prometheus metrics → JWT auth → user-agent check
→ payload logging → k8s error code → git error code → recovery

OTel tracing is added via grpc.StatsHandler(otelgrpc.NewServerHandler()).


REST / HTTP API#

grpc-gateway transcodes all 13 gRPC services to REST at /api/.... URL patterns follow the proto google.api.http options (e.g., GET /api/v1/applications, POST /api/v1/applications/{name}/sync).

Additional HTTP-only endpoints (registered in newHTTPServer, server/server.go:1167):

PathPurpose
/api/webhookGit event webhook receiver (GitHub, GitLab, Bitbucket, Bitbucket Server)
/api/badgeApplication status badge image
/terminalWebSocket exec terminal (auth-gated, feature-flag-gated)
/logoutSession logout (cookie clearing)
/swagger-uiSwagger UI served from embedded JSON
/healthzHTTP health check
/downloadCLI binary downloads
/extensions.jsUI extensions JavaScript bundle
/extensions/<name>/*Proxy extension forwarding (alpha, opt-in)
/dex/..., /auth, /callbackDex OIDC reverse-proxy and OAuth2 callbacks
/React SPA static assets

Authentication (HTTP layer):

  • gRPC requests: JWT Bearer token validated in grpc_auth.UnaryServerInterceptorserver.Authenticate()
  • HTTP terminal/extensions: util/session.WithAuthMiddleware wraps the handler
  • Dex SSO: Dex is a reverse-proxied sidecar; OAuth2 flow ends at /callback which issues a JWT

Transport multiplexing (cmux):

TCP listener
  ├── HTTP1 (PATCH) → HTTP server
  ├── HTTP2 grpc content-type → gRPC server
  └── (TLS mode) TLS listener via tlsm sub-mux

Browser gRPC clients use grpc-web+proto content type, routed to grpcWebHandler.


CLI#

Framework#

Cobra (github.com/spf13/cobra). Entry point: cmd/argocd/commands/root.go.

Command structure#

argocd
├── login SERVER
├── logout
├── relogin
├── context [CONTEXT]
├── app                          # Application management
│   ├── create, get, set, unset
│   ├── diff, sync, wait
│   ├── list, delete, edit, patch
│   ├── logs, manifests, history
│   ├── rollback, terminate-op
│   ├── add-source, remove-source
│   ├── confirm-deletion
│   └── actions list|run
├── appset                       # ApplicationSet management
│   ├── get, create, generate
│   ├── list, delete
│   └── (watch via Watch RPC)
├── proj                         # Project management
│   ├── create, set, get, delete, list, edit
│   ├── add-source/destination, remove-source/destination
│   ├── allow/deny-cluster-resource
│   ├── role (create, delete, list, get, add-policy, remove-policy, create-token, delete-token)
│   └── windows (add, delete, update, list, enable-manual-sync, disable-manual-sync)
├── cluster
│   ├── add, set, get, rm, list, rotate-auth
├── repo
│   ├── add, set, get, rm, list
├── repocreds
│   ├── add, rm, list
├── cert
│   ├── add-tls, add-ssh, rm, list
├── gpg
│   ├── list, get, add, rm
├── account
│   ├── update-password, get-user-info, can-i
│   ├── list, get, generate-token, delete-token, session-token
├── version
├── completion SHELL
├── plugin
├── bcrypt
└── admin                        # Administrative (direct Kubernetes access, no API server)
    ├── cluster shards|namespaces|stats|kubeconfig|generate-spec|enable-namespaced-mode|disable-namespaced-mode
    ├── proj generate-spec|update-role-policy
    ├── repo generate-spec
    ├── app generate-spec|diff-reconcile-results|get-reconcile-results
    ├── settings validate|resource-overrides (ignore-differences|ignore-resource-updates|health|list-actions|run-action)
    ├── rbac can|validate
    ├── export / import           # Backup/restore all Argo CD resources
    ├── initial-password
    ├── redis-initial-password
    ├── dashboard
    └── generate-allow-list

Flag patterns#

  • Global flags: --server, --auth-token, --insecure, --config (argocd config file path)
  • Persistent flags defined on app, proj, cluster, etc. sub-commands
  • Environment variable overrides: ARGOCD_SERVER, ARGOCD_AUTH_TOKEN, ARGOCD_OPTS
  • admin commands bypass the API server and connect directly to Kubernetes — they accept --kubeconfig / --context / --namespace flags

Plugin / Extension system#

Config Management Plugins (CMP)#

  • Mechanism: Sidecar container alongside repo-server; communicates via Unix domain socket gRPC (cmpserver/plugin/plugin.proto)
  • Discovery: plugin.yaml in the sidecar filesystem; repo server calls MatchRepository to test compatibility, then GenerateManifest to render
  • Extension points: Arbitrary shell commands in generate and discover stanzas of plugin.yaml; environment variables and file injection provided by repo-server
  • Examples: Helm wrappers, kpt, jsonnet custom scripts, any command-line tool

Proxy Extensions (alpha)#

  • Mechanism: Configured in argocd-cm ConfigMap under extensions; API server acts as an authenticated reverse proxy
  • Extension points: External HTTP services registered by name; accessible at /extensions/<name>/...
  • Auth: Requests must pass Argo CD auth; the extension manager (server/extension/extension.go) enforces this before forwarding
  • Status: Alpha, disabled by default (--enable-proxy-extension flag)

UI Extensions#

  • Mechanism: JavaScript bundles placed in /tmp/extensions/ in the API server pod
  • Served at: /extensions.js — merged into the React SPA at load time
  • Extension points: React component injection points in the UI (defined by the UI extension API)

Library API#

Argo CD is not designed as a library, but several packages are effectively used as one:

  • pkg/apiclient/ — Public generated gRPC client stubs for all services; used by the CLI and automation tooling (e.g., Argo Workflows, CI pipelines). Stable API: versioned proto definitions
  • gitops-engine/pkg/ — Re-exported sub-module: cache, diff, health, sync. Used by forks and related tools (Flux experimented with it). The module is embedded but retains its own import path
  • util/db — Kubernetes-as-database layer; could be used by other CNCF tools that need the same storage model
  • util/settings — Settings manager (reads argocd-cm/argocd-secret); used in admin CLI without API server

API style: Generated protobuf structs + service interfaces. No fluent or functional-options style — all request types are protobuf-generated structs.

Backward compatibility: Proto files use google.api.http option annotations; gRPC reflection is registered (reflection.Register(grpcS)). No explicit versioning beyond the module path (github.com/argoproj/argo-cd/v3). Breaking changes are managed via the Argo CD release cycle, not semantic versioning of sub-packages.


Notable API surface observations#

  1. Dual-protocol by default — Every gRPC service has a REST equivalent via grpc-gateway, with no separate REST implementation. This means the CLI, Web UI, and REST consumers all use the same code path.

  2. ApplicationService is disproportionately large — ~25 RPCs in a single service covering CRUD, sync, rollback, streaming logs, resource tree watching, sub-resource operations. By Interface Segregation Principle standards this is too broad, but it collocates all application operations for RBAC purposes (one Casbin resource: applications).

  3. Streaming is used selectively — Server-streaming for Watch, WatchResourceTree, PodLogs; client-streaming for GetManifestsWithFiles and CMP GenerateManifest (large file upload). Bidirectional streaming is not used.

  4. Admin CLI bypasses the API — The admin sub-commands connect directly to Kubernetes, enabling disaster recovery without a running API server. This is a deliberate two-tier CLI design.

  5. Webhook receiver is not a separate service — The /api/webhook endpoint lives inside the API server rather than in a dedicated ingress controller, which means Git providers need direct HTTPS access to the Argo CD server.