Sign-in and Account Tokens coverage
Sign-in modes, consent, Account Tokens, and sign-out (§4.4 to §4.9). Upstream: personalagentprotocol.org/docs/spec.
22 entries: 17 implemented, 2 partial, 2 open, 1 not-applicable. Each row is one atomic statement of the upstream text, with the SDK symbols that implement it (Python; TypeScript mirrors them), the tests and shared conformance cases that show it, and its status.
| ID | Section | Level | Role | Requirement | SDK symbol | Tests | Status |
|---|---|---|---|---|---|---|---|
PAP-4.4-01 | §4.4 | MUST | personal-agent | The types work on trust: a Personal Agent MUST use direct or Device Sign-In only when the User signs in themselves. | DirectSignInClient.beginDeviceSignInClient.begin | test_direct_and_api.py::test_signed_out_then_direct_sign_in_then_a_read_and_a_proposed_exchangetest_device.py::test_device_sign_in_paces_polling_and_protects_tokens | implemented |
PAP-4.4-02 | §4.4 | MUST NOT | company | The Company MUST NOT grant scopes beyond those requested and allowed for the type used. | CompanyService.approve_deviceCompanyService.approve_authorizationCompanyService._refresh_grantCompanyService._mediated | test_direct_and_api.py::test_partial_consent_and_a_write_that_was_not_grantedtest_conformance.py::test_python_agent_python_company_over_tlslifecycle.sign-in-scopeslifecycle.wider-scopes-refused | implemented |
PAP-4.4-03 | §4.4 | MUST | personal-agent | Each sign-in request MUST include scope as a space-separated string, following OAuth scope syntax. | _scopesDeviceSignInClient.beginMediatedSignInClient.sign_in | test_auth.py::test_builds_direct_sign_in_url_with_s256_pkcetest_conformance.py::test_python_agent_python_company_over_tlslifecycle.sign-in-scopeslifecycle.unknown-scope-refused | implemented |
PAP-4.4-04 | §4.4 | SHOULD | personal-agent | The new Account Token replaces the old one, which the Personal Agent SHOULD revoke (4.9). | AccountTokenClient.revoke | — | open: No helper replaces and revokes the previous Account Token after a wider sign-in; the host calls revoke(). |
PAP-4.4-05 | §4.4 | SHOULD | personal-agent | Before starting a new sign-in, the Personal Agent SHOULD check whether it already holds an Account Token that covers the task (4.8). | — | — | open: No helper maps a task's scopes to a held Account Token; the host decides. |
PAP-4.5-01 | §4.5 | MUST | company | redirect_uri MUST exactly match an entry in the Personal Agent's redirect_uris (4.1). | CompanyService._authorizeCompanyService._code_grant | test_direct_and_api.py::test_the_consent_page_is_never_framed_and_bad_redirects_are_not_followed | implemented |
PAP-4.5-02 | §4.5 | MUST | personal-agent | The Personal Agent checks state, and MUST check that iss exactly matches the auth.issuer of the Company it started sign-in with. | validate_direct_sign_in_callback | test_auth.py::test_validates_callback_and_redacts_code_exchangetest_auth.py::test_rejects_invalid_callbacks | implemented |
PAP-4.6-01 | §4.6 | MUST NOT | company | Opening the link MUST NOT approve the request by itself. | CompanyService.approve_device | test_company_end_to_end.py::test_a_user_and_a_company_from_question_to_confirmed_exchange | implemented |
PAP-4.7-01 | §4.7 | MUST | personal-agent | secret marks a value the Personal Agent MUST protect: never shown back to the User, written to logs, or sent anywhere else. | MediatedSignInClientPROTECTED_INPUTS | test_mediated.py::test_the_declared_fields_go_to_the_endpoint_and_the_session_is_signed_intest_mediated.py::test_a_one_time_code_continues_without_the_credentials | implemented |
PAP-4.7-02 | §4.7 | MUST | company | A Company that offers Mediated Sign-In MUST rate-limit attempts, MUST NOT return credentials in any response, and SHOULD require a one-time code when a sign-in looks unusual. | CompanyService._mediated_code | test_company_end_to_end.py::test_mediated_sign_in_with_a_one_time_code | partial: Wrong one-time codes are capped (max_code_attempts); credential attempts are not yet rate-limited by account, client_id, or user. |
PAP-4.7-03 | §4.7 | MUST NOT | company | A Company that offers Mediated Sign-In MUST rate-limit attempts, MUST NOT return credentials in any response, and SHOULD require a one-time code when a sign-in looks unusual. | CompanyService._mediated | test_company_end_to_end.py::test_mediated_sign_in_with_a_one_time_codetest_conformance.py::test_python_agent_python_company_over_tlssecurity.refusals-disclose-no-credential | implemented |
PAP-4.7-04 | §4.7 | SHOULD | company | A Company that offers Mediated Sign-In MUST rate-limit attempts, MUST NOT return credentials in any response, and SHOULD require a one-time code when a sign-in looks unusual. | AccountDirectory.authenticateCompanyService._mediated | test_company_end_to_end.py::test_mediated_sign_in_with_a_one_time_code | implemented |
PAP-4.7-05 | §4.7 | MUST NOT | personal-agent | Personal Agents MUST NOT send credentials to any endpoint other than the Company's auth.mediated.endpoint. | MediatedSignInClient._endpoint_on_company_domainMediatedSignInClient._post | test_mediated.py::test_a_redirect_never_carries_the_credentials_elsewheretest_mediated.py::test_an_endpoint_off_the_company_domain_is_refused_before_asking | implemented |
PAP-4.8-01 | §4.8 | MUST | company | Companies MUST accept an Account Token only at their token_endpoint and revocation_endpoint, and only from the client_id it was issued to, authenticated by its client assertion. | CompanyService._refresh_grantCompanyService._revokeCompanyService._caller | test_conformance.py::test_python_agent_python_company_over_tlslifecycle.account-token-signs-in-new-sessionlifecycle.narrower-scopeslifecycle.account-token-at-api | implemented |
PAP-4.8-02 | §4.8 | MUST | company | Companies MUST accept an Account Token only at their token_endpoint and revocation_endpoint, and only from the client_id it was issued to, authenticated by its client assertion. | CompanyService._clientCompanyService._refresh_grant | test_conformance.py::test_python_agent_python_company_over_tlslifecycle.account-token-from-another-clientsecurity.client-assertion-bad-audience | implemented |
PAP-4.8-03 | §4.8 | MUST | company | The Session MUST belong to the same client_id and User ID as the Account Token, and be signed out or signed in to the same account. | CompanyService._refresh_grant | test_conformance.py::test_python_agent_python_company_over_tlslifecycle.renew-for-another-userlifecycle.account-token-for-another-users-session | implemented |
PAP-4.8-04 | §4.8 | MUST | company | The Session MUST belong to the same client_id and User ID as the Account Token, and be signed out or signed in to the same account. | CompanyService._refresh_grantCompanyService._sign_in | test_conformance.py::test_python_agent_python_company_over_tlslifecycle.account-mismatch | implemented |
PAP-4.8-05 | §4.8 | MUST | personal-agent | A Company MAY return a new Account Token in refresh_token. The Personal Agent then MUST use the new one from then on. | AccountTokenClient.refresh | test_accounts.py::test_refresh_signs_the_session_in_and_rotates_the_stored_tokentest_accounts.py::test_concurrent_refreshes_rotate_one_after_the_othertest_conformance.py::test_python_agent_python_company_over_tlslifecycle.rotated-tokenlifecycle.sign-out-every-session | implemented |
PAP-4.8-06 | §4.8 | MUST | personal-agent | Personal Agents MUST store Account Tokens as secrets, and MUST NOT put them in model context, conversation messages, logs, or URLs. | TokenStoreDeviceSignInClient._completeDirectSignInClient._resultMediatedSignInClient._complete | test_device.py::test_device_sign_in_paces_polling_and_protects_tokenstest_auth.py::test_orchestrates_one_use_direct_sign_in_with_nonce_and_partial_scopes | implemented |
PAP-4.8-07 | §4.8 | MUST NOT | personal-agent | Personal Agents MUST store Account Tokens as secrets, and MUST NOT put them in model context, conversation messages, logs, or URLs. | AccountTokenClientAccountRefreshResultDirectSignInClient._resultDeviceSignInClient._completeMediatedSignInClient._complete | test_accounts.py::test_no_error_carries_the_account_tokentest_auth.py::test_orchestrates_one_use_direct_sign_in_with_nonce_and_partial_scopes | partial: Results and errors never carry the token, but no test yet proves logs and traces stay free of credentials (plan §2). |
PAP-4.9-01 | §4.9 | SHOULD | company | Companies SHOULD check on each request whether the Session is still signed in, so sign-out takes effect right away. | CompanyService._revokeCompanyService.disconnectCompanyService._caller | test_company_store.py::test_a_company_restarted_over_its_store_continues_every_flowtest_conformance.py::test_python_agent_python_company_over_tlslifecycle.sign-out-takes-effectlifecycle.sign-out-session-continueslifecycle.sign-out-every-sessionlifecycle.mcp-sign-out-takes-effect | implemented |
PAP-4.9-02 | §4.9 | SHOULD | company | A Company that doesn't SHOULD use much shorter Session Token lifetimes, such as a few minutes. | — | — | not-applicable: The reference company checks on each request (PAP-4.9-01). |
Conformance case IDs name protocol/fixtures/conformance cases; see the conformance report for their outcome in every language pairing.