fix(access): apply API token limits in more permission checks

- Use the limits of the API token in more permission checks.
- Show a clearer message when a token limit blocks a change.
- Describe API tokens with limits in SECURITY.md.
This commit is contained in:
Andras Bacsai
2026-11-08 15:53:02 +01:00
parent 1d21a27812
commit 3c588d482d
7 changed files with 180 additions and 7 deletions
+17 -1
View File
@@ -759,13 +759,29 @@ class EnvironmentVariable extends BaseModel
$scope = self::sharedVariableScope($resource, $reference['type']);
if ($scope === null || Gate::forUser($user)->denies('viewSensitive', $scope)) {
$name = "{$reference['type']}.{$reference['key']}";
throw ValidationException::withMessages([
$field => "You cannot reference the shared variable {$reference['type']}.{$reference['key']}, because you cannot read its value.",
$field => self::isBlockedOnlyByTokenScope($user, $scope)
? "This API token is limited to selected projects, environments, or resources, so it cannot reference the {$reference['type']} shared variable {$name}. Use a token for the whole team."
: "You cannot reference the shared variable {$name}, because you cannot read its value.",
]);
}
}
}
/**
* True when the user is an admin who can read team and server variables, but the API token of the request
* is limited to selected projects, environments, or resources.
*/
private static function isBlockedOnlyByTokenScope(User $user, ?SharedEnvironmentVariable $scope): bool
{
return $scope !== null
&& in_array($scope->type, ['team', 'server'], true)
&& data_get($user->currentAccessToken(), 'scopes') !== null
&& $user->isAdminOfTeam((int) $scope->team_id);
}
/**
* An unsaved shared variable of the given type for the resource. The policy decides by the
* scope, so a reference to a key that does not exist yet is checked like an existing one.