immich-app/immich · error · BadRequestException

Cannot grant permissions you do not have

Error message

Cannot grant permissions you do not have

What it means

Raised by ApiKeyService.create when the current request is itself authenticated with an API key and the requested permissions in ApiKeyCreateDto are not a subset of that key's own permissions (checked with isGranted). An API key cannot mint another key with privileges beyond its own, so creation is refused with a 400. The input at fault is dto.permissions.

Solutions

  1. Remove the excess permissions from dto.permissions so they are a subset of the authenticating API key's permissions
  2. Authenticate as the user (session/OAuth) instead of via the restricted API key, then create the new key
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/api-key.service.ts:17 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/c05872e653fbd49d. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/api-key.service.ts:17

import { BadRequestException, ForbiddenException, Injectable } from '@nestjs/common';
import { ApiKey } from 'src/database.js';
import { ApiKeyCreateDto, ApiKeyCreateResponseDto, ApiKeyResponseDto, ApiKeyUpdateDto } from 'src/dtos/api-key.dto.js';
import { AuthDto } from 'src/dtos/auth.dto.js';
import { Permission } from 'src/enum.js';
import { BaseService } from 'src/services/base.service.js';
import { isGranted } from 'src/utils/access.js';
import { findOrFail } from 'src/utils/misc.js';

@Injectable()
export class ApiKeyService extends BaseService {
  async create(auth: AuthDto, dto: ApiKeyCreateDto): Promise<ApiKeyCreateResponseDto> {
    const token = this.cryptoRepository.randomBytesAsText(32);
    const hashed = this.cryptoRepository.hashSha256(token);

    if (auth.apiKey && !isGranted({ requested: dto.permissions, current: auth.apiKey.permissions })) {
      throw new BadRequestException('Cannot grant permissions you do not have');
    }

    const entity = await this.apiKeyRepository.create({
      key: hashed,
      name: dto.name || 'API Key',
      userId: auth.user.id,
      permissions: dto.permissions,
    });
    const apiKey = this.map(entity);

    return { ...apiKey, secret: token, apiKey };
  }

  async update(auth: AuthDto, id: string, dto: ApiKeyUpdateDto): Promise<ApiKeyResponseDto> {
    const exists = await this.apiKeyRepository.getById(auth.user.id, id);
    if (!exists) {
      throw new BadRequestException('API Key not found');
    }

View on GitHub (pinned to e55ac299a4)