PAP-5-01 | §5 | MUST | personal-agent | When it does, the Personal Agent MUST join its browser to a Session before browsing the Company's website. | BrowserSessionClient.join | test_browser.py::test_posts_and_verifies_browser_assertion_once
lifecycle.browser-joins-session | implemented |
PAP-5-02 | §5 | MUST | personal-agent | return_to is the page to open afterward. It MUST be an HTTPS URL on the Company's organization.domain or one of its subdomains. | _company_return_to
build_browser_assertion_claims | test_browser.py::test_builds_short_lived_company_bound_claims | implemented |
PAP-5-03 | §5 | MUST | personal-agent | The assertion MUST go in the request body, never in the URL. | BrowserSessionClient.join
BROWSER_FORM_POSTS | test_browser.py::test_posts_and_verifies_browser_assertion_once
lifecycle.browser-joins-session | implemented |
PAP-5-04 | §5 | MUST | personal-agent | The Personal Agent MUST post browser assertions only from a browser it controls, never from the User's own browser, which would then be using the Personal Agent's Session. | BROWSER_FORM_POSTS
BROWSER_HANDOFFS | test_browser.py::test_posts_and_verifies_browser_assertion_once | implemented |
PAP-5-05 | §5 | MUST | company | The Company MUST check that: The signature verifies with a key from the iss client's jwks_uri, and typ is poppy-browser+jwt. A Session assertion isn't accepted here, and a browser assertion isn't accepted at the token endpoint. | verify_browser_assertion
CompanyService._browser_session | test_browser.py::test_posts_and_verifies_browser_assertion_once
test_browser.py::test_rejects_wrong_type_owner_and_expiry
test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-assertion-refused
security.browser-assertion-at-token-endpoint | implemented |
PAP-5-06 | §5 | MUST | company | The Company MUST check that: aud is its endpoint, the assertion hasn't expired, and exp is no more than 60 seconds after iat. | verify_browser_assertion
CompanyService._browser_session | test_browser.py::test_posts_and_verifies_browser_assertion_once
test_browser.py::test_rejects_wrong_type_owner_and_expiry
test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-assertion-refused | implemented |
PAP-5-07 | §5 | MUST | company | The Company MUST check that: It hasn't accepted the same jti before. | verify_browser_assertion
CompanyService._browser_session | test_browser.py::test_posts_and_verifies_browser_assertion_once
test_browser.py::test_rejects_wrong_type_owner_and_expiry
test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-assertion-refused | implemented |
PAP-5-08 | §5 | MUST | company | The Company MUST check that: The Session is active and belongs to the same client_id and User. | verify_browser_assertion
CompanyService._browser_session | test_browser.py::test_posts_and_verifies_browser_assertion_once
test_browser.py::test_rejects_wrong_type_owner_and_expiry
test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-assertion-refused | implemented |
PAP-5-09 | §5 | MUST | company | The Company MUST check that: return_to is on its own domain. | verify_browser_assertion
CompanyService._browser_session | test_browser.py::test_posts_and_verifies_browser_assertion_once
test_browser.py::test_rejects_wrong_type_owner_and_expiry
test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-assertion-refused | implemented |
PAP-5-10 | §5 | MUST | company | The cookie MUST follow the Session's current state: when the Session signs in or out, or its scopes change, the website reflects it on the next request. | CompanyService._web_session
CompanyService._live_session | test_mcp_and_web.py::test_the_website_follows_the_session_and_refuses_bad_assertions
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-joins-session | implemented |
PAP-5-11 | §5 | MUST NOT | company | The cookie MUST NOT outlive the Session. | CompanyService._web_session
CompanyService._browser_session | test_mcp_and_web.py::test_the_operation_confirmed_on_the_website_is_the_same_operation_once
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-joins-session | implemented |
PAP-5-12 | §5 | MUST | company | The cookie MUST be Secure and HttpOnly, and use SameSite=Lax or None, not Strict. | CompanyService._browser_session | test_mcp_and_web.py::test_the_operation_confirmed_on_the_website_is_the_same_operation_once
test_conformance.py::test_python_agent_python_company_over_tls
lifecycle.browser-joins-session | implemented |