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 file | Domain |
|---|---|
server/application/application.proto | Application lifecycle |
server/applicationset/applicationset.proto | ApplicationSet factory |
server/cluster/cluster.proto | Managed clusters |
server/project/project.proto | AppProject (RBAC boundary) |
server/repository/repository.proto | Git/Helm/OCI repos |
server/repocreds/repocreds.proto | Credential templates |
server/session/session.proto | Auth sessions |
server/account/account.proto | Users + API tokens |
server/settings/settings.proto | Argo CD configuration |
server/certificate/certificate.proto | TLS certs + SSH known hosts |
server/gpgkey/gpgkey.proto | GnuPG keys |
server/notification/notification.proto | Notification introspection |
server/version/version.proto | Version info |
reposerver/repository/repository.proto | Internal: manifest rendering |
cmpserver/plugin/plugin.proto | Internal: CMP sidecar protocol |
commitserver/commit/commit.proto | Internal: 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 eventsCreate,Get,Update,UpdateSpec,Patch,DeleteSync,Rollback,TerminateOperationGetManifests,GetManifestsWithFiles(streaming upload)ManagedResources,ResourceTree,WatchResourceTree(streaming)ServerSideDiff— compute diff without applyingGetResource,PatchResource,DeleteResource— sub-resource opsListResourceActions,RunResourceAction,RunResourceActionV2PodLogs(streaming),ListLinks,ListResourceLinksRevisionMetadata,RevisionChartDetails,GetOCIMetadata
ProjectService:
Create,List,Get,GetDetailedProject,GetGlobalProjects,Update,DeleteCreateToken,DeleteToken— project-scoped API tokensGetSyncWindowsState,ListEvents,ListLinks
ClusterService:
List,Create,Get,Update,Delete,RotateAuth,InvalidateCache
RepositoryService (large — includes write-repo variants):
List,Get,GetWrite,ListRepositories,ListWriteRepositoriesCreate,CreateRepository,CreateWriteRepository,Update,UpdateRepository,UpdateWriteRepositoryDelete,DeleteRepository,DeleteWriteRepositoryValidateAccess,ValidateWriteAccessListRefs,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,ResolveRevisionListRefs,ListOCITags,ListApps,ListPluginsGetAppDetails,GetRevisionMetadata,GetOCIMetadata,GetRevisionChartDetailsGetHelmCharts,GetGitFiles,GetGitDirectoriesUpdateRevisionForPaths— 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 → recoveryOTel 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):
| Path | Purpose |
|---|---|
/api/webhook | Git event webhook receiver (GitHub, GitLab, Bitbucket, Bitbucket Server) |
/api/badge | Application status badge image |
/terminal | WebSocket exec terminal (auth-gated, feature-flag-gated) |
/logout | Session logout (cookie clearing) |
/swagger-ui | Swagger UI served from embedded JSON |
/healthz | HTTP health check |
/download | CLI binary downloads |
/extensions.js | UI extensions JavaScript bundle |
/extensions/<name>/* | Proxy extension forwarding (alpha, opt-in) |
/dex/..., /auth, /callback | Dex OIDC reverse-proxy and OAuth2 callbacks |
/ | React SPA static assets |
Authentication (HTTP layer):
- gRPC requests: JWT Bearer token validated in
grpc_auth.UnaryServerInterceptor→server.Authenticate() - HTTP terminal/extensions:
util/session.WithAuthMiddlewarewraps the handler - Dex SSO: Dex is a reverse-proxied sidecar; OAuth2 flow ends at
/callbackwhich 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-muxBrowser 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-listFlag 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 admincommands bypass the API server and connect directly to Kubernetes — they accept--kubeconfig/--context/--namespaceflags
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.yamlin the sidecar filesystem; repo server callsMatchRepositoryto test compatibility, thenGenerateManifestto render - Extension points: Arbitrary shell commands in
generateanddiscoverstanzas ofplugin.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-cmConfigMap underextensions; 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-extensionflag)
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 definitionsgitops-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 pathutil/db— Kubernetes-as-database layer; could be used by other CNCF tools that need the same storage modelutil/settings— Settings manager (readsargocd-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#
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.
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).Streaming is used selectively — Server-streaming for
Watch,WatchResourceTree,PodLogs; client-streaming forGetManifestsWithFilesand CMPGenerateManifest(large file upload). Bidirectional streaming is not used.Admin CLI bypasses the API — The
adminsub-commands connect directly to Kubernetes, enabling disaster recovery without a running API server. This is a deliberate two-tier CLI design.Webhook receiver is not a separate service — The
/api/webhookendpoint 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.