自定义 TFS 发布任务获得什么样的安全上下文?

What kind of security context do custom TFS release tasks get?

TFS 2018u1。我有一个通过 VSSConnection 对象调用 TFS 服务的自定义 Powershell 任务:

$VSS = Get-VssConnection -TaskContext $distributedTaskContext
$Client = $VSS.GetClient(...)

问题:任务获得什么样的安全上下文?绝对不是代理帐户。为了确保,我已经设置了一个临时代理实例,它以我的身份运行,TFS 管理员,并且该代理上的自定义任务 运行 没有完整的管理员。

潜在的问题是 - 我正在尝试从一项任务中获取当前代理记录,而该任务只看到一个池,即使我们有多个。参见

我正在尝试从一项任务中获取当前代理记录,但该任务只能看到一个池,尽管我们有多个池。

有一个Agent pool security roles的概念,例如具有Administrator角色,您可以:

Rregister or unregister agents from the pool and manage membership for all pools, as well as view and create pools. They can also use the agent pool when creating an agent queue in a team project. The system automatically adds the user that created the pool to the Administrator role for that pool.

构建代理的默认权限运行发布任务应与构建服务帐户相同。请从集合级管理上下文、代理池页面将您的构建服务帐户添加到代理池安全角色到管理员。然后再试一次。

另一种可能是您在自定义发布任务中缺少 vso.agentpools 范围。

Grants the ability to view tasks, pools, queues, agents, and currently running or recently completed jobs for agents

详情请看Supported scopes

首先,distributedTaskContext 不使用 NTLM 连接到 TFS,就像 Patrick Lu 的回答所暗示的那样。它与 Authorization:Bearer 和一个令牌连接。我使用相同的令牌调用 /_api/_common/GetUserProfile 端点,即 returns 当前用户,并返回以下身份记录:

{
    "IdentityType": "user",
    "FriendlyDisplayName": "Project Collection Build Service (TEAM FOUNDATION)",
    "DisplayName": "Project Collection Build Service (TEAM FOUNDATION)",
    "SubHeader": "Build\233e4ccc-d129-4ba4-9c5b-ea82c7ae1d15",
    "TeamFoundationId": "7a3195ee-870e-4151-ba58-1e522732086c",
    "EntityId": "vss.ds.v1.ims.user.7a3195ee870e4151ba581e522732086c",
    "Errors": [],
    "Warnings": [],
    "Domain": "Build",
    "AccountName": "233e4ccc-d129-4ba4-9c5b-ea82c7ae1d15",
    "IsWindowsUser": false,
    "MailAddress": ""
}

它看起来像是 TFS 专门为此目的创建的某种人工标识。在 tbl_Identity table 中的 TFS 数据库中查看,有许多具有类似名称的用户记录 - 似乎每个 collection 一个,还有一些是特定于项目的。

此用户属于名为 "Security Service Group" 的 server-level 组(并且还属于具有相同名称的 collection 级别组)。这些组分别属于 Team Foundation 有效用户和项目 Collection 有效用户,仅此而已。

至少在 collection 级别,"Security Service Group" 是可见的并且包含很多帐户。

所有这些 "Build Service" 用户都属于名为 "Build" 的域。虽然域不是安全主体,但您不能向域授予权限。

说到 OAuth 范围。我使用了相同的标记来调用 the homegrown "what are this token's scopes" page, and it turns out the distributedTaskContext token has exactly one - app_token. It's a valid scope that opens up all endpoints and all methods (see the dynamic scope list)。扩展清单中的 scopes 参数与此无关;它只影响 client-side 个贡献。


不过,谈到池的可见性,情况就很棘手了。似乎所有 "Project Collection Build Service" 帐户都属于有效用户,但将所有池中的 Reader 角色授予有效用户并不会在任务中向 REST API 开放它们。将 Reader 显式授予 "Project Collection Build Service" 即可。但是,有许多这样的帐户(似乎每个 collection 一个)- 授予 Reader 只会打开池以在其所在的 collection 中发布定义。为了让所有 collections 中的发布任务读取池,您需要遍历所有 collections 并将每个 Reader 授予 "Project Collection Build Service"。