Panel still shows "cookie signing key has not been changed" despite correctly set cookie.key option (Kirby 5.4.4)

Panel still shows “cookie signing key has not been changed” despite correctly set cookie.key option (Kirby 5.4.4)

Setup

  • Kirby version: 5.4.4 (Kirby Basic, valid license)
  • PHP: 8.4.12
  • Server: Apache (hosted at dogado)
  • Plain PHP setup (no Composer, classic kirby folder)

Problem

In the Panel under System → Security, the following warning is permanently displayed:

The cookie signing key has not been changed from its default value

This happens even though I set a custom value for the cookie key in config.php, following the security guide docs. The content.salt warning correctly disappeared after the same approach — only the cookie key warning remains.

What I’ve already tried / checked

1. First attempt — option named exactly as worded in the docs:

"Kirby\Http\Cookie::\$key" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

→ Warning remained.

2. Checked the Kirby source code (src/Http/Cookie.php, hmac() method):

protected static function hmac(string $value): string
{
    // prefer the option if it was set, otherwise use the value
    // set directly to this class (for backwards-compatibility)
    // or fall back to the fixed default set directly with the prop
    $key = App::instance(lazy: true)?->option('cookie.key') ?: static::$key;

    return hash_hmac('sha1', $value, $key);
}

This shows that the actual option key is cookie.key, not Kirby\Http\Cookie::$key (the latter appears to just be the docs referencing the PHP class name, not an actual config array key).

3. Second attempt — corrected option:

"cookie.key" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

→ Warning in the Panel is still showing.

Verification via debug script

To rule out another config file (e.g. host-specific) overriding something, I placed a small script right next to index.php that boots Kirby normally and outputs the active values:

require __DIR__ . '/kirby/bootstrap.php';
$kirby = new Kirby();

$host = $kirby->environment()->host();
$cookieKey = \Kirby\Http\Cookie::$key;
$cookieKeyOption = $kirby->option('cookie.key');

Output:

Detected hostname:          example.com
Expected host config path:  .../config/config.example.com.php
This file exists:           no

Active Cookie::$key:        KirbyHttpCookieKey   <- default!
Option 'cookie.key':        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Active content.salt:        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The odd part: the cookie.key option comes through correctly with my value ($kirby->option('cookie.key') returns the right string). Yet \Kirby\Http\Cookie::$key still shows the default KirbyHttpCookieKey, and the Panel keeps showing the warning accordingly.

It looks to me as if the static property Cookie::$key is no longer (or never was) automatically populated from the cookie.key option, or as if the Panel’s security check compares directly against Cookie::$key === 'KirbyHttpCookieKey', while hmac() itself correctly pulls from the option at runtime. If that’s the case, this would be an inconsistency between the actual cookie signing (which presumably works correctly with my value) and the Panel’s warning display itself.

Questions for you

  1. Is cookie.key actually the correct/only way to set this value, or does Kirby\Http\Cookie::$key additionally need to be set directly as a static property, e.g. via a bootstrap hook / ready callback?
  2. If the latter: what’s the correct syntax for this in config.php? The security guide uses the class name directly as the example option key, which suggests (to me, and probably others) that a simple array entry should be sufficient.
  3. Does the Panel security warning possibly check the wrong thing (static property instead of option), causing it to fire even when the signing itself is already working correctly?

Thanks for your help — I just want to make sure the cookie signing is actually using my custom value, rather than just making the warning disappear without the underlying protection actually being in effect.

See cookie | Kirby CMS

Please note that the forum language is English.

Solved!

Thanks for pointing me to that page — that was exactly the missing piece.

The key issue was that I had set the cookie key as an array entry inside the return [...] block, e.g.:

return [
    "Kirby\Http\Cookie::\$key" => "...",
    // or, after digging through the source code, also tried:
    "cookie.key" => "...",
];

But as the reference page shows, this option is not a regular array key — it needs to be a direct static property assignment, placed before the return statement:

<?php

Kirby\Http\Cookie::$key = "your-random-string-here";

return [
    // all other options go here as usual
];

Once I moved it outside the array and assigned it directly like this, the Panel warning disappeared immediately.

For anyone else running into this: it’s an easy mistake to make, since literally every other config option in Kirby is set as an array entry inside return [...], so it’s natural to assume this one works the same way. Might be worth adding a short note on the security guide page itself (not just the cookie reference page) clarifying that this specific option uses different syntax than the rest — that’s where most people will land first when following the security recommendations.

Thanks again for the quick help!

There are more static props that work like that, not just the cookie setting.