mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Derive console API key scopes from project API key
Instead of hardcoding scopes in the console key, read them from the project API key. Added platforms.read and keys.read to the project key, and the console key now receives only scopes that the project key already has.
This commit is contained in:
@@ -319,6 +319,8 @@ class Migrations extends Action
|
||||
'functions.write',
|
||||
'tokens.read',
|
||||
'tokens.write',
|
||||
'platforms.read',
|
||||
'keys.read',
|
||||
]
|
||||
]);
|
||||
|
||||
@@ -326,23 +328,37 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a console-scoped dynamic API key for settings migration.
|
||||
*
|
||||
* This key allows the source adapter to read platforms and keys
|
||||
* via the console API endpoints (same-instance only).
|
||||
*
|
||||
* @throws Exception
|
||||
* Decode a dynamic API key and extract its scopes.
|
||||
*/
|
||||
protected function generateConsoleAPIKey(string $targetProjectId): string
|
||||
protected function decodeAPIKeyScopes(string $apiKey): array
|
||||
{
|
||||
if (\str_contains($apiKey, '_')) {
|
||||
[, $secret] = \explode('_', $apiKey, 2);
|
||||
} else {
|
||||
$secret = $apiKey;
|
||||
}
|
||||
|
||||
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 86400, 0);
|
||||
$payload = $jwt->decode($secret);
|
||||
|
||||
return $payload['scopes'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a console-scoped dynamic API key for settings migration.
|
||||
* Scopes are derived from the project API key (same-instance only).
|
||||
*/
|
||||
protected function generateConsoleAPIKey(string $targetProjectId, array $scopes): string
|
||||
{
|
||||
if (empty($scopes)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 86400, 0);
|
||||
|
||||
$apiKey = $jwt->encode([
|
||||
'projectId' => 'console',
|
||||
'scopes' => [
|
||||
'platforms.read',
|
||||
'keys.read',
|
||||
],
|
||||
'scopes' => $scopes,
|
||||
'targetProjectId' => $targetProjectId,
|
||||
]);
|
||||
|
||||
@@ -389,8 +405,14 @@ class Migrations extends Action
|
||||
// Only generate and set consoleApiKey for same-instance migrations
|
||||
// to avoid leaking a locally-signed JWT to untrusted remote servers
|
||||
if ($credentials['endpoint'] === $endpoint) {
|
||||
$credentials['consoleApiKey'] = $this->generateConsoleAPIKey($credentials['projectId']);
|
||||
$credentials['sourceProjectId'] = $credentials['projectId'];
|
||||
// Read scopes from the project API key
|
||||
$projectKeyScopes = $this->decodeAPIKeyScopes($credentials['apiKey']);
|
||||
$consoleApiKey = $this->generateConsoleAPIKey($credentials['projectId'], $projectKeyScopes);
|
||||
|
||||
if (!empty($consoleApiKey)) {
|
||||
$credentials['consoleApiKey'] = $consoleApiKey;
|
||||
$credentials['sourceProjectId'] = $credentials['projectId'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user