#Local appwrite run functions --user-id not generating x-appwrite-user-jwt (self-hosted)

3 messages · Page 1 of 1 (latest)

gentle flower
#

Hi, I'm running into an issue when testing Appwrite functions locally with user impersonation.

I'm using a self-hosted Appwrite instance and running functions locally with the CLI:
appwrite run functions --function-id <FUNCTION_ID> --user-id <USER_ID>

The function runs correctly, but the impersonation headers are not generated.

Inside the function I logged the headers and I'm getting:
log(JSON.stringify({
userId: req.headers['x-appwrite-user-id'] ?? null,
hasUserJwt: Boolean(req.headers['x-appwrite-user-jwt']),
hasApiKey: Boolean(req.headers['x-appwrite-key']),
}, null, 2));
So:
{
"userId": "6978b6b8003822478082",
"hasUserJwt": false,
"hasApiKey": false
}

The CLI prints the following warning:
Dynamic API key not generated. Header x-appwrite-key will not be set.
Reason: <email> (role: users) missing scopes (["users.read"])

However the function does have the required scopes in appwrite.config.json, including:
"scopes": [
"users.read"
]

Other CLI commands work normally:
appwrite push functions
appwrite pull
deployments etc.

So the CLI login seems valid.

Am I missing something in my setup, or is there any additional configuration required for local user impersonation on self-hosted Appwrite?

velvet harbor
#

Hey! This is a great catch. I’m on the Appwrite Quality Team, and that 'missing scopes' warning in the CLI is definitely the smoking gun here.
Even though you’ve added users.read to your appwrite.json, the CLI is reporting that the API Key it's trying to generate dynamically doesn't have the permissions to impersonate that user.
Here are the most likely culprits to check:
The 'push' sync: Double-check if the scopes in your local appwrite.json have actually been pushed to the server. The CLI generates the dynamic key based on what the server thinks the function's scopes are. Try running appwrite push functions again just to be 100% sure the server-side metadata is updated.
CLI Scopes vs. Function Scopes: The CLI uses your logged-in session to create that dynamic key. If your CLI user (usually the developer/admin) doesn't have the high-level permission to view users, it might fail to generate the JWT for impersonation.
The --verbose flag: Try running the command with the flag:
appwrite run functions --function-id <ID> --user-id <ID> --verbose
This should give us a more detailed error message than just 'missing scopes' and might show exactly which entity is lacking the permission.
One thing to note: On self-hosted instances, ensure your _APP_OPTIONS_ABUSE or _APP_FUNCTIONS_TIMEOUT env vars aren't hitting a limit, though usually, this specific error is strictly a Scope/Role mismatch.
Give the push and verbose check a go—if the server still insists the scope is missing after a push, let us know so we can look into it as a potential CLI sync bug!

gentle flower
#

Thanks for the suggestions! I went through the checks you mentioned and did a bit more testing.

I ran appwrite push functions again to make sure the scopes were synced to the server.
I also tried running with --verbose, but the output didn't show any additional scope-related detail beyond the same warning:
Dynamic API key not generated... missing scopes (["users.read"])
I verified that the function scopes in appwrite.config.json do include users.read, and the verbose output shows the scopes correctly when starting the local run.

Another useful detail: this happens across multiple functions, not just one specific function.
I also logged the headers inside the function and confirmed that during local execution with --user-id, the headers are still missing:
{
"userId": "6978b6b8003822478082",
"hasUserJwt": false,
"hasApiKey": false
}
Because of that, any Appwrite calls from inside the function behave as guest, which leads to errors like:
User (role: guests) missing scopes (["users.read"])

However, I found something interesting while testing on another machine.
On another computer with Appwrite CLI 12.0.0, the exact same project and self-hosted instance work correctly — x-appwrite-user-jwt is generated and impersonation works as expected.
On my current machine with CLI 14.0.1, the same command does not generate the headers and produces the missing scopes warning.
After downgrading the CLI on this machine to 12.0.0, the problem disappears and impersonation works again.
So at this point it looks like this might be related to a change/regression in newer CLI versions rather than a project configuration issue.

Have there been any changes to the local impersonation or dynamic API key generation logic in newer CLI versions that could affect self-hosted setups?