Skip to content

App key rotation is unsupported, while it is in Laravel 11 itself #1801

Open
@serious-angel

Description

Passport Version

12.3.1

Laravel Version

11.35.1

PHP Version

8.2

Database Driver & Version

No response

Description

Dear Developers and Community,

Thank you for the marvel...

Issue

With the key rotated, the general User session gets authorized successfully, but if there are grants or anything OAuth active, those get invalidated.

Apparently, they rotation mechanism added in Laravel 11 is not supported by Laravel Passport.

Laravel 11 supports decryption with a set of keys, while Laravel Passports - only one, the current.

Details

Laravel 11

Multiple keys are set on:

// \Illuminate\Encryption\EncryptionServiceProvider

protected function registerEncrypter()
{
    $this->app->singleton('encrypter', function ($app) {
        $config = $app->make('config')->get('app');

        return (new Encrypter($this->parseKey($config), $config['cipher']))
            ->previousKeys(array_map(
                fn ($key) => $this->parseKey(['key' => $key]),
                $config['previous_keys'] ?? [] // Previous keys (e.g. `APP_PREVIOUS_KEYS`).
            ));
    });
}

Source

Laravel Passport

The key gets set on:

// \Laravel\Passport\PassportServiceProvider

public function makeAuthorizationServer()
{
    return new AuthorizationServer(
        $this->app->make(Bridge\ClientRepository::class),
        $this->app->make(Bridge\AccessTokenRepository::class),
        $this->app->make(Bridge\ScopeRepository::class),
        $this->makeCryptKey('private'),
        app('encrypter')->getKey(), // Obtains the current key (e.g. DotEnv `APP_KEY`).
        Passport::$authorizationServerResponseType
    );
}

Source

// \League\OAuth2\Server\AuthorizationServer

public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null) 
{
    if ($accessTokenTTL === null) {
        $accessTokenTTL = new DateInterval('PT1H');
    }

    $grantType->setAccessTokenRepository($this->accessTokenRepository);
    $grantType->setClientRepository($this->clientRepository);
    $grantType->setScopeRepository($this->scopeRepository);
    $grantType->setDefaultScope($this->defaultScope);
    $grantType->setPrivateKey($this->privateKey);
    $grantType->setEmitter($this->getEmitter());
    $grantType->setEncryptionKey($this->encryptionKey); // We set the key for the key file.
    $grantType->revokeRefreshTokens($this->revokeRefreshTokens);

    $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType;
    $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL;
}

Source

Question

Is it an expected behavior? If not, what would be the most appropriate approach if the support won't be added in the future?

I have tried adding it manually, but after encountering multiple places where file keys are set, chains of interfaces, multiple conditional endpoints etc., it felt like a prior clarification of rationales and approaches is more adequate.


Best and kind regards ✨

Steps To Reproduce

  1. Configure any Laravel Passport grant which requires encryption;
  2. OAuth-authorize storing the cookies/tokens in a client;
  3. Rotate the Laravel app key following the steps;
  4. Try OAuth-authorizing again using the same client with its cookies/token.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions