====== PHP RFC: Cookies Having Independent Partitioned State (CHIPS) ======
* Version: 0.9.1
* Date: 2025-07-12
* Author: Dmitrii Derepko, xepozzd@gmail.com; Niels Dossche, dossche.niels@gmail.com
* Status: Voting
* Implementation: https://github.com/php/php-src/pull/12652
===== Introduction =====
Modern browsers have several security levels to separate cross-site communications, including various settings to how cookies should behave across the sites.
CHIPS is best explained by the description on [[https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies|MDN]]:
Cookies Having Independent Partitioned State (CHIPS, also known as Partitioned cookies) allows developers to opt a cookie into partitioned storage, with a separate cookie jar per top-level site.
Without cookie partitioning, third-party cookies can enable services to track users and associate their information across unrelated top-level sites. Cookies marked Partitioned are double-keyed: by the origin that sets them and the origin of the top-level page.
CHIPS is necessary to keep cross-site cookies working properly, as Google Chrome has been phasing third-party cookies out for some time now.
CHIPS technology was introduced not so long ago, but still has "little" adoption (currently "only" available in Blink-based or Gecko-based browsers).
Prior to Firefox 141, it was temporarily disabled due to web compatibility issues. Starting with Firefox 141, the feature is fully enabled. The feature is also implemented in [[https://webkit.org/blog/16574/webkit-features-in-safari-18-4/|Safari 18.4 (released recently)]].
CHIPS implementation introduces a new Cookie parameter named //Partitioned//, which should be applied during //Secure// context.
This RFC proposes two groups of changes:
1. Adding a new option "partitioned" for setcookie() and setrawcookie() functions.
true, 'partitioned' => true]);
?>
Notably, only the array overload of these functions is affected. This is in a similar vain to the recent ''samesite'' addition that also was only added to the array overload.
2. Add support for partitioned session cookies. This means that session_set_cookie_params(), session_get_cookie_params(), and session_start() will receive support for partitioned cookies.
Currently, frameworks and applications have to work around not having this option by manually setting a header, which is cumbersome.
This feature was requested via https://github.com/php/php-src/issues/12646, and has seen some activity and workarounds being posted.
===== Proposal =====
Extend setcookie() and setrawcookie() functions and make them able to accept one more option named "partitioned" to control CHIPS behavior.
Using "partitioned" without setting "secure" will throw a ValueError.
Extend session_start() options with "cookie_partitioned", and session_set_cookie_params()'s array overload to support the "partitioned" key. Also update the returned array from session_get_cookie_params() to include the "partitioned" key with a boolean value.
==== Examples ====
Example 1: Regular CHIPS usage:
true, "partitioned" => true]);
// will result in headers:
// Set-Cookie: name=value; secure; Partitioned
?>
Example 2: Using "partitioned" without "secure" or with disabled "secure" option:
true]);
setcookie("name", "value", ["secure" => false, "partitioned" => true]);
// Both raise a ValueError:
// Uncaught ValueError: setcookie(): "partitioned" option cannot be used without "secure" option in ...
?>
Example 3: Starting a session with partitioned cookies:
true, "partitioned" => true]);
session_start();
// will result in headers:
// Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned
?>
Example 4: Setting the session cookie settings and dumping those settings:
true,
"partitioned" => true
]);
var_dump(session_get_cookie_params());
// will dump this array:
// array(7) {
// ["lifetime"]=>
// int(0)
// ["path"]=>
// string(1) "/"
// ["domain"]=>
// string(0) ""
// ["secure"]=>
// bool(true)
// ["partitioned"]=>
// bool(true)
// ["httponly"]=>
// bool(false)
// ["samesite"]=>
// string(0) ""
// }
?>
Example 5: Configuring the session with partitioned, but not secure:
false, "cookie_partitioned" => true])); // bool(false)
// Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in ...
?>
The reason we defer the check until the session is started, is because any combination of ini_set(), session_start(), session_set_cookie_params() can set //some// cookie settings.
===== Backward Incompatible Changes =====
No breaking changes.
===== Proposed PHP Version(s) =====
PHP 8.5
===== RFC Impact =====
==== To the Ecosystem ====
No effects.
==== To Existing Extensions ====
- ext/standard, as the existing setcookie() and setrawcookie() PHP APIs are contained there. Furthermore, there is an internal API ''php_setcookie'' for C extensions that now gets an additional boolean argument ''partitioned''.
- ext/session, as described above.
==== To SAPIs ====
An additional cookie parameter is introduced, but it has no direct API influence on the SAPI layer.
==== php.ini Defaults ====
The session cookie settings for session_start() and session_set_cookie_params() are stored in INI settings. These functions internally modify the session INI settings for the lifetime of the request. For example, using session_start(["cookie_secure" => true]) will set the ''session.cookie_secure'' setting to true. Likewise, we will add a ''session.cookie_partitioned'' boolean setting that defaults to false, but can be set via the above-mentioned functions. It is also possible to default this setting to true in the php.ini if one desires to do so.
===== Open Issues =====
No issues.
===== Future Scope =====
Currently, there is no future scope. Any CHIPS evolution steps will be made separately.
===== Voting Choices =====
Single voting widget that requires 2/3rd majority.
* Yes
* No
===== Patches and Tests =====
Implementation (patch+test): https://github.com/php/php-src/pull/12652
===== Implementation =====
After the RFC is implemented, this section should contain:
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
===== References =====
CHIPS MDN: https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies
===== Rejected Features =====
None yet.
===== Changelog =====
Version 0.9.1: Extra clarifications on non-Blink browsers, thanks Claude!
Version 0.9: First version.