Corsair puts policy between an agent and business APIs
Corsair addresses the uncomfortable part of agent integrations: the agent needs to call Gmail, Slack, GitHub, or another service, but it should not receive a reusable credential or unrestricted authority. Each plugin resolves credentials internally and describes endpoints with read, write, or destructive risk. A policy can allow the call, deny it, or store frozen arguments until a human approves a single execution. The agent receives method names and results rather than the API key.
There are 4 named permission modes. Open allows everything. Cautious allows reads and ordinary writes while requiring approval for destructive actions. Strict permits reads, sends writes for approval, and blocks destructive calls. Readonly blocks both write categories. Endpoint overrides can tighten a plugin further, such as denying repository deletion while requiring approval for release creation. This is a useful model, but teams must read the matrix: cautious does not mean every outward action pauses for review.
Credential isolation depends on one recoverable KEK
Corsair uses envelope encryption. Each connection gets a data-encryption key, and one key-encryption key from the application's environment protects those per-connection keys. Tokens live in the application's database whether the operator uses Corsair Hub or hosts all public surfaces manually. The Hub relays connect, callback, approval, and webhook traffic; the documentation says it does not store credentials. Teams with their own KMS can pass decrypted credentials and bypass the built-in key manager.
The quick start warns that losing CORSAIR_KEK means losing access to every encrypted credential. That makes backup and rotation design part of setup, not a later security task. The database also stores accounts, integration entities, events, and approval records. SQLite is offered for a quick start, while PostgreSQL, Drizzle, and Prisma examples cover production-shaped applications. OAuth client secrets and provider callback configuration remain the operator's responsibility.
What happened when we ran it
Our sandbox cloned commit b0e01d8 into an unprivileged Debian container with 3 CPUs and 8 GB of RAM. Pnpm installed 2,105 packages in 94 seconds and occupied 2,278 MB. The monorepo build succeeded in 565 seconds. No package-audit result was supplied for this run, so we make no vulnerability claim.
The test step exited with code 1 after 59 seconds. Jest reported 9 passing and 34 failing tests out of 43. Turbo identified @corsair-dev/intercom#test as the failed task, reported 9 successful tasks out of 174, and stopped the run. The log tail does not contain the individual assertion errors, so it cannot tell us whether one shared setup problem produced many failures or whether 34 behaviors were independently broken.
The checkout was also large: 5,802 files, roughly 841,752 lines of source, and 58.7 MB before dependencies. Our scan found 7 CI workflow files, pnpm workspaces, no Dockerfile, and no conventional tests directory. A successful 565-second build shows the packages compile in the measured environment. It does not outweigh a suite where most reported Jest cases failed.
Hub removes pages, while manual mode makes you build them
The shortest setup uses Corsair Hub. Developers create a Hub project, store its development API key and signing secret, mount one handler, and let Hub host connect and approval pages. Credentials remain encrypted in the application's database. This removes callback pages and environment-specific public URLs from the product team, though it adds Corsair's hosted relay to the authentication and approval path.
Manual mode keeps those surfaces under your domain but requires more application code. The team builds a connect page, OAuth callback route, missing-connection flow, and approval UI, then wires delivery and timeout behavior. Mixing is allowed, so OAuth can use Hub while approvals stay local. That is a sensible compromise for regulated writes, but it is still infrastructure that must be tested against replay, expiration, denial, and interrupted execution.
Approval records fail closed when the table is missing
An action requiring approval is written with its plugin, endpoint, tenant, frozen arguments, expiry, and a 64-character token. Approved requests are single-use and move through executing to completed after the endpoint succeeds. Duplicate pending requests reuse the existing token. If the permissions table is absent, gated endpoints deny instead of proceeding, which is the correct default. Timeouts also default to denial unless the operator explicitly chooses approval.
Multi-tenancy adds tenant_id to writes and filters reads through withTenant(). Direct plugin calls are rejected by TypeScript when multi-tenancy is enabled. Webhooks route the tenant through a query parameter, so applications still need to protect and validate that public route. Type-level scoping is helpful, but database constraints, webhook tests, and adversarial tenant-isolation tests remain necessary for a production claim.
Same-day activity is high, with no GitHub release to anchor it
The repository was pushed on August 26, 2026. GitHub showed 217 combined issues and pull requests, and the newest activity included numerous integration requests and plugin pull requests, several marked with failed gates. That is an energetic project with a large moving surface. The latest-release endpoint returned no GitHub release, so teams cannot use a release page as their upgrade checkpoint. Package versions may exist elsewhere, but no such claim is needed here.
Apache-2.0 text is present in the repository even though GitHub reported the license as NOASSERTION. Corsair's core idea is sound: credentials stay outside the agent, and risky actions can require a human decision. The current buying decision is about execution quality. With 34 failed tests, a 2.3 GB install, and hundreds of active issues and pull requests, Corsair belongs in a narrow pilot before it sits between an autonomous agent and production accounts.

