在正式场合我们讨厌秘密自第一天起,我们就开始尝试把基础设施中长期存在的秘密降到零。
我们希望我们的产品和我们的客户与它的互动方式也能够反映这个哲学。 因此,我们几个月前建立了OIDC Institutions:一种任意的机器工作量的方法,以他们自己的基础设施身份认证为形式,并可以选择地证明沿途的人类身份。
除了产品和CI/CD工作量之外,我们还发现支持OIDC对agents在我们的基础设施中做更多事情非常有用。 云编码agents像Cursor和德文本身都是OIDC的发行者,这意味着我们现在可以通过Attrole获取我们的生产数据和云基础设施,给予它们可审计的,政策控制的,只读的访问权。
OpenID 连接( OIDC)
为了进行简短的再培训,国际开发部的认证流程适用于机器工作量。 目标是从工作量单位的身份提供者(IdP)那里获得一个短暂的象征,并将其作为外部服务(称为依赖方(RP))的身份证明。 依赖方通常以对IDP的了解来预先配置。
- 工作量从环境获得国际税务局的标志。 有时它作为环境变量(如GitHub,GitLab)提供;有时工作量需要通过给元数据端点(如AWS,GCP,Azure)发出API呼叫来取回。 通常情况下,该标志被限定为RP(例如,通过设定Aud Claiming),以防止不同RP的标志再使用。
- 工作量使API呼叫RP,使用获得的OIDC信使作为无记名信使(即授权:Bearer eyJ.)。
- RP从它的配置中查看JWKS的端点(通常是https://idp.com/.well-nowed/openid-confguation等),并获得IDP的公钥来验证JWT.
- RP核查JWT的私人钥匙。 RP还检查了JWT中嵌入的一些声称作为认证条件——这很重要,因为IDPs通常是多租户。 这些声称也通常被用来将来历身份映射到RP上的机器身份。
- 如果所有检查都通过,API呼叫被允许继续。 有时,对通过国际开发部认证的API电话实行额外授权条件。
OIDC 正式办公室
我们国际开发部的一体化遵循了上述流程,并附带了几个关键的额外细节:
- 客户可以指定每个集成的 CEL 条件,其中只允许给定的令牌在条件评价为真实时进行认证。 此外,OIDC索赔领域也作为给Lights的投入而浮出水面,因此客户可以为特定的控制平面API请求规定更颗粒式的授权条件。
- OIDC认证呼叫器可以调用的一个端点是 CreateFederation Token,它返回一个短寿命的 Connection 访问令牌,它嵌入源 OIDC 索赔字段。 这意味着工作量可以使用Connector作为证书注入代理,而不需要自己存储长寿证书。
- SPIFFE的工作量也以本地为单位:正式核查来自SPIRE的JWT-SVID像其他OIDC的标志一样,并配有SPIFFE的ID,供政策和许可机构使用。
- OIDC也可以用于认证正版端点和Kubernetes Egress Agent.
检验人类身份
每个OIDC集成地图到一个单机用户。 这对大多数传统机器工作量来说是一个很好的默认模式;例如,CI工作通常可以归结于一个推动一个承诺的人,而云·agents经常因为有人从Slack踢出一个而跑出。 因此,每次整合都可以选择地界定一种象征性的主张,即正式解决在日志中出现的作为政策投入的人类身份。
这里所涉及的两个身份有着不同种类的信任。 正式的可以加密认证机器身份,但人类身份只能由下游的工作量来确认。 我们接受这个说法是因为我们的客户信任这个系统,并且明确配置了形式来信任它。
我们从第一天起就支持这个形状,Metabase等工具每个数据库只能使用一个证书,但客户经常根据登录到Metabase的人类用户有差别地执行控制。 我们最初建立了最终用户身份传播系统,使Metabase能够维护人类身份,以数据库查询,并让正式评价与之相抗衡的政策。
这种模式最终几乎完美地适合了云编码agents,尤其是一个全队共享的多人游戏,任何人都可以从Slack,Linear,或GitHub得到发布。 云agent平台无法合理地为每一个可能为发布Zagent的人提供单独的证书。 但是,它可以发出一个签名的代号,即称是agent的会话,它是在哪个仓库工作,是谁开始的。 我们的客户已经信任他们的agent平台来做这个声明,就像他们信任Metabase来报告谁登录。 因此,客户可以使用同一种正版原始来遮盖Metabase的数据库列并控制云agent的拥有者团队进入基础设施。
食用犬类
在"正规"中,我们广泛使用自有产品"狗食"——我们有一个Connector,它坐落在我们生产数据库"S3桶"和"日志集群"的前面,我们使用"正规端点"来监控和控制开发商笔记本电脑上agent的用法。 我们生产租户的控制平面完全由Terraform公司管理,因此我们最早的OIDC集成的内部使用案例之一是将Terraform Cloud认证方式转换为正式控制平面使用OIDC,而不是长寿的API密钥。
agent平台已逐渐从笔记本电脑转向云沙箱。 我们不愿让这些云agents进入我们的基础设施,因为这样做将意味着发出静态证书
然而,OIDC提出了解决方案——我们不再需要指定编码agents静态证书,我们可以根据云agent的具体细节来评价政策(例如人类将它踢出,或者它正在研究的GitHub repo).
以下是我们发现的使用案例列表
产品分析
产品分析工作流程往往依赖我们生产数据库(我们replicate到一个分析数据库)的数据。 例如,测量新产品对象的通过率需要查看客户究竟有哪个产品对象的数据库条目。
在不远的过去,这个过程曾经是手动的——工程师曾经需要手动为这些工作流程作 SQL 查询。 agents在写SQL和消化结果方面都非常出色,因此,我们必须手动运行查询,将结果导出为 CSV,然后将其粘贴回agent的上下文。
然而,随着OIDC的混合,我们现在有了一个方法,将每一次云agent会话作为自己的特性。 在Cursor帮助朋友创造的一股潮流的启发下,我们为云agents建立了一个途径,要求其人类所有者批准短期访问我们生产数据库。 这种流动利用了我们的OIDC集成,以及包括"工作流"和"政策暂停"在内的其他几个已存在的平台原始。
特别是,agent可以告诉人类超过Slack,它到底为什么需要访问,以及需要多长时间。 一旦人类批准,访问范围将扩大到云agent会话ID和所请求的具体数据库。
调试同步工作流程
我们的工作流程管弦乐提供商不会提供远程的MCP服务器,所以以前没有长寿的证书就无法给予云agents访问权限。 这限制了我们利用编码agents的能力来根据真实运行历史优化工作流程性能。
我们可以将工作流程管弦乐器注册为正式资源,并将只读的API密钥存储为原生用户。 使用OIDC,云agents可以像上面的数据库一样,请求并被批准短期访问。 请求总是以正式形式登录,并归咎于云agent和发布的工程师。
测试云内特性
形式平台支持AWS,GCP,和Azure等多处本土地貌。 例如,连接器可以使用IAM认证到数据库和Kubernetes集群。 此外,控制平面还可以与每个云提供商整合,以自动发现资源并发送日志到存储桶。
当我们研究这些特性时,我们现在可以让云agents联邦使用OIDC 既给我们的正式租户,也给一个云供应商的账户。 这使得agent能够确保其代码更改在活的,有代表性的云环境中如出一辙地工作,帮助它关闭回路而不需要诉诸于bitchtle模拟。
例如,我最近有Cursor云agent的工作,将我们的Kubernetes操作员扩展至使用OIDC(例如带有Azure工作负荷身份)认证到正式控制平面。 在开发过程中,我让云克agent访问一个dev Azure账户,在其中,它部署了一个新的AKS集群,从其PR分支运行Kubernetes操作员。 agent能够通过连接我们的正式dev租户来核实,一旦在集群中创建了正式政策CRD,政策就与这位dev租户同步——证明代码的更改是如所愿的。
结论
Cloud agents当它们能够自己关闭环路时就变得大有用处:它们应该能够收集出产品使用数据,调查故障,并在现实环境中验证其工作。 但这并不需要发放可重复使用、长期有效的证书。
OIDC帮助我们把个人的agent运行作为独特的工作量身份来建模。 当agent通过"形式"向外部服务提出请求时,访问可以与发布它所在的工程师,它正在工作的寄存器,以及提出请求的具体的agent会话相接。 生产准入仍然只有读取和批准,而开发环境中的许可可以更广泛,而不成为永久的。
从我们内部使用的更广泛的教训是,agent访问应作为临时代表团的模式——而不仅仅是另一个具有长期秘密的机器工作量。 一旦有了这种区别,agents获得实际基础设施的机会就变得不那么可怕了,而且更加有用。
本文由 AI宝库自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。
At Formal, we hate secrets. Since day one, we’ve been on a quest to drive the number of long-lived secrets in our infrastructure to zero.
We want our product and the way our customers interact with it to reflect that philosophy, too. Accordingly, we built OIDC Integrations a few months ago: a way for arbitrary machine workloads to authenticate to Formal on the strength of their own infrastructure identity, and optionally attest a human identity along the way.
Beyond product and CI/CD workloads, we’ve also found that supporting OIDC has been extremely useful for enabling agents to do more in our infrastructure. Cloud coding agents like Cursor and Devin themselves are OIDC issuers, which means that we can now give them auditable, policy-controlled, read-only access through Formal to our production data and cloud infrastructure.
OpenID Connect (OIDC)
For a brief refresher, an OIDC authentication flow works as follows for machine workloads. The goal is to obtain a short-lived token from the workload’s identity provider (IdP) and use it as proof of identity on an external service, known as the relying party (RP). The relying party is usually preconfigured with knowledge about the IdP.
- The workload obtains its OIDC JWT token from its environment. Sometimes this is provided as an environment variable (e.g., GitHub, GitLab); sometimes the workload needs to retrieve it by making an API call to a metadata endpoint (e.g., AWS, GCP, Azure). Typically, the token is scoped to the RP (e.g., by setting the Audience aud claim) to prevent token reuse across different RPs.
- The workload makes an API call to the RP, using the obtained OIDC token as a bearer token (i.e., Authorization: Bearer eyJ...).
- The RP looks up the JWKS endpoint (usually something like https://idp.com/.well-known/openid-configuration) from its configuration and obtains the IdP’s public key to verify the JWT with.
- The RP verifies the JWT is signed with the IdP’s private key. The RP also checks some of the claims embedded in the JWT as an authentication condition — which is important, because IdPs are typically multi-tenant. These claims are also typically used to map the incoming identity to a machine identity on the RP.
- If all checks pass, the API call is allowed to proceed. Sometimes, additional authorization conditions are applied to API calls that are authenticated via OIDC.
OIDC at Formal
Our OIDC integrations follow the above flow, with a few key additional details:
- Customers can specify a CEL condition for each integration, where a given token is only allowed to authenticate if that condition evaluates to true. Additionally, OIDC claim fields are also surfaced as inputs to Permissions, such that customers can define more granular authorization conditions for specific control plane API requests.
- One endpoint that OIDC-authenticated callers can call is CreateFederationToken, which returns a short-lived Connector access token that embeds the source OIDC claim fields. This means that workloads can use the Connector as a credential-injecting proxy without needing to store long-lived credentials themselves.
- SPIFFE workloads work natively too: Formal verifies JWT-SVIDs from SPIRE like any other OIDC token, with the SPIFFE ID available to Policies and Permissions.
- OIDC can also be used to authenticate the Formal Endpoint and Kubernetes Egress Agent.
Attesting human identity
Every OIDC integration maps to a single machine user. This is a good default model for most traditional machine workloads; however, many workloads we care about don’t act on their own behalf. For example, CI jobs can usually be attributed to a human that pushed a commit, and cloud agents are often run because someone kicked one off from Slack. As such, each integration can optionally define a token claim that Formal resolves to a human identity which appears in logs and as input to policies.
The two identities involved here come with different kinds of trust. Formal can cryptographically authenticate the machine identity, but the human identity is only asserted by the downstream workload. We accept that claim because our customer trusts the system making it, and explicitly configures Formal to trust it too.
We’ve supported this shape since day one, but for a very different use case: many of our customers use Formal to control database traffic between business intelligence (BI) tools and their data sources. Tools like Metabase can only use one credential per database, but customers often differentially enforce controls based on the human user logged into Metabase. We originally built end-user identity propagation as a way to allow Metabase to assert the human identity to database queries and let Formal evaluate policies against it.
That pattern turns out to fit cloud coding agents almost perfectly, especially multiplayer ones that a whole team shares and anyone can launch from Slack, Linear, or GitHub. A cloud agent platform can’t reasonably produce a separate credential for every human who might launch an agent. It can, however, issue a signed token that says which agent session this is, which repository it’s working in, and who started it. Our customers already trust their agent platform to make that statement, just as they trust Metabase to report who is logged in. As a result, customers can use the same Formal primitive to both mask database columns in Metabase and to control cloud agent access to infrastructure by its owner’s team.
Dogfooding OIDC integrations
At Formal, we extensively dogfood our own product — we have a Connector that sits in front of our production databases, S3 buckets, and log clusters, and we use the Formal Endpoint to monitor and control coding agent usage on developer laptops. Our production tenant’s control plane is fully managed with Terraform, so one of our first internal use cases for the OIDC integration was to switch the way Terraform Cloud authenticates to the Formal control plane to use OIDC rather than a long-lived API key.
We’re heavy customers of a few cloud coding agent platforms, and we’ve been gradually shifting development away from our laptops and onto cloud sandboxes. We’d been reluctant to give these cloud agents access into our infrastructure, as doing so would have meant handing out static credentials without much in the way of granular scoping.
However, OIDC presented the solution — we no longer needed to assign coding agents static credentials, and we could evaluate policies based on specific details of the cloud agent (such as which human kicked it off, or which GitHub repo it’s working on).
The following is a non-exhaustive list of the use cases we’ve found to make our cloud agents more productive.
Product analytics
Often, product analytics workflows lean on data from our production databases (which we replicate to an analytics database). For example, measuring the rate of adoption of a new product object requires seeing which customers actually have database entries for that product object.
In the not-too-distant past, this process used to be manual — engineers used to need to manually compose SQL queries for these workflows. Coding agents are great both at writing SQL and digesting the results, but we previously didn’t have a safe way to give them controlled access. As a result, we would have to manually run the query, export the result as CSV, and then paste it back into the agent’s context.
With OIDC in the mix, however, we now had a way to treat each cloud agent session as its own identity. Inspired by a flow we helped our friends at Cursor create, we set up a way for cloud agents to request approval from their human owners for short-lived access to our production databases. This flow uses our OIDC integration, along with a few other existing platform primitives including Workflows and Policy Suspensions.
In particular, the agent can tell the human over Slack why exactly it needs access, and for how long. Once the human approves, access is scoped to the cloud agent session ID and the specific database that was requested.
Debugging asynchronous workflows
Our workflow orchestration provider doesn’t supply a remote MCP server, so previously there was no way to give cloud agents access without long-lived credentials. This limited our ability to use coding agents to optimize workflow performance based on real run history.
We can register the workflow orchestrator as a Formal resource and store a read-only API key as a Native User. Using OIDC, cloud agents can request and be approved for short-lived access as they would with databases above. Requests are always logged in Formal and attributed to both the cloud agent and the engineer that launched it.
Testing cloud-native features
The Formal platform supports a number of native features of AWS, GCP, and Azure. For example, the Connector can authenticate to databases and Kubernetes clusters using IAM. Additionally, the control plane can integrate with each cloud provider to autodiscover resources and to send logs to storage buckets.
When we iterate on these features, we can now have cloud agents federate using OIDC to both our Formal dev tenant and to a dev account on a cloud provider. This allows an agent to ensure its code change works as intended in a live, representative cloud environment, helping it close the loop without needing to resort to brittle mocks.
For example, I recently had a Cursor cloud agent work on extending our Kubernetes operator to authenticate to the Formal control plane using OIDC (e.g., with Azure Workload Identity). During the development process, I gave the cloud agent access to a dev Azure account, into which it deployed a new AKS cluster to run the Kubernetes operator from its PR branch. The agent was able to verify through connecting to our Formal dev tenant that once it created a FormalPolicy CRD in the cluster, the policy was synced to that dev tenant — proving the code change worked as intended.
Conclusion
Cloud agents become substantially more useful when they can close the loop themselves: they should be able to gather product usage data, investigate failures, and validate their work in realistic environments. However, that shouldn’t need to require handing out reusable, long-lived credentials.
OIDC helps us model an individual agent run as a unique workload identity. When an agent makes requests to external services via Formal, access can be tied to the engineer who launched it, the repository it is working on, and the specific agent session making the request. Production access remains read-only and approval-gated, while permissions in development environments can be broader without becoming permanent.
The broader lesson from our internal use is that agent access should be modeled as a temporary delegation — not just as another machine workload with another long-lived secret. Once that distinction exists, giving agents access to real infrastructure becomes much less frightening and considerably more useful.
Auto-fetched and translated by AI Gem Box. All rights belong to the original author.