# RFC: Cookies Having Independent Partitioned State (CHIPS)

- Status: Implemented (PHP 8.5)
- Authors: Dmitrii Derepko, xepozzd@gmail.com; Niels Dossche, dossche.niels@gmail.com
- Date: 2025-07-12
- Version: 0.9.1
- Implementation: https://github.com/php/php-src/pull/12652 & https://github.com/php/php-src/commit/1bba07ecc065a281ddb3a0ad81c923874882825b
- Original: https://wiki.php.net/rfc/chips
- Page: https://externals.io/rfc/chips
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Implement CHIPS as outlined in the RFC? (closed)

Yes: 25 · No: 0

Voters: asgrim (Yes), ashnazg (Yes), ayesh (Yes), cmb (Yes), crell (Yes), daniels (Yes), derick (Yes), devnexen (Yes), dunglas (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), josh (Yes), kalle (Yes), mauricio (Yes), narf (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), pmjones (Yes), ramsey (Yes), sergey (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

## Discussions on the mailing list

- [\[RFC\] \[Discussion\] CHIPS](https://externals.io/message/128047.md) — started on 2025-07-15, 5 messages
- [\[VOTE\] \[RFC\] Cookies Having Independent Partitioned State (CHIPS)](https://externals.io/message/128301.md) — started on 2025-07-29, 2 messages

---

## 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 [MDN](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies):

> 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 [Safari 18.4 (released recently)](https://webkit.org/blog/16574/webkit-features-in-safari-18-4/).

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.

```php
<?php
 
setcookie('name', 'value', ['secure' => 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:

```php
<?php
 
setcookie("name", "value", ["secure" => true, "partitioned" => true]);
 
// will result in headers:
// Set-Cookie: name=value; secure; Partitioned
 
?>
```

Example 2: Using “partitioned” without “secure” or with disabled “secure” option:

```php
<?php
 
setcookie("name", "value", ["partitioned" => 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:

```php
<?php
 
session_id("12345");
session_set_cookie_params(["secure" => 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:

```php
<?php
 
session_set_cookie_params([
  "secure" => 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:

```php
<?php
 
var_dump(session_start(["cookie_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

1. 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`.
2. 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.

**Vote: Implement CHIPS as outlined in the RFC?** — Yes: 25 · No: 0 (closed)

## Patches and Tests

Implementation (patch+test): <https://github.com/php/php-src/pull/12652>

## Implementation

Merged into PHP 8.5 via <https://github.com/php/php-src/commit/1bba07ecc065a281ddb3a0ad81c923874882825b>

## References

CHIPS MDN: [https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy\_sandbox/Partitioned\_cookies](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.
