From 7fb5855f14f7a48480b4f83da56bfeee7729f266 Mon Sep 17 00:00:00 2001 From: w Date: Wed, 21 Oct 2026 09:55:26 +0000 Subject: [PATCH] test: use a secret-shaped fake credential in redaction tests (1/2) Tests that use an AWS access key ID as their stand-in for "a credential" now use a fake token the redactor treats as a secret (a GitLab- or Slack-shaped fake, or a labelled fake secret key). No product code changes; every test passes on main before and after. --- src/kiro_crew/testing/fake_computer_use.py | 10 +- test/conftest.py | 12 +- test/discord_resumed_busy_helpers.py | 2 +- test/markdown_link_parentheses_helpers.py | 8 +- test/member_memory_helpers.py | 2 +- test/metrics/test_recorder.py | 2 +- test/metrics/test_telemetry_titles.py | 8 +- test/split_credential_boundary_helpers.py | 2 +- test/telegram_parity_helpers.py | 2 +- test/test_acp_client.py | 22 +-- test/test_acp_client_commands.py | 4 +- test/test_acp_client_inbound.py | 8 +- test/test_acp_client_model_substitution.py | 20 +- test/test_acp_client_prompt_turn.py | 10 +- test/test_acp_client_tool_call_updates.py | 26 +-- test/test_acp_client_tool_events.py | 4 +- test/test_acp_client_tool_hooks.py | 16 +- test/test_acp_mcp_ref_guard.py | 8 +- test/test_acp_refactor_error_surface.py | 2 +- test/test_acp_runtime_compaction.py | 4 +- test/test_acp_runtime_dispatch_updates.py | 4 +- test/test_acp_runtime_permission_trust.py | 4 +- test/test_acp_runtime_unroutable_frames.py | 6 +- test/test_acp_session_handle_capabilities.py | 4 +- .../test_acp_session_handle_stream_command.py | 2 +- test/test_acp_structured_refusal.py | 6 +- test/test_agent_panel_routes_allocation.py | 2 +- test/test_agent_panel_store.py | 4 +- test/test_agent_spec_safety.py | 6 +- test/test_agent_sync_prune.py | 2 +- test/test_agent_templates_endpoint.py | 10 +- test/test_agent_welcome_message.py | 2 +- test/test_agents_roster_contract.py | 12 +- test/test_api_file_diff.py | 6 +- test/test_api_hook_test_stop_payload.py | 2 +- test/test_api_tasks.py | 2 +- test/test_artifact_comment_handlers.py | 6 +- test/test_artifact_materialize.py | 4 +- test/test_artifact_merge_remote_comments.py | 2 +- test/test_artifacts_handlers_coverage.py | 24 +-- test/test_artifacts_handlers_update.py | 8 +- test/test_ask_question_roundtrip.py | 2 +- test/test_auto_research.py | 8 +- test/test_auto_research_http.py | 34 ++-- test/test_auto_research_watchdog.py | 4 +- test/test_autonudge.py | 6 +- test/test_autonudge_authz_cov80.py | 6 +- test/test_autonudge_banner.py | 24 +-- test/test_autonudge_fingerprint.py | 12 +- test/test_autonudge_handlers_cov80.py | 4 +- test/test_autonudge_quarantine_sidecar.py | 2 +- test/test_autonudge_refactor_contract.py | 4 +- test/test_autonudge_wake_judge_point.py | 8 +- test/test_aws_consent.py | 4 +- test/test_aws_control_app.py | 4 +- test/test_aws_control_app_hardening.py | 14 +- test/test_aws_control_backup_conversations.py | 10 +- test/test_aws_control_backup_ownership.py | 4 +- test/test_aws_control_backup_retry_backoff.py | 12 +- test/test_aws_control_library.py | 4 +- test/test_aws_control_routes.py | 14 +- test/test_builtin_app_lifecycle.py | 4 +- test/test_capability_agents_plugins.py | 10 +- test/test_channel_send_target.py | 12 +- test/test_channel_slots.py | 8 +- test/test_chat_backfill.py | 10 +- test/test_chat_follow_default.py | 4 +- test/test_chat_mirror_link_delivery.py | 2 +- ...t_chat_persistence_composition_contract.py | 4 +- test/test_chat_regenerate_cov80.py | 12 +- test/test_chat_runner_coverage.py | 17 +- test/test_chat_runner_coverage_output.py | 38 ++-- test/test_chat_runner_coverage_turn_start.py | 4 +- test/test_chat_steer.py | 2 +- test/test_chat_tags.py | 12 +- test/test_chat_threads.py | 8 +- test/test_chat_utils.py | 36 ++-- test/test_cli_chat_consent_surface.py | 2 +- test/test_cli_chat_permission.py | 4 +- test/test_cli_doctor_member_memory.py | 8 +- test/test_command_surface_fixes.py | 6 +- test/test_computer_use_policy_cov80.py | 2 +- test/test_conductor_base_work_ledger.py | 2 +- test/test_config_agent_fields_redaction.py | 12 +- test/test_connections_mint_flow.py | 26 +-- test/test_connections_warm_activation.py | 2 +- test/test_core_path_redact_before_bound.py | 4 +- test/test_cpp_wiring_enterprise_wave2.py | 4 +- test/test_crew_log_emit_continuity.py | 4 +- test/test_crew_routing_and_delegation.py | 2 +- test/test_crew_teams.py | 2 +- test/test_crew_turn_proxy_reply.py | 14 +- test/test_cron_channel_delivery.py | 10 +- test/test_cron_script.py | 38 ++-- test/test_cron_script_sessions.py | 2 +- test/test_cron_secret_env_grant_endpoint.py | 10 +- test/test_cron_turn_stats_footer.py | 2 +- test/test_cross_surface_mirror.py | 10 +- test/test_dashboard.py | 20 +- test/test_dashboard_approval.py | 4 +- test/test_dashboard_chat.py | 8 +- test/test_dashboard_chat_compaction.py | 4 +- test/test_dashboard_chat_fork.py | 10 +- test/test_dashboard_chat_pagination_suffix.py | 4 +- test/test_dashboard_chat_pins.py | 8 +- test/test_dashboard_chat_prompt_prep.py | 2 +- test/test_dashboard_chat_regenerate.py | 10 +- test/test_dashboard_chat_segments.py | 20 +- test/test_dashboard_chat_tool_calls.py | 6 +- test/test_dashboard_chat_unflushed_tail.py | 2 +- test/test_dashboard_cron_script_source.py | 12 +- test/test_dashboard_files_coverage.py | 6 +- ...oard_handlers_core_coverage_stt_runtime.py | 4 +- test/test_dashboard_save_tool.py | 2 +- test/test_dashboard_tools.py | 10 +- test/test_decisions_compaction_keep.py | 2 +- test/test_decisions_judge_llm.py | 2 +- test/test_decisions_memory_recall.py | 4 +- test/test_decisions_message_steer.py | 10 +- test/test_decisions_points.py | 3 +- test/test_decisions_tool_risk.py | 8 +- test/test_deny_bounded_write.py | 4 +- test/test_deploy_round19_fixes.py | 12 +- test/test_deploy_round6_fixes.py | 16 +- test/test_deploy_round8_fixes.py | 10 +- test/test_deploy_web_handlers.py | 16 +- test/test_deploy_web_profiles.py | 14 +- test/test_design_tweak_backend.py | 2 +- test/test_design_tweak_backend_queue.py | 6 +- test/test_design_tweak_devproc.py | 2 +- test/test_dev_fleet_app_sync.py | 4 +- test/test_dev_fleet_app_worktrees.py | 2 +- test/test_diag_procs.py | 18 +- test/test_diagnose_probes.py | 2 +- test/test_diagnostics.py | 2 +- ..._directive_refusal_not_lost_marker_8635.py | 2 +- test/test_discord_outbound_files.py | 14 +- test/test_discord_render_config.py | 2 +- test/test_discord_renderer.py | 37 ++-- test/test_discover_handlers_cov80.py | 4 +- test/test_display_split_safety.py | 54 +++--- test/test_display_time_redaction.py | 2 +- test/test_display_verdicts.py | 2 +- test/test_dynamic_dashboard.py | 6 +- test/test_dynamic_dashboard_cards.py | 43 ++--- test/test_ephemeral_sessions.py | 4 +- test/test_eval_subagent_deny_notice.py | 4 +- test/test_fargate_closed_forward_remedy.py | 6 +- test/test_file_change_snapshots.py | 18 +- test/test_file_grep.py | 30 +-- test/test_file_office_preview.py | 38 ++-- test/test_file_office_slides.py | 6 +- test/test_file_send_channel.py | 14 +- test/test_file_sheet.py | 2 +- test/test_file_stream.py | 4 +- test/test_followup_suggest.py | 4 +- test/test_gateway_appkit_endpoints_install.py | 4 +- test/test_gateway_appkit_endpoints_note.py | 6 +- test/test_git_repo_touches.py | 2 +- test/test_goal_setup.py | 2 +- test/test_governance_distribution.py | 2 +- .../test_governance_distribution_redaction.py | 8 +- test/test_handler_cron_list.py | 12 +- test/test_handler_turn.py | 2 +- test/test_handlers_artifacts_coverage.py | 16 +- test/test_handlers_memory_coverage.py | 2 +- test/test_heartbeat_prompt_deliver.py | 6 +- test/test_heartbeat_safe_tools.py | 4 +- test/test_history_auto_skills.py | 6 +- test/test_history_retention.py | 4 +- test/test_image_artifacts.py | 2 +- test/test_imessage_renderer.py | 14 +- test/test_inbound_unbind_notice.py | 2 +- test/test_instances_proxy_handler.py | 28 ++- test/test_instances_remote_update.py | 4 +- test/test_instances_search_federation.py | 2 +- test/test_instances_token_mint.py | 12 +- test/test_issue_radar_crew_mcp_tools.py | 12 +- test/test_lesson_contradiction.py | 8 +- test/test_markdown_link_parentheses.py | 176 +++++++++--------- ...est_markdown_link_parentheses_renderers.py | 34 ++-- ...st_markdown_link_parentheses_split_keys.py | 110 +++++------ test/test_memory_history_edit.py | 8 +- test/test_private_profile_error_response.py | 2 +- test/test_split_credential_boundary.py | 14 +- ...it_credential_boundary_channel_delivery.py | 2 +- ...test_split_credential_boundary_readings.py | 2 +- test/test_telegram_parity_turns.py | 4 +- test/test_telegram_renderer_split.py | 22 ++- test/test_wecom_renderer.py | 74 ++++---- 190 files changed, 1014 insertions(+), 980 deletions(-) diff --git a/src/kiro_crew/testing/fake_computer_use.py b/src/kiro_crew/testing/fake_computer_use.py index 27e641ea8ca..8244bd1684d 100644 --- a/src/kiro_crew/testing/fake_computer_use.py +++ b/src/kiro_crew/testing/fake_computer_use.py @@ -88,12 +88,10 @@ FAKE_IMAGE_HEIGHT = 1 # ── Redaction fixtures ── -# The canonical PUBLIC documentation access-key id (it appears verbatim in AWS's -# own docs and in this repo's redaction tests) plus two exfiltration-shaped URLs -# using IANA-reserved documentation ranges. None of these is a real credential or -# a reachable host; they exist so a test can assert that the rendered tree comes -# back MASKED. -FAKE_CREDENTIAL_FIXTURE = "AKIA" "IOSFODNN7EXAMPLE" +# A GitLab-shaped fake token plus two exfiltration-shaped URLs using IANA-reserved +# documentation ranges. None of these is a real credential or a reachable host; +# they exist so a test can assert that the rendered tree comes back MASKED. +FAKE_CREDENTIAL_FIXTURE = "glpat-" "IOSFODNN7EXAMPLE" FAKE_EXFIL_URL = ( "https://evil.example.com/collect?data=" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" diff --git a/test/conftest.py b/test/conftest.py index 744fe2e74a0..795adbb9fe7 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -390,19 +390,19 @@ def forget_env_at_teardown(monkeypatch, *names: str) -> None: #: a cut may fall (``test_display_split_safety.py``) and the renderer that applies #: it (``test_wecom_renderer.py``) -- and a duplicated fixture table drifts. CREDENTIAL_STRADDLE_SHAPES = [ - pytest.param("[AKIA](https://ex.test/a,b)", "IOSFODNN7EXAMPLE", id="link-target-comma"), + pytest.param("[glpat-](https://ex.test/a,b)", "IOSFODNN7EXAMPLE", id="link-target-comma"), pytest.param( "Authorization: Bearer", " abcdefghijklmnopqrstuvwxyz0123456789", id="header-whitespace", ), - pytest.param("AKIAIOSF_", "_ODNN7EXAMPLE", id="underscore-emphasis"), - pytest.param("AKIAIOSF~", "~ODNN7EXAMPLE", id="tilde-emphasis"), - pytest.param("https://evil.test/?q=AKIAIOSFODNN7", "EXAMPLE.", id="url-punctuation"), - pytest.param("[l](https://ex.test/x/AKIAIOSF", "ODNN7EXAMPLE)", id="cut-inside-a-url"), + pytest.param("glpat-IOSF_", "_ODNN7EXAMPLE", id="underscore-emphasis"), + pytest.param("glpat-IOSF~", "~ODNN7EXAMPLE", id="tilde-emphasis"), + pytest.param("https://evil.test/?q=glpat-IOSFODNN7", "EXAMPLE.", id="url-punctuation"), + pytest.param("[l](https://ex.test/x/glpat-IOSF", "ODNN7EXAMPLE)", id="cut-inside-a-url"), pytest.param(f"{_PEM_DASHES}BEGIN RSA PRIV", _PEM_TAIL_HALF, id="pem-anchor"), pytest.param(f"{_PEM_DASHES}BEG**IN** RSA PRIV", _PEM_TAIL_HALF, id="pem-anchor-markup-split"), - pytest.param("AKIAIOSF", "ODNN7EXAMPLE", id="no-markup-at-all"), + pytest.param("glpat-IOSF", "ODNN7EXAMPLE", id="no-markup-at-all"), ] diff --git a/test/discord_resumed_busy_helpers.py b/test/discord_resumed_busy_helpers.py index 1dce129ad56..fd057f803d7 100644 --- a/test/discord_resumed_busy_helpers.py +++ b/test/discord_resumed_busy_helpers.py @@ -18,7 +18,7 @@ # The refusal every case in the test_discord_resumed_busy*.py suites either avoids or keeps. _REFUSAL = "busy with a turn started elsewhere" # A credential the display redaction rewrites, inside otherwise ordinary text. -_SECRET = "AKIAIOSFODNN7EXAMPLE" +_SECRET = "glpat-IOSFODNN7EXAMPLE" _TYPED = f"use https://docs.example.com/page?key={_SECRET} for this" diff --git a/test/markdown_link_parentheses_helpers.py b/test/markdown_link_parentheses_helpers.py index 4184c1a594f..c30dd6ed5a6 100644 --- a/test/markdown_link_parentheses_helpers.py +++ b/test/markdown_link_parentheses_helpers.py @@ -58,7 +58,7 @@ def _regex_destination(rest: str) -> tuple[str | None, int]: #: The AWS example access key, split by a link so that only a reader who sees the #: link rendered away sees it whole. -_KEY = "AKIAIOSFODNN7EXAMPLE" +_KEY = "glpat-IOSFODNN7EXAMPLE" def _screen_readings(text: str) -> list[str]: @@ -79,12 +79,12 @@ def _discord_reader_sees(text: str) -> str: #: The trigger that makes ``redact_for_display`` emit the canonical form: a link #: whose url holds the key split by ``**``, whole on a plain-text sink only. -_URL_SPLIT_TRIGGER = f"[l](https://x/AKIA**{_KEY[4:]}**)" +_URL_SPLIT_TRIGGER = f"[l](https://x/glpat-**{_KEY[6:]}**)" def _nested_link(depth: int) -> str: - """``[AKIA](u)`` wrapped in *depth* more ``[...](u)`` links, one level per pass.""" - link = "[AKIA](u)" + """``[glpat-](u)`` wrapped in *depth* more ``[...](u)`` links, one level per pass.""" + link = "[glpat-](u)" for _ in range(depth): link = f"[{link}](u)" return link diff --git a/test/member_memory_helpers.py b/test/member_memory_helpers.py index 4227fc55bc9..a5555b32689 100644 --- a/test/member_memory_helpers.py +++ b/test/member_memory_helpers.py @@ -33,7 +33,7 @@ from kiro_crew.vector_memory import VectorMemoryStore, create_member_database, open_member_database #: A credential-shaped token for "sensitive document" fixtures. -DOCUMENT_CREDENTIAL = "AKIAIOSFODNN7EXAMPLE" +DOCUMENT_CREDENTIAL = "glpat-IOSFODNN7EXAMPLE" MEMBERS = ("alice", "bob") diff --git a/test/metrics/test_recorder.py b/test/metrics/test_recorder.py index e43b9e05835..b9c0e19aee3 100644 --- a/test/metrics/test_recorder.py +++ b/test/metrics/test_recorder.py @@ -79,7 +79,7 @@ def test_credential_attr_redacted(self): rec.counter( "kirocrew.test.count", 1, - attrs={"api_key": "AKIAIOSFODNN7EXAMPLE1", "safe": "ok"}, + attrs={"api_key": "glpat-IOSFODNN7EXAMPLE1", "safe": "ok"}, ) points = _data_points(reader) assert points, "metric should have recorded" diff --git a/test/metrics/test_telemetry_titles.py b/test/metrics/test_telemetry_titles.py index 5c07389fc1d..126b0797d7d 100644 --- a/test/metrics/test_telemetry_titles.py +++ b/test/metrics/test_telemetry_titles.py @@ -69,11 +69,11 @@ def _cost(*slot_keys: str) -> dict: async def test_a_credential_shaped_title_is_redacted(): # A real AWS-key shape. The scanner recognises it; the point is that this # endpoint runs the scanner at all. - leaked = "notes for AKIA" + "IOSFODNN7EXAMPLE" + leaked = "notes for glpat-" + "IOSFODNN7EXAMPLE" slots = {"chat-1-1": SimpleNamespace(display_title=leaked)} out = await _with_conversation_titles(_request(slots), _cost("chat-1-1")) title = out["conversations"][0]["title"] - assert "AKIA" + "IOSFODNN7EXAMPLE" not in title + assert "glpat-" + "IOSFODNN7EXAMPLE" not in title assert "REDACTED" in title @@ -188,7 +188,7 @@ async def test_a_transcript_without_an_explicit_title_yields_none(self, tmp_path @pytest.mark.asyncio async def test_a_persisted_title_is_redacted_like_a_live_one(self, tmp_path): - leaked = "notes for AKIA" + "IOSFODNN7EXAMPLE" + leaked = "notes for glpat-" + "IOSFODNN7EXAMPLE" log = ConversationLog(tmp_path) log.set_title(slot_transcript_key("chat-1-1"), leaked) @@ -196,7 +196,7 @@ async def test_a_persisted_title_is_redacted_like_a_live_one(self, tmp_path): _request({}, conversation_log=log), _cost("chat-1-1") ) title = out["conversations"][0]["title"] - assert "AKIA" + "IOSFODNN7EXAMPLE" not in title + assert "glpat-" + "IOSFODNN7EXAMPLE" not in title assert "REDACTED" in title @pytest.mark.asyncio diff --git a/test/split_credential_boundary_helpers.py b/test/split_credential_boundary_helpers.py index a50dc59ee3c..75dc2b25be2 100644 --- a/test/split_credential_boundary_helpers.py +++ b/test/split_credential_boundary_helpers.py @@ -15,7 +15,7 @@ #: AWS's own documented example key, the same fixture the display-safety tests #: use, so no real credential shape is introduced anywhere. -KEY = "AKIAIOSFODNN7EXAMPLE" +KEY = "glpat-IOSFODNN7EXAMPLE" HEAD, TAIL = KEY[:10], KEY[10:] SRC = Path(kiro_crew.__file__).parent diff --git a/test/telegram_parity_helpers.py b/test/telegram_parity_helpers.py index 45338c39c58..d17068534e9 100644 --- a/test/telegram_parity_helpers.py +++ b/test/telegram_parity_helpers.py @@ -23,7 +23,7 @@ from kiro_crew.telegram.transport import TELEGRAM_CAPABILITIES, TelegramInboundMessage # Split so the literal never appears whole in this file. -_AWS_KEY = "AKIA" + "IOSFODNN7EXAMPLE" +_AWS_KEY = "glpat-" + "IOSFODNN7EXAMPLE" @pytest.fixture(autouse=True) diff --git a/test/test_acp_client.py b/test/test_acp_client.py index f230cd56c6b..f68480b6d5d 100644 --- a/test/test_acp_client.py +++ b/test/test_acp_client.py @@ -540,20 +540,20 @@ def test_credentials_in_data_are_redacted(self): err = { "code": -32603, "message": "Internal error", - "data": "AccessDenied: AKIAIOSFODNN7EXAMPLE not authorized", + "data": "AccessDenied: glpat-IOSFODNN7EXAMPLE not authorized", } out = _format_acp_error(err) - assert "AKIAIOSFODNN7EXAMPLE" not in out + assert "glpat-IOSFODNN7EXAMPLE" not in out def test_credentials_in_unknown_dict_fallback_are_redacted(self): """The fallback path echoes raw dict — must still scrub secrets.""" err = { "code": -32000, "message": "weird upstream", - "data": "leak: AKIAIOSFODNN7EXAMPLE", + "data": "leak: glpat-IOSFODNN7EXAMPLE", } out = _format_acp_error(err) - assert "AKIAIOSFODNN7EXAMPLE" not in out + assert "glpat-IOSFODNN7EXAMPLE" not in out # The scrubbed placeholder proves redaction ran on this path. assert "REDACTED" in out # The surrounding provider text still reaches the user. @@ -591,14 +591,14 @@ def test_sensitive_content_emits_log_warning(self, caplog): err = { "code": -32000, "message": "weird upstream", - "data": "leak: AKIAIOSFODNN7EXAMPLE", + "data": "leak: glpat-IOSFODNN7EXAMPLE", } with caplog.at_level(logging.WARNING, logger="kiro_crew.acp.client"): _format_acp_error(err) warnings = [r for r in caplog.records if "sensitive content" in r.getMessage()] assert warnings, "expected a redaction warning to be logged" - assert "AKIAIOSFODNN7EXAMPLE" not in warnings[0].getMessage() + assert "glpat-IOSFODNN7EXAMPLE" not in warnings[0].getMessage() def test_internal_server_error_rewrite(self): """A transient 5xx from the backend must @@ -667,10 +667,10 @@ def test_transient_branch_does_not_leak_credentials(self): err = { "code": -32603, "message": "Internal error", - "data": "InternalServerError: leaked AKIAIOSFODNN7EXAMPLE please try again", + "data": "InternalServerError: leaked glpat-IOSFODNN7EXAMPLE please try again", } out = _format_acp_error(err) - assert "AKIAIOSFODNN7EXAMPLE" not in out + assert "glpat-IOSFODNN7EXAMPLE" not in out assert "transient error" in out.lower() def test_throttle_precedence_over_transient(self): @@ -990,9 +990,9 @@ def test_is_bounded_and_redacted(self): assert len(detail) == _COMPACTION_DETAIL_MAX_CHARS secret = compaction_failure_detail( - {"status": {"type": "failed", "error": "aws_secret_access_key=AKIAIOSFODNN7EXAMPLE"}} + {"status": {"type": "failed", "error": "aws_secret_access_key=glpat-IOSFODNN7EXAMPLE"}} ) - assert "AKIAIOSFODNN7EXAMPLE" not in secret + assert "glpat-IOSFODNN7EXAMPLE" not in secret def test_rejects_a_placeholder_reason(self): """A named reason of "error" is not a reason. KAS's summarization_failed @@ -1043,7 +1043,7 @@ def test_the_frame_is_redacted_before_it_reaches_the_log(self, caplog): import logging handle = self._bare_handle() - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" update = { "sessionUpdate": "session_info_update", "_meta": { diff --git a/test/test_acp_client_commands.py b/test/test_acp_client_commands.py index 88123a485dd..ffd3750d738 100644 --- a/test/test_acp_client_commands.py +++ b/test/test_acp_client_commands.py @@ -225,14 +225,14 @@ async def test_failed_with_a_credential_shaped_summary_is_redacted(self, tmp_pat method=METHOD_COMPACTION_STATUS, params={ "status": {"type": "failed"}, - "summary": "backend error: key AKIAIOSFODNN7EXAMPLE rejected", + "summary": "backend error: key glpat-IOSFODNN7EXAMPLE rejected", }, ) client._read_message = AsyncMock(return_value=msg) result = await client.wait_for_compaction(timeout=5.0) assert result["type"] == "failed" - assert "AKIAIOSFODNN7EXAMPLE" not in result["summary"] + assert "glpat-IOSFODNN7EXAMPLE" not in result["summary"] assert "[REDACTED: credential]" in result["summary"] @pytest.mark.asyncio diff --git a/test/test_acp_client_inbound.py b/test/test_acp_client_inbound.py index 269a0e895c6..a885b42afe3 100644 --- a/test/test_acp_client_inbound.py +++ b/test/test_acp_client_inbound.py @@ -1078,7 +1078,7 @@ class TestDrainStderrRedaction: @pytest.mark.asyncio async def test_raw_stored_redacted_logged(self): client = AcpClient() - raw = "Error: key=AKIAIOSFODNN7EXAMPLE connect failed" + raw = "Error: key=glpat-IOSFODNN7EXAMPLE connect failed" reader = AsyncMock(spec=["readline"]) reader.readline = AsyncMock(side_effect=[raw.encode() + b"\n", b""]) @@ -1090,7 +1090,7 @@ async def test_raw_stored_redacted_logged(self): assert list(client._stderr_lines) == [raw] # Logged call used redacted text (credential replaced) logged_text = mock_logger.warning.call_args[0][2] - assert "AKIAIOSFODNN7EXAMPLE" not in logged_text + assert "glpat-IOSFODNN7EXAMPLE" not in logged_text class TestDrainStderrSuppression: @@ -1177,14 +1177,14 @@ async def test_acperror_contains_redacted_stderr(self): client._process.returncode = 1 client._process.stdout = MagicMock() client._process.stdout.readline = AsyncMock(return_value=b"") - client._stderr_lines = deque(["secret key=AKIAIOSFODNN7EXAMPLE"]) + client._stderr_lines = deque(["secret key=glpat-IOSFODNN7EXAMPLE"]) client._stderr_task = MagicMock() client._stderr_task.done.return_value = True with pytest.raises(AcpError, match="ACP process exited") as exc_info: await client._read_message(timeout=1.0) - assert "AKIAIOSFODNN7EXAMPLE" not in str(exc_info.value) + assert "glpat-IOSFODNN7EXAMPLE" not in str(exc_info.value) class TestTrackMetadataCredits: diff --git a/test/test_acp_client_model_substitution.py b/test/test_acp_client_model_substitution.py index 56d73640a2c..95fb271aeb8 100644 --- a/test/test_acp_client_model_substitution.py +++ b/test/test_acp_client_model_substitution.py @@ -557,11 +557,11 @@ async def test_new_session_following_substitution_redacts_log_payload(self, tmp_ # Inject a substitute that embeds an AWS access-key-shaped substring # so the dual redactor heuristic actually fires (redact_exfiltration_urls - # matches the URL because the query carries an AKIA token, and - # redact_credentials matches the standalone AKIA pattern). A bare + # matches the URL because the query carries a glpat- token, and + # redact_credentials matches the standalone glpat- pattern). A bare # arbitrary URL is too tame for the heuristic and would leave the test # asserting on a no-op pass-through. - url_shaped = "http://attacker.example.com/exfil?token=AKIAIOSFODNN7EXAMPLE" + url_shaped = "http://attacker.example.com/exfil?token=glpat-IOSFODNN7EXAMPLE" sent: list[str] = [] @@ -598,7 +598,7 @@ async def _wait(req_id, timeout=0.0, *, method="", expected_mcp=None): # inside "[REDACTED: suspicious URL to ]" so operators can # investigate the leak source -- that is BY DESIGN, not a bypass. assert ( - "AKIAIOSFODNN7EXAMPLE" not in emitted + "glpat-IOSFODNN7EXAMPLE" not in emitted ), "AWS access-key substring MUST be redacted before logging" assert ( "REDACTED" in emitted @@ -620,7 +620,7 @@ async def test_initialize_session_redacts_model_in_info_log(self, tmp_path): client._process.returncode = None # AWS access-key-shaped substring guarantees both redactors fire (URL # query matches _EXFIL_PATTERNS; standalone key matches _CREDENTIAL_PATTERNS). - client._model = "http://attacker.example.com/m?token=AKIAIOSFODNN7EXAMPLE" + client._model = "http://attacker.example.com/m?token=glpat-IOSFODNN7EXAMPLE" async def _send(method, params): return 1 @@ -658,7 +658,7 @@ async def _drain(): # See sibling test for the design note: redactor keeps the host as a # diagnostic label inside "[REDACTED: suspicious URL to ]". assert ( - "AKIAIOSFODNN7EXAMPLE" not in emitted_model + "glpat-IOSFODNN7EXAMPLE" not in emitted_model ), "AWS access-key substring MUST be redacted before logging" assert ( "REDACTED" in emitted_model @@ -694,7 +694,7 @@ async def _no_session_with_credshaped(*args, **kwargs): # Helper adopted a credential-shaped substitute then gave up without # producing a sessionId. Drives the "even after adopting substitute # model X" branch where X is credential-shaped. - client._model = "AKIAIOSFODNN7EXAMPLE" + client._model = "glpat-IOSFODNN7EXAMPLE" return {} client._new_session_following_substitution = _no_session_with_credshaped # type: ignore[assignment] @@ -704,7 +704,7 @@ async def _no_session_with_credshaped(*args, **kwargs): msg = str(excinfo.value) assert ( - "AKIAIOSFODNN7EXAMPLE" not in msg + "glpat-IOSFODNN7EXAMPLE" not in msg ), "AWS access-key-shaped substitute MUST be redacted before reaching the AcpError message" assert "even after adopting substitute model" in msg @@ -718,7 +718,7 @@ async def test_wait_for_response_catchall_raise_redacts_msg_error(self, tmp_path real_err = { "code": -32603, "message": "Internal error", - "data": "request_id: AKIAIOSFODNN7EXAMPLE backend trace failed", + "data": "request_id: glpat-IOSFODNN7EXAMPLE backend trace failed", } msg = MagicMock() msg.is_response_for.return_value = True @@ -736,7 +736,7 @@ async def _one_message(timeout=0.0): await client._wait_for_response(13, timeout=1.0) emitted = str(excinfo.value) - assert "AKIAIOSFODNN7EXAMPLE" not in emitted, ( + assert "glpat-IOSFODNN7EXAMPLE" not in emitted, ( "AWS access-key-shaped substring in msg.error MUST be redacted " "before reaching the catch-all AcpError message" ) diff --git a/test/test_acp_client_prompt_turn.py b/test/test_acp_client_prompt_turn.py index 9a2cec9fe3f..c9acd5e20a4 100644 --- a/test/test_acp_client_prompt_turn.py +++ b/test/test_acp_client_prompt_turn.py @@ -917,7 +917,7 @@ async def test_dispatch_redacts_and_extracts_subagent_output(self): "update": { "sessionUpdate": "tool_call_chunk", "toolCallId": "tc-1", - "title": "leak AKIAIOSFODNN7EXAMPLE now", + "title": "leak glpat-IOSFODNN7EXAMPLE now", }, } ), @@ -930,7 +930,7 @@ async def test_dispatch_redacts_and_extracts_subagent_output(self): "sessionId": "s1", "update": { "sessionUpdate": "agent_message_chunk", - "content": {"text": "secret AKIAIOSFODNN7EXAMPLE here"}, + "content": {"text": "secret glpat-IOSFODNN7EXAMPLE here"}, }, } ), @@ -951,13 +951,13 @@ async def _fake_loop(req_id, timeout): acts = [e for e in events if e.kind == EVENT_SUBAGENT_ACTIVITY] tc = [a for a in acts if a.tool_call_id == "tc-1"] txt = [a for a in acts if a.text] - # Title redacted (credential scrubbed, no raw AKIA leaks through). + # Title redacted (credential scrubbed, no raw glpat- leaks through). assert len(tc) == 1 - assert "AKIAIOSFODNN7EXAMPLE" not in tc[0].title + assert "glpat-IOSFODNN7EXAMPLE" not in tc[0].title assert "[REDACTED" in tc[0].title # Nested content.text was extracted (robustness) AND redacted (security). assert len(txt) == 1 and txt[0].sub_session_id == "s1" - assert "AKIAIOSFODNN7EXAMPLE" not in txt[0].text + assert "glpat-IOSFODNN7EXAMPLE" not in txt[0].text assert "[REDACTED" in txt[0].text @pytest.mark.asyncio diff --git a/test/test_acp_client_tool_call_updates.py b/test/test_acp_client_tool_call_updates.py index f22e965af29..f12da90f031 100644 --- a/test/test_acp_client_tool_call_updates.py +++ b/test/test_acp_client_tool_call_updates.py @@ -352,12 +352,12 @@ def test_redaction_applied(self): "sessionUpdate": "tool_call_update", "toolCallId": "tc-8", "content": [ - {"content": {"type": "text", "text": "key=AKIAIOSFODNN7EXAMPLE secret"}}, + {"content": {"type": "text", "text": "key=glpat-IOSFODNN7EXAMPLE secret"}}, ], } ) event = client._extract_tool_call_update(msg) - assert "AKIAIOSFODNN7EXAMPLE" not in event.tool_output + assert "glpat-IOSFODNN7EXAMPLE" not in event.tool_output def test_ignores_non_dict_content_blocks(self): client = self._client() @@ -492,9 +492,9 @@ def test_shape_diagnostics_and_tool_id_are_redacted(self, caplog): from kiro_crew.acp._dispatch import _build_tool_result_event # Split so this file holds no literal-looking key; matches - # (?:AKIA|ASIA)[A-Z0-9]{16}, the same shape as + # glpat-[A-Za-z0-9_-]{16,}, the same shape as # test_core_path_redact_before_bound. - token = "AKIA" + "SHAPELEAK0123456" + token = "glpat-" + "SHAPELEAK0123456" with caplog.at_level(logging.WARNING, logger="kiro_crew.acp._dispatch"): assert ( @@ -630,7 +630,7 @@ def test_an_object_valued_type_never_renders_its_nested_values(self): non-string type renders by CLASS instead.""" from kiro_crew.acp._dispatch import unrenderable_content_shapes - token = "AKIA" + "NESTEDLEAK012345" + token = "glpat-" + "NESTEDLEAK012345" out = unrenderable_content_shapes([{"type": {"secret": token}, "other": 1}]) assert token not in out assert "secret" not in out @@ -673,13 +673,13 @@ def test_a_wrapped_entry_with_a_malformed_inner_block_is_reported(self): from kiro_crew.acp._dispatch import unrenderable_content_shapes out = unrenderable_content_shapes( - [{"type": "content", "content": {"kind": "text", "text": "AKIAIOSFODNN7SECRET"}}] + [{"type": "content", "content": {"kind": "text", "text": "glpat-IOSFODNN7SECRET"}}] ) assert out, "a wrapped entry with an unreadable inner block must be reported" assert "inner_type=" in out assert "'kind'" in out and "'text'" in out # Key NAMES only at the inner level too -- this lands in the log ring. - assert "AKIAIOSFODNN7SECRET" not in out + assert "glpat-IOSFODNN7SECRET" not in out def test_a_wrapped_inner_block_carrying_no_text_stays_silent(self): """The negative control for the inner check, and the reason it is an @@ -715,9 +715,9 @@ def test_a_wrapped_non_dict_inner_renders_by_class_not_value(self): named, never the string itself.""" from kiro_crew.acp._dispatch import unrenderable_content_shapes - out = unrenderable_content_shapes([{"type": "content", "content": "AKIAIOSFODNN7SECRET"}]) + out = unrenderable_content_shapes([{"type": "content", "content": "glpat-IOSFODNN7SECRET"}]) assert "inner=" in out - assert "AKIAIOSFODNN7SECRET" not in out + assert "glpat-IOSFODNN7SECRET" not in out # ── _extract_tool_call_refinement tests ── @@ -931,12 +931,12 @@ def test_redacts_credentials_in_input(self): "sessionUpdate": "tool_call_update", "toolCallId": "tc-5", "title": "Bash", - "rawInput": {"command": "echo AKIAIOSFODNN7EXAMPLE"}, + "rawInput": {"command": "echo glpat-IOSFODNN7EXAMPLE"}, } ) event = client._extract_tool_call_refinement(msg) assert event is not None - assert "AKIAIOSFODNN7EXAMPLE" not in event.tool_input + assert "glpat-IOSFODNN7EXAMPLE" not in event.tool_input def test_no_refinement_fields_returns_none(self): # Empty update with just tool_call_id should not emit a refinement. @@ -1008,7 +1008,7 @@ def test_purpose_is_redacted(self): "toolCallId": "tc-10", "rawInput": { "command": "aws s3 ls", - "__tool_use_purpose": "Use AKIAIOSFODNN7EXAMPLE to list buckets", + "__tool_use_purpose": "Use glpat-IOSFODNN7EXAMPLE to list buckets", }, } ) @@ -1016,7 +1016,7 @@ def test_purpose_is_redacted(self): assert event is not None assert event.tool_purpose.startswith("Use ") assert event.tool_purpose.endswith("to list buckets") - assert "AKIAIOSFODNN7EXAMPLE" not in event.tool_purpose + assert "glpat-IOSFODNN7EXAMPLE" not in event.tool_purpose class TestAcpClientIsShellSignal: diff --git a/test/test_acp_client_tool_events.py b/test/test_acp_client_tool_events.py index 7ee2afa569d..472eafe1b8e 100644 --- a/test/test_acp_client_tool_events.py +++ b/test/test_acp_client_tool_events.py @@ -469,7 +469,7 @@ def test_cached_tool_input_carries_redaction_provenance(self): "title": "Run Command", "kind": "execute", "toolCallId": "tc-secret", - "rawInput": {"command": "echo AKIAIOSFODNN7EXAMPLE"}, + "rawInput": {"command": "echo glpat-IOSFODNN7EXAMPLE"}, } } ) @@ -487,7 +487,7 @@ def test_cached_tool_input_carries_redaction_provenance(self): event = client._build_permission_event(permission) assert event.tool_input_redacted is True - assert "AKIAIOSFODNN7EXAMPLE" not in event.tool_input + assert "glpat-IOSFODNN7EXAMPLE" not in event.tool_input assert "[REDACTED: credential]" in event.tool_input assert client._tool_call_input_redacted["tc-secret"] is True repeated = client._build_permission_event(permission) diff --git a/test/test_acp_client_tool_hooks.py b/test/test_acp_client_tool_hooks.py index a61c7c9e630..a889340468d 100644 --- a/test/test_acp_client_tool_hooks.py +++ b/test/test_acp_client_tool_hooks.py @@ -482,7 +482,7 @@ async def test_pre_and_post_fire_when_audit_source_set(self, monkeypatch): # frontmatter: the Post-fire path MUST redact it (parity with chat_runner's # PostToolUse) before handing it to the hook engine — addresses review-bot # security-controls. - raw_output = "---\nname: x\nsecret: AKIAIOSFODNN7EXAMPLE\n---" + raw_output = "---\nname: x\nsecret: glpat-IOSFODNN7EXAMPLE\n---" await client._maybe_fire_post_tool_hooks(self._result_ev(output=raw_output)) pre = [c for c in store.calls if c["event"] == "PreToolUse"] @@ -496,7 +496,7 @@ async def test_pre_and_post_fire_when_audit_source_set(self, monkeypatch): # redacted (not the raw form). fired_output = post[0]["tool_response"]["output"] assert fired_output == "---\nname: x\nsecret: [REDACTED: credential]\n---" - assert "AKIAIOSFODNN7EXAMPLE" not in fired_output # raw credential scrubbed + assert "glpat-IOSFODNN7EXAMPLE" not in fired_output # raw credential scrubbed # YAML frontmatter (name:) is untouched by redaction → skill capture intact. assert "name: x" in fired_output @@ -516,14 +516,14 @@ async def test_post_fire_truncates_tool_output_to_2000(self, monkeypatch): client = AcpClient(session_key="sk", agent="code-review-sage", audit_source="subagent") client._observed_tool_calls["tc1"] = ("Reading /x/SKILL.md", "read") # Credential near the front + padding to blow past the 2000-char bound. - raw_output = "secret: AKIAIOSFODNN7EXAMPLE\n" + ("x" * 3000) + raw_output = "secret: glpat-IOSFODNN7EXAMPLE\n" + ("x" * 3000) await client._maybe_fire_post_tool_hooks(self._result_ev(output=raw_output)) post = [c for c in store.calls if c["event"] == "PostToolUse"] assert len(post) == 1 fired_output = post[0]["tool_response"]["output"] assert len(fired_output) == 2000 # bounded to first 2000 chars - assert "AKIAIOSFODNN7EXAMPLE" not in fired_output # raw credential scrubbed + assert "glpat-IOSFODNN7EXAMPLE" not in fired_output # raw credential scrubbed assert "[REDACTED: credential]" in fired_output # redaction survives truncation @pytest.mark.asyncio @@ -538,14 +538,14 @@ async def test_pre_fire_redacts_credential_in_tool_input(self, monkeypatch): store = self._Store() monkeypatch.setattr(acp_client, "get_global_hook_store", lambda: store) client = AcpClient(session_key="sk", agent="code-review-sage", audit_source="subagent") - raw_input = '{"cmd": "aws configure set key AKIAIOSFODNN7EXAMPLE"}' + raw_input = '{"cmd": "aws configure set key glpat-IOSFODNN7EXAMPLE"}' await client._maybe_fire_pre_tool_hooks(self._call_ev(tool_input=raw_input)) pre = [c for c in store.calls if c["event"] == "PreToolUse"] assert len(pre) == 1 fired_input = pre[0]["tool_input"] # parsed by fire_tool_hooks fired_str = json.dumps(fired_input) - assert "AKIAIOSFODNN7EXAMPLE" not in fired_str # raw credential scrubbed + assert "glpat-IOSFODNN7EXAMPLE" not in fired_str # raw credential scrubbed assert "[REDACTED: credential]" in fired_str # redaction marker present @pytest.mark.asyncio @@ -561,14 +561,14 @@ async def test_pre_fire_redacts_credential_in_dict_tool_input(self, monkeypatch) store = self._Store() monkeypatch.setattr(acp_client, "get_global_hook_store", lambda: store) client = AcpClient(session_key="sk", agent="code-review-sage", audit_source="subagent") - raw_input = {"cmd": "aws configure set key AKIAIOSFODNN7EXAMPLE"} + raw_input = {"cmd": "aws configure set key glpat-IOSFODNN7EXAMPLE"} await client._maybe_fire_pre_tool_hooks(self._call_ev(tool_input=raw_input)) pre = [c for c in store.calls if c["event"] == "PreToolUse"] assert len(pre) == 1 fired_input = pre[0]["tool_input"] # parsed by fire_tool_hooks fired_str = json.dumps(fired_input) - assert "AKIAIOSFODNN7EXAMPLE" not in fired_str # raw credential scrubbed + assert "glpat-IOSFODNN7EXAMPLE" not in fired_str # raw credential scrubbed assert "[REDACTED: credential]" in fired_str # redaction marker present @pytest.mark.asyncio diff --git a/test/test_acp_mcp_ref_guard.py b/test/test_acp_mcp_ref_guard.py index 60912cd70e6..002d3ef508e 100644 --- a/test/test_acp_mcp_ref_guard.py +++ b/test/test_acp_mcp_ref_guard.py @@ -421,7 +421,7 @@ def test_a_credential_shaped_ref_is_redacted_before_it_is_logged(self, caplog): ring fans out to the dashboard, so a credential-shaped ref would appear there verbatim. Redaction is not optional on a sink like that. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" spec = {"tools": [f"@{secret}"], "mcpServers": {}} with caplog.at_level(logging.WARNING, logger=mcp_ref_guard.__name__): found = warn_unresolved_server_refs( @@ -449,7 +449,7 @@ def test_the_agent_name_is_redacted_on_the_same_line(self, caplog): second line was never the exposure there. Redaction is the half ``%r`` cannot do: it would print a secret-shaped name in full, just quoted. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" spec = {"tools": ["@ghost"], "mcpServers": {}} with caplog.at_level(logging.WARNING, logger=mcp_ref_guard.__name__): warn_unresolved_server_refs( @@ -508,11 +508,11 @@ def test_url_punctuation_never_reaches_the_log_line(self, caplog): def test_the_rebuild_runs_after_the_redactors_not_instead_of_them(self, caplog): """Order is the load-bearing part: the alphabet alone would leak a key. - ``AKIAIOSFODNN7EXAMPLE`` is pure alphanumerics, so a rebuild would pass it + ``glpat-IOSFODNN7EXAMPLE`` is pure alphanumerics, so a rebuild would pass it through verbatim. Redaction is what removes the secret; the rebuild removes the punctuation and the dataflow. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" assert mcp_ref_guard._log_safe(secret) == secret # the alphabet alone: no help spec = {"tools": [f"@{secret}"], "mcpServers": {}} with caplog.at_level(logging.WARNING, logger=mcp_ref_guard.__name__): diff --git a/test/test_acp_refactor_error_surface.py b/test/test_acp_refactor_error_surface.py index 3d831dbeaec..b78a6a6ce46 100644 --- a/test/test_acp_refactor_error_surface.py +++ b/test/test_acp_refactor_error_surface.py @@ -301,7 +301,7 @@ def _tags( ), pytest.param("boom", None, "Prompt error: boom", _tags(), id="non-dict-error"), pytest.param( - _frame("leak AKIAIOSFODNN7EXAMPLE https://evil.example.com/x?d=secret"), + _frame("leak glpat-IOSFODNN7EXAMPLE https://evil.example.com/x?d=secret"), None, "leak [REDACTED: credential] https://evil.example.com/x?d=secret", _tags(), diff --git a/test/test_acp_runtime_compaction.py b/test/test_acp_runtime_compaction.py index 18c9f1f35fc..a46b2c33273 100644 --- a/test/test_acp_runtime_compaction.py +++ b/test/test_acp_runtime_compaction.py @@ -217,7 +217,7 @@ async def test_wait_for_compaction_drain_failed_with_a_credential_shaped_summary params={ "sessionId": "sA", "status": {"type": "failed"}, - "summary": "backend error: key AKIAIOSFODNN7EXAMPLE rejected", + "summary": "backend error: key glpat-IOSFODNN7EXAMPLE rejected", }, ) ) @@ -225,7 +225,7 @@ async def test_wait_for_compaction_drain_failed_with_a_credential_shaped_summary result = await handle.wait_for_compaction(timeout=3.0) assert result["type"] == "failed" - assert "AKIAIOSFODNN7EXAMPLE" not in result["summary"] + assert "glpat-IOSFODNN7EXAMPLE" not in result["summary"] assert "[REDACTED: credential]" in result["summary"] diff --git a/test/test_acp_runtime_dispatch_updates.py b/test/test_acp_runtime_dispatch_updates.py index bf3381d6b24..84abf3f0713 100644 --- a/test/test_acp_runtime_dispatch_updates.py +++ b/test/test_acp_runtime_dispatch_updates.py @@ -747,7 +747,7 @@ async def drive(): "sessionId": "sub-3", "update": { "sessionUpdate": "agent_message_chunk", - "text": "leaked AKIAIOSFODNN7EXAMPLE key", + "text": "leaked glpat-IOSFODNN7EXAMPLE key", }, }, } @@ -757,7 +757,7 @@ async def drive(): await await_until(driver, what="the driver finishing its turn") sa = [e for e in events if e.kind == EVENT_SUBAGENT_ACTIVITY] assert len(sa) == 1 - assert "AKIAIOSFODNN7EXAMPLE" not in sa[0].text + assert "glpat-IOSFODNN7EXAMPLE" not in sa[0].text assert "[REDACTED: credential]" in sa[0].text finally: await _stop_reader(task) diff --git a/test/test_acp_runtime_permission_trust.py b/test/test_acp_runtime_permission_trust.py index 42919f71a38..af36d2eb1cc 100644 --- a/test/test_acp_runtime_permission_trust.py +++ b/test/test_acp_runtime_permission_trust.py @@ -562,7 +562,7 @@ def test_shared_permission_event_carries_redaction_provenance_without_secret(): "toolCallId": "tc-secret", "title": "Run Command", "kind": "execute", - "rawInput": {"command": "echo AKIAIOSFODNN7EXAMPLE"}, + "rawInput": {"command": "echo glpat-IOSFODNN7EXAMPLE"}, }, input_cache, shell_cache=shell_cache, @@ -588,7 +588,7 @@ def test_shared_permission_event_carries_redaction_provenance_without_secret(): ) assert event.tool_input_redacted is True - assert "AKIAIOSFODNN7EXAMPLE" not in event.tool_input + assert "glpat-IOSFODNN7EXAMPLE" not in event.tool_input assert "[REDACTED: credential]" in event.tool_input assert redacted_cache["tc-secret"] is True repeated, _ = build_permission_event( diff --git a/test/test_acp_runtime_unroutable_frames.py b/test/test_acp_runtime_unroutable_frames.py index f71cfbf9983..de16d70a288 100644 --- a/test/test_acp_runtime_unroutable_frames.py +++ b/test/test_acp_runtime_unroutable_frames.py @@ -210,7 +210,7 @@ def test_drop_key_is_redacted_before_the_retention_cap(caplog): rt, _reader, _ = _make_runtime() limit = runtime_mod._DROP_SUMMARY_KEY_MAX_CHARS - token = "AKIA" + "STRADDLE0123456A" + token = "glpat-" + "STRADDLE0123456A" hostile = "s" * (limit - 9) + token + " tail" assert limit - 9 < limit < limit - 9 + len(token), "premise: the cap cuts the token" @@ -218,13 +218,13 @@ def test_drop_key_is_redacted_before_the_retention_cap(caplog): (session_id, method), count = next(iter(rt._dropped_frames.items())) assert count == 1 for part in (session_id, method): - assert "AKIA" not in part and len(part) <= limit + assert "glpat-" not in part and len(part) <= limit with caplog.at_level(logging.DEBUG, logger="kiro_crew.acp.runtime"): rt._flush_dropped_frames() records = _drop_records(caplog) assert records, "the flush must still report the drop" - assert all("AKIA" not in r for r in records) + assert all("glpat-" not in r for r in records) def test_drop_key_over_the_redact_input_cap_keeps_only_its_length(): diff --git a/test/test_acp_session_handle_capabilities.py b/test/test_acp_session_handle_capabilities.py index 04b1fa84649..604b3e38c7b 100644 --- a/test/test_acp_session_handle_capabilities.py +++ b/test/test_acp_session_handle_capabilities.py @@ -261,11 +261,11 @@ async def test_a_rejected_id_is_redacted_before_it_reaches_the_message(): """ handle = _make_handle(ACP_BACKEND_CODEX) handle.set_config_option = _Writes(_value_refusal_bare()) # type: ignore[method-assign] - leaky = "https://evil.example.com/m?access_token=AKIAIOSFODNN7EXAMPLE" + leaky = "https://evil.example.com/m?access_token=glpat-IOSFODNN7EXAMPLE" with pytest.raises(AcpModelUnavailable) as caught: await handle._push_model_config_option(leaky, strict=True) - assert "AKIAIOSFODNN7EXAMPLE" not in str(caught.value) + assert "glpat-IOSFODNN7EXAMPLE" not in str(caught.value) assert "REDACTED" in str(caught.value) diff --git a/test/test_acp_session_handle_stream_command.py b/test/test_acp_session_handle_stream_command.py index dfe480f0fc9..21185544a32 100644 --- a/test/test_acp_session_handle_stream_command.py +++ b/test/test_acp_session_handle_stream_command.py @@ -175,7 +175,7 @@ async def test_result_text_is_credential_redacted(): """Command output is backend-echoed text that reaches the dashboard — the two-pass redaction (URLs + credentials) must run on it, matching send_command's auditable control at the same surface.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" handle, _ = _make(response_result={"message": f"key {secret} leaked"}) events = await _collect(handle, "/env") text_events = [ev for ev in events if ev.kind == EVENT_TEXT_CHUNK] diff --git a/test/test_acp_structured_refusal.py b/test/test_acp_structured_refusal.py index 6312b0b0783..d802bfd933d 100644 --- a/test/test_acp_structured_refusal.py +++ b/test/test_acp_structured_refusal.py @@ -113,7 +113,7 @@ def test_non_string_fields_are_empty_not_guessed(self): assert info == RefusalInfo() def test_explanation_is_redacted_and_capped(self): - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" info = parse_refusal( { "stopReason": "CONTENT_FILTERED", @@ -251,7 +251,7 @@ class TestEveryFieldIsScrubbed: """Round-2 GPT finding: ``category`` / ``recommendedModel`` reach the same log line and card as ``explanation``, so all three pass the two redactors.""" - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "glpat-IOSFODNN7EXAMPLE" @pytest.mark.parametrize("field", ["category", "explanation", "recommendedModel"]) def test_credential_in_any_field_is_redacted(self, field, caplog): @@ -356,7 +356,7 @@ class TestRedactionSeesTheWholeValue: full value; only the result is capped.""" def test_credential_beyond_the_cap_is_still_redacted(self): - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" padding = "https://evil.example/" + "u" * 300 + " " value = padding * 3 + secret + " tail" assert len(value) > 4 * 128 diff --git a/test/test_agent_panel_routes_allocation.py b/test/test_agent_panel_routes_allocation.py index 1df8eeccef4..0efd6862e96 100644 --- a/test/test_agent_panel_routes_allocation.py +++ b/test/test_agent_panel_routes_allocation.py @@ -571,7 +571,7 @@ async def test_a_hostile_member_name_is_refused_on_the_read(vetted): async def test_a_credential_shaped_legacy_crew_can_read_its_redacted_panel(vetted): - shaped = "".join(["AKIA", "IOSFODNN7", "EXAMPLE"]) + shaped = "".join(["glpat-", "IOSFODNN7", "EXAMPLE"]) assert agent_panel._scrub(shaped) != shaped, "fixture is no longer redacted" slug = members_mod.slug_for_name(shaped) diff --git a/test/test_agent_panel_store.py b/test/test_agent_panel_store.py index c7dedadbc5e..1e956e7dda3 100644 --- a/test/test_agent_panel_store.py +++ b/test/test_agent_panel_store.py @@ -168,7 +168,7 @@ def test_a_crew_name_that_could_traverse_never_selects_a_template(): #: which is the shape ``redact_exfiltration_urls`` flags -- a plain #: suspicious-looking host is NOT flagged, and a test built on one would have #: passed vacuously while proving nothing. -SECRET = "AKIAIOSFODNN7EXAMPLE" +SECRET = "glpat-IOSFODNN7EXAMPLE" EXFIL = ( "https://api.notion.com/v1/oauth/authorize?client_id=client123" "&response_type=code&state=s3cr3tstate0123456789abcdef0123456789" @@ -1148,7 +1148,7 @@ def test_an_invisible_character_inside_a_token_does_not_defeat_redaction(): level only would pass a shallower test: a nested value, a list item, a KEY (the template renders it as a heading) and the title. """ - split = "AKIA\u200bIOSFODNN7EXAMPLE" + split = "glpat-\u200bIOSFODNN7EXAMPLE" secret = split.replace("\u200b", "") record = agent_panel.publish( CREW, diff --git a/test/test_agent_spec_safety.py b/test/test_agent_spec_safety.py index 8c08b06e7a2..b293a5e0ae6 100644 --- a/test/test_agent_spec_safety.py +++ b/test/test_agent_spec_safety.py @@ -487,13 +487,13 @@ def test_credential_straddling_the_cut_is_not_leaked(self, monkeypatch) -> None: from kiro_crew.agent import _sel_hook_rejected events = self._capture_sel(monkeypatch) - # fabricated AKIA-shaped literal, inlined (a ``secret``-named binding + # fabricated glpat-shaped literal, inlined (a ``secret``-named binding # trips CodeQL's name-based sensitive-source heuristic); the 200-char # cut lands 8 chars into the 20-char key - command = "x" * 192 + "AKIAIOSFODNN7EXAMPLE" + " --flag" + command = "x" * 192 + "glpat-IOSFODNN7EXAMPLE" + " --flag" _sel_hook_rejected("preToolUse", command, "denied") assert len(events) == 1 - assert "AKIA" not in events[0].resources + assert "glpat-" not in events[0].resources def test_plain_command_truncation_unchanged(self, monkeypatch) -> None: """Ordinary path is result-preserving: no secret ⇒ the same 200-char slice.""" diff --git a/test/test_agent_sync_prune.py b/test/test_agent_sync_prune.py index 0accbbe7c72..262d2921e33 100644 --- a/test/test_agent_sync_prune.py +++ b/test/test_agent_sync_prune.py @@ -241,7 +241,7 @@ class TestSyncRefusesCredentialShapedNames: this source too. """ - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" @pytest.mark.asyncio async def test_a_credential_shaped_discovered_name_is_not_synced(self): diff --git a/test/test_agent_templates_endpoint.py b/test/test_agent_templates_endpoint.py index 1482e6f98a9..d1b80f8fc83 100644 --- a/test/test_agent_templates_endpoint.py +++ b/test/test_agent_templates_endpoint.py @@ -223,7 +223,7 @@ async def test_roster_flags_which_rows_the_picker_may_offer(agents_dir): assert rows["reviewer"] is True assert rows["scribe"] is False masked = AgentInfo( - name="AKIAIOSFODNN7EXAMPLE", + name="glpat-IOSFODNN7EXAMPLE", filename="masked.json", description="", model="", @@ -259,7 +259,7 @@ async def test_roster_flags_which_rows_the_picker_may_offer(agents_dir): ({"name": "scribe", "filename": "notes--scribe.json"}, "", False), ( { - "name": "AKIAIOSFODNN7EXAMPLE", + "name": "glpat-IOSFODNN7EXAMPLE", "filename": "masked.json", }, "", @@ -317,7 +317,7 @@ async def test_roster_masks_package_controlled_strings_like_the_sibling_rosters( identity itself would be masked is left out rather than half-shown.""" from kiro_crew.dashboard.handlers.core import _SENSITIVE_MASK - probe = "AKIAIOSFODNN7EXAMPLE" + probe = "glpat-IOSFODNN7EXAMPLE" _write(agents_dir, "SomePkg-atlas.json", name="atlas", description=f"key {probe}", model=probe) _write(agents_dir, "reviewer.json", description="benign") _write(agents_dir, f"{probe}.json", name=probe) @@ -1178,7 +1178,7 @@ async def test_delete_classifies_the_file_on_disk_not_the_row(agents_dir, monkey async def test_delete_refusal_masks_reference_labels_like_the_roster(agents_dir): from kiro_crew.dashboard.handlers.core import _SENSITIVE_MASK - probe = "AKIAIOSFODNN7EXAMPLE" + probe = "glpat-IOSFODNN7EXAMPLE" _write(agents_dir, "reviewer.json") _seed_config({"pr-bot": "kirocrew"}, default="pr-bot") _seed_cron("reviewer", name=f"nightly {probe}") @@ -1369,7 +1369,7 @@ def test_ambiguous_refusal_text_masks_a_credential_shaped_file_name(tmp_path): from kiro_crew.dashboard.handlers.agents import _AmbiguousTemplateName from kiro_crew.dashboard.handlers.core import _SENSITIVE_MASK - probe = "AKIAIOSFODNN7EXAMPLE" + probe = "glpat-IOSFODNN7EXAMPLE" exc = _AmbiguousTemplateName("atlas", (tmp_path / "atlas.json", tmp_path / f"{probe}.json")) text = exc.refusal_text() assert probe not in text diff --git a/test/test_agent_welcome_message.py b/test/test_agent_welcome_message.py index 96f69a4613e..c5b7f84868c 100644 --- a/test/test_agent_welcome_message.py +++ b/test/test_agent_welcome_message.py @@ -381,7 +381,7 @@ async def test_a_credential_in_the_hint_is_redacted(self, monkeypatch, tmp_path) other foreign string on that path.""" from kiro_crew.dashboard.chat_runner import _surface_agent_welcome - secret = "AKIA" + "I" * 16 + secret = "glpat-" + "I" * 16 state, slot, _ = self._slot(monkeypatch, tmp_path, f"use {secret} to start") await _surface_agent_welcome(state, slot, "helper") diff --git a/test/test_agents_roster_contract.py b/test/test_agents_roster_contract.py index 4290ba06147..06ea1b94399 100644 --- a/test/test_agents_roster_contract.py +++ b/test/test_agents_roster_contract.py @@ -208,7 +208,7 @@ async def test_app_token_caller_gets_the_same_keys_with_scrubbed_values( A middleware sets ``request["app"]``, which is what ``token_auth`` does for a verified app token and what ``members.py::_deny_app_caller`` reads. """ - probe = "AKIAIOSFODNN7EXAMPLE" + probe = "glpat-IOSFODNN7EXAMPLE" seed = _seed_config_with_every_field_set() seed["agents"]["roster-probe"]["description"] = f"see {probe}" tmp = tmp_path / "config.json" @@ -297,7 +297,7 @@ def _clone(f: dataclasses.Field) -> dataclasses.Field: class TestUnshowableValuesAreMasked: """The read half: nothing that cannot be shown verbatim leaves as content.""" - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" # The five declared-``str`` record fields a roster row ships besides the # ones with their own inline guard. The loader now pins all of them to # their default on a non-string (``_safe_str``), so the mask below is @@ -430,7 +430,7 @@ class TestAvatarIsShapeAllowlistedNotMasked: nothing, and a masked ``kind`` loses ghost-vs-image. """ - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" FILE_PIN = "0123456789abcdef.png" def test_a_credential_shaped_trait_value_is_masked(self) -> None: @@ -630,7 +630,7 @@ class TestCredentialShapedNamesAreRefusedAtCreation: logs, error messages and telemetry. Refusing it at creation closes the source. """ - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" def test_the_create_rule_is_keyed_to_the_read_rule(self) -> None: """One detector, so the two halves cannot drift apart. @@ -720,7 +720,7 @@ async def _owner(request: web.Request, handler): # type: ignore[no-untyped-def] class TestCallerClassIsTheOwnerPredicate: """Who counts as the owner is delegated, not hand-rolled per caller class.""" - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" def _app(self, *, user: str, owner_id: str) -> web.Application: """An app whose requests carry a dashboard identity and an owner_id. @@ -841,7 +841,7 @@ async def test_an_echoed_avatar_does_not_overwrite_a_masked_trait(self, tmp_path class TestMaskIsTreatedAsUnchangedOnWrite: """The write half, without which the read half destroys stored config.""" - PROBE = "AKIAIOSFODNN7EXAMPLE" + PROBE = "glpat-IOSFODNN7EXAMPLE" @pytest.fixture(autouse=True) def _as_owner(self, monkeypatch): diff --git a/test/test_api_file_diff.py b/test/test_api_file_diff.py index b0879016e3b..c6c40734bc9 100644 --- a/test/test_api_file_diff.py +++ b/test/test_api_file_diff.py @@ -506,7 +506,7 @@ async def test_a_credential_straddling_the_read_cap_is_still_masked(tmp_path): _git_repo(tmp_path) f = tmp_path / "padded.txt" # Places the token across the byte offset the sibling endpoint caps at. - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" padding = "a" * (files_mod._FILE_READ_CAP - 10) f.write_text(padding + secret + "\nkeep\n") subprocess.run(["git", "add", "padded.txt"], cwd=tmp_path, capture_output=True, check=True) @@ -595,7 +595,7 @@ async def test_an_edit_inside_a_key_block_serves_no_key_text(tmp_path, kind, edi @pytest.mark.asyncio @requires_git -@pytest.mark.parametrize("shape", ["github", "aws"]) +@pytest.mark.parametrize("shape", ["github", "gitlab"]) async def test_a_long_line_above_a_hunk_serves_no_token_text(tmp_path, shape): """A long line above a hunk serves no part of a token it holds.""" import random @@ -604,7 +604,7 @@ async def test_a_long_line_above_a_hunk_serves_no_token_text(tmp_path, shape): if shape == "github": token = "gh" + "p_" + _noise(rng, _ALNUM, 36) else: - token = "AK" + "IA" + _noise(rng, _ALNUM[:36].upper(), 16) + token = "gl" + "pat-" + _noise(rng, _ALNUM, 16) assert redact_credentials(token)[0] != token, "fixture must be a shape the redactor masks" line = "x" * (80 - len(" = ") - 8) + " = " + token rows = [line] + [f" row {i}" for i in range(30)] diff --git a/test/test_api_hook_test_stop_payload.py b/test/test_api_hook_test_stop_payload.py index 697216c41c3..dfbb69b4af6 100644 --- a/test/test_api_hook_test_stop_payload.py +++ b/test/test_api_hook_test_stop_payload.py @@ -178,7 +178,7 @@ async def test_hook_test_redacts_context_in_sel_metadata(tmp_path): "command": "cat", } ) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" context = f"deploy with {secret}" fake_result = type( "R", diff --git a/test/test_api_tasks.py b/test/test_api_tasks.py index cfb6f3042b1..c6c44bf3b5a 100644 --- a/test/test_api_tasks.py +++ b/test/test_api_tasks.py @@ -289,7 +289,7 @@ async def test_detail_404_for_unknown_id(store: TaskStore) -> None: #: A credential the redaction table matches, and an exfiltration URL whose #: payload is that same credential. Real shapes, not placeholders: a pin over #: a string the redactor does not match would pass on an unredacted surface. -_CRED = "AKIAIOSFODNN7EXAMPLE" +_CRED = "glpat-IOSFODNN7EXAMPLE" _EXFIL_HOST = "collector.example.invalid" _EXFIL_URL = f"https://{_EXFIL_HOST}/ingest?token={_CRED}" diff --git a/test/test_artifact_comment_handlers.py b/test/test_artifact_comment_handlers.py index b6399b769ee..6796f74f2e3 100644 --- a/test/test_artifact_comment_handlers.py +++ b/test/test_artifact_comment_handlers.py @@ -609,7 +609,7 @@ async def test_provider_author_redacted_at_read_boundary(self, store, monkeypatc RemoteComment( remote_id="7", thread_id="7", - author="AKIAIOSFODNN7EXAMPLE", + author="glpat-IOSFODNN7EXAMPLE", body="looks good", ) ], @@ -618,10 +618,10 @@ async def test_provider_author_redacted_at_read_boundary(self, store, monkeypatc assert resp.status == 200 cmt = next(c for c in _j(resp)["comments"] if c["origin"] == "fakeprov:7") # Credential in the provider-controlled author never reaches the wire. - assert "AKIAIOSFODNN7EXAMPLE" not in cmt["author"] + assert "glpat-IOSFODNN7EXAMPLE" not in cmt["author"] # ...but it IS stored raw in the mirror (redaction is read-boundary only). stored = next(c for c in store.list_comments("doc") if c.origin == "fakeprov:7") - assert stored.author == "AKIAIOSFODNN7EXAMPLE" + assert stored.author == "glpat-IOSFODNN7EXAMPLE" @pytest.mark.asyncio async def test_merged_mirror_carries_routing_metadata(self, store, monkeypatch): diff --git a/test/test_artifact_materialize.py b/test/test_artifact_materialize.py index d561541f756..013ea35e555 100644 --- a/test/test_artifact_materialize.py +++ b/test/test_artifact_materialize.py @@ -251,12 +251,12 @@ def test_redaction_lives_at_the_api_boundary_only(): shared flag. The external ``_scan_session_docs`` MUST redact a credential-shaped path; the internal ``_collect_session_docs`` (used by the authorization scan) MUST preserve the TRUE path so it can be ``stat``'d.""" - cred_path = "/tmp/AKIAIOSFODNN7EXAMPLE/report.md" + cred_path = "/tmp/glpat-IOSFODNN7EXAMPLE/report.md" log = _FakeLog([cred_path]) # API boundary: the path is redacted (never leaks a credential substring). api = h._scan_session_docs(log, {}) assert api[0]["path"] != cred_path - assert "AKIAIOSFODNN7EXAMPLE" not in api[0]["path"] + assert "glpat-IOSFODNN7EXAMPLE" not in api[0]["path"] # Internal collector: the true path is preserved (authorization can stat it). raw = h._collect_session_docs(log, {}) assert raw[0]["path"] == cred_path diff --git a/test/test_artifact_merge_remote_comments.py b/test/test_artifact_merge_remote_comments.py index 2ae44372b91..2e0ff5ce789 100644 --- a/test/test_artifact_merge_remote_comments.py +++ b/test/test_artifact_merge_remote_comments.py @@ -102,7 +102,7 @@ def test_returns_existing_when_no_change(self, store): assert len(result) == 1 and result[0].id == "r1" -_AKIA = "AKIAIOSFODNN7EXAMPLE" # canonical AWS access-key-id shaped test token +_AKIA = "glpat-IOSFODNN7EXAMPLE" # a GitLab-shaped fake test token class TestRemoteCommentAnchorRedaction: diff --git a/test/test_artifacts_handlers_coverage.py b/test/test_artifacts_handlers_coverage.py index 237c5888c45..a2bd40fe046 100644 --- a/test/test_artifacts_handlers_coverage.py +++ b/test/test_artifacts_handlers_coverage.py @@ -319,13 +319,13 @@ async def test_scan_failure_is_a_redacted_500( self, store: ArtifactStore, monkeypatch: pytest.MonkeyPatch, audit: list ) -> None: def _boom(*_a: Any, **_k: Any) -> list[dict[str, Any]]: - raise RuntimeError("token=AKIAIOSFODNN7EXAMPLE blew up") + raise RuntimeError("token=glpat-IOSFODNN7EXAMPLE blew up") monkeypatch.setattr(h, "_scan_session_docs", _boom) resp = await h.api_artifact_session_docs(_req(conversation_log=_FakeLog())) assert resp.status == 500 assert audit[-1]["outcome"] == "error" - assert "AKIAIOSFODNN7EXAMPLE" not in audit[-1]["error"] + assert "glpat-IOSFODNN7EXAMPLE" not in audit[-1]["error"] # ── POST /api/artifacts/materialize ────────────────────────────────────────── @@ -541,11 +541,11 @@ def _boom(*_a: Any, **_k: Any) -> Any: monkeypatch.setattr(h, "_materialize_and_pin", _boom) await h.api_artifact_materialize( _req( - body={"path": "/tmp/AKIAIOSFODNN7EXAMPLE/a.md"}, + body={"path": "/tmp/glpat-IOSFODNN7EXAMPLE/a.md"}, conversation_log=_FakeLog(), ) ) - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(audit[-1]["extra"]) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(audit[-1]["extra"]) # ── PATCH /api/artifacts/{slug}/relocate ───────────────────────────────────── @@ -876,9 +876,9 @@ async def test_agent_author_and_anchor_are_redacted(self, published: ArtifactSto body={ "text": "note", "is_agent": True, - "author": "AKIAIOSFODNN7EXAMPLE", + "author": "glpat-IOSFODNN7EXAMPLE", "anchor": { - "quote": "AKIAIOSFODNN7EXAMPLE", + "quote": "glpat-IOSFODNN7EXAMPLE", "prefix": "p", "suffix": "s", "version_number": 1, @@ -890,8 +890,8 @@ async def test_agent_author_and_anchor_are_redacted(self, published: ArtifactSto assert resp.status == 201 stored = published.list_comments("doc")[0] assert stored.is_agent is True - assert "AKIAIOSFODNN7EXAMPLE" not in stored.author - assert "AKIAIOSFODNN7EXAMPLE" not in (stored.anchor_quote or "") + assert "glpat-IOSFODNN7EXAMPLE" not in stored.author + assert "glpat-IOSFODNN7EXAMPLE" not in (stored.anchor_quote or "") class TestReplyCommentProviderPush: @@ -1183,11 +1183,11 @@ async def test_edited_text_is_redacted(self, published: ArtifactStore) -> None: ) await h.api_artifact_edit_comment( _req( - body={"text": "creds AKIAIOSFODNN7EXAMPLE"}, + body={"text": "creds glpat-IOSFODNN7EXAMPLE"}, match={"slug": "doc", "comment_id": "local-1"}, ) ) - assert "AKIAIOSFODNN7EXAMPLE" not in published.list_comments("doc")[0].body + assert "glpat-IOSFODNN7EXAMPLE" not in published.list_comments("doc")[0].body class TestResolveAndReopen: @@ -1374,12 +1374,12 @@ async def test_provider_error_is_redacted( _use_provider( monkeypatch, _StubProvider( - {Capability.COMMENTS_READ}, fail=RuntimeError("bad AKIAIOSFODNN7EXAMPLE creds") + {Capability.COMMENTS_READ}, fail=RuntimeError("bad glpat-IOSFODNN7EXAMPLE creds") ), ) resp = await h.api_artifact_comments(_req(match={"slug": "doc"})) assert resp.status == 200 - assert "AKIAIOSFODNN7EXAMPLE" not in _j(resp)["remote_sync_error"] + assert "glpat-IOSFODNN7EXAMPLE" not in _j(resp)["remote_sync_error"] # ── _annotate_local_slugs ──────────────────────────────────────────────────── diff --git a/test/test_artifacts_handlers_update.py b/test/test_artifacts_handlers_update.py index 8e8f93c17fe..4722c1a8808 100644 --- a/test/test_artifacts_handlers_update.py +++ b/test/test_artifacts_handlers_update.py @@ -863,18 +863,18 @@ async def test_a_credential_shaped_binding_is_not_echoed_back_in_the_refusal( # The refusal names the target so the author can see which binding was wrong, # and an agent can put anything in a bound_to slug. A credential-shaped one # must not come back verbatim in the 400 body. - resp = await api_artifact_update(_bound_request(bound, "crewmate:AKIAIOSFODNN7EXAMPLE")) + resp = await api_artifact_update(_bound_request(bound, "crewmate:glpat-IOSFODNN7EXAMPLE")) assert resp.status == 400 - assert b"AKIAIOSFODNN7EXAMPLE" not in resp.body + assert b"glpat-IOSFODNN7EXAMPLE" not in resp.body assert b"REDACTED" in resp.body @pytest.mark.asyncio async def test_the_session_scope_refusal_is_redacted_too(self, isolated_store, bound) -> None: # Both scopes build their sentences through the same helper, so neither can # return one that was never redacted. - resp = await api_artifact_update(_bound_request(bound, "session:AKIAIOSFODNN7EXAMPLE")) + resp = await api_artifact_update(_bound_request(bound, "session:glpat-IOSFODNN7EXAMPLE")) assert resp.status == 400 - assert b"AKIAIOSFODNN7EXAMPLE" not in resp.body + assert b"glpat-IOSFODNN7EXAMPLE" not in resp.body assert b"REDACTED" in resp.body @pytest.mark.asyncio diff --git a/test/test_ask_question_roundtrip.py b/test/test_ask_question_roundtrip.py index e16a8714510..813b29411c6 100644 --- a/test/test_ask_question_roundtrip.py +++ b/test/test_ask_question_roundtrip.py @@ -1644,7 +1644,7 @@ async def test_answers_that_redaction_would_push_past_the_cap(self) -> None: from kiro_crew.session_directive import MAX_TOOL_RESULT_CHARS from kiro_crew.validation import _ASK_MAX_ANSWER_LEN, format_ask_answers - key_id = "AKIA" + "ABCDEFGHIJKLMNOP" # assembled so secret scanners do not flag a fake key + key_id = "xoxb-" + "ABCDEFGHIJKLMNO" # assembled so secret scanners do not flag a fake key answer = (f"{key_id} " * 100)[:_ASK_MAX_ANSWER_LEN] answers = {k: answer for k in self._max_keys()} # As typed (before the scrub format_ask_answers applies) the set fits the cap. diff --git a/test/test_auto_research.py b/test/test_auto_research.py index c7f87e322aa..dad1ec32b40 100644 --- a/test/test_auto_research.py +++ b/test/test_auto_research.py @@ -333,14 +333,14 @@ def test_near_miss_findings_are_redacted_before_surfacing(self, tmp_path: Path): (d / "cycle-1.json").write_text(json.dumps({ "cycle": 1, "new_findings_count": 1, - "summary": "key AKIAIOSFODNN7EXAMPLE leaked", + "summary": "key glpat-IOSFODNN7EXAMPLE leaked", "sources_checked": [exfil_url], })) findings = get_findings("a1b2c3d4") assert len(findings) == 1 blob = json.dumps(findings[0]) # Leg 1: the raw credential must not survive into the surfaced payload. - assert "AKIAIOSFODNN7EXAMPLE" not in blob + assert "glpat-IOSFODNN7EXAMPLE" not in blob # Leg 2: the exfil-shaped URL must be redacted wholesale — path and # payload gone, replaced by the redaction marker. (The marker itself # names the domain by design, so assert on the URL body, not the domain.) @@ -1125,7 +1125,7 @@ async def test_expand_redacts_returned_text(self, app): class _FakePool: async def send(self, prompt: str, timeout: float = 0) -> str: - return '[{"kind":"research","text":"key AKIAIOSFODNN7EXAMPLE leaked"}]' + return '[{"kind":"research","text":"key glpat-IOSFODNN7EXAMPLE leaked"}]' async def shutdown(self) -> None: pass @@ -1141,7 +1141,7 @@ async def shutdown(self) -> None: "mode": "generate", }, ) - assert "AKIAIOSFODNN7EXAMPLE" not in (await r.text()) + assert "glpat-IOSFODNN7EXAMPLE" not in (await r.text()) @pytest.mark.asyncio async def test_expand_requires_auth(self): diff --git a/test/test_auto_research_http.py b/test/test_auto_research_http.py index 87a1963006f..d33cc5a7c70 100644 --- a/test/test_auto_research_http.py +++ b/test/test_auto_research_http.py @@ -633,14 +633,14 @@ def add_source(self, *, name, source_type, uri, properties): cid = (await r.json())["id"] d = h._campaign_dir(cid) (d / "FINDINGS.md").write_text( - "# Summary\nFound key aws_secret=AKIAIOSFODNN7EXAMPLE in the config." + "# Summary\nFound key aws_secret=glpat-IOSFODNN7EXAMPLE in the config." ) r = await c.post(f"/api/apps/auto-research/campaigns/{cid}/to-knowledge", json={}) assert r.status == 201 # A sanitized copy is created and the raw credential is gone. sanitized = d / "findings_for_knowledge.md" assert sanitized.exists() - assert "AKIAIOSFODNN7EXAMPLE" not in sanitized.read_text(encoding="utf-8") + assert "glpat-IOSFODNN7EXAMPLE" not in sanitized.read_text(encoding="utf-8") # The source ingested is the sanitized file, never raw FINDINGS.md. assert added["uri"] == str(sanitized.resolve()) @@ -745,7 +745,7 @@ async def shutdown(self) -> None: # Findings containing a credential-shaped token must be redacted # before it lands in the shareable artifact. (d / "FINDINGS.md").write_text( - "# Summary\nToken bucket is common. aws_secret=AKIAIOSFODNN7EXAMPLE" + "# Summary\nToken bucket is common. aws_secret=glpat-IOSFODNN7EXAMPLE" ) r = await c.post(f"/api/apps/auto-research/campaigns/{cid}/to-artifact", json={}) assert r.status == 201 @@ -755,7 +755,7 @@ async def shutdown(self) -> None: # The stored artifact must not contain the raw credential. art = ArtifactStore(root=tmp_path / "artifacts").get(body["slug"]) content = art.content or "" - assert "AKIAIOSFODNN7EXAMPLE" not in content + assert "glpat-IOSFODNN7EXAMPLE" not in content # The malicious origin must be HTML-escaped, not raw. assert "" not in content assert "<script>" in content @@ -776,7 +776,7 @@ async def send(self, prompt: str, timeout: float = 0) -> str: # step on this path is actually exercised (not vacuously true). return ( "```html\n

Nice Report

" - "

Found aws_secret=AKIAIOSFODNN7EXAMPLE

" + "

Found aws_secret=glpat-IOSFODNN7EXAMPLE

" "\n```" ) @@ -803,7 +803,7 @@ async def shutdown(self) -> None: cid = (await r.json())["id"] d = h._campaign_dir(cid) (d / "FINDINGS.md").write_text( - "# Summary\nToken bucket. aws_secret=AKIAIOSFODNN7EXAMPLE" + "# Summary\nToken bucket. aws_secret=glpat-IOSFODNN7EXAMPLE" ) r = await c.post(f"/api/apps/auto-research/campaigns/{cid}/to-artifact", json={}) assert r.status == 201 @@ -811,7 +811,7 @@ async def shutdown(self) -> None: content = ArtifactStore(root=tmp_path / "artifacts").get(slug).content or "" assert "Nice Report" in content # LLM-authored HTML was used assert "```" not in content # code fence stripped - assert "AKIAIOSFODNN7EXAMPLE" not in content # still redacted + assert "glpat-IOSFODNN7EXAMPLE" not in content # still redacted @pytest.mark.asyncio async def test_to_artifact_reuse_regenerates(self, app, tmp_path: Path): @@ -1105,7 +1105,7 @@ async def test_grill_tree_redacts_node_text(self, app): from kiro_crew.apps.builtins.auto_research import handlers as h - tree = [{"id": "n1", "kind": "research", "text": "leaked AKIAIOSFODNN7EXAMPLE in node"}] + tree = [{"id": "n1", "kind": "research", "text": "leaked glpat-IOSFODNN7EXAMPLE in node"}] camp = h.create_campaign( { "question": "Redacted tree question padded enough", @@ -1120,7 +1120,7 @@ async def test_grill_tree_redacts_node_text(self, app): r = await c.get(f"/api/apps/auto-research/campaigns/{cid}/grill-tree") assert r.status == 200 body = await r.text() - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body @pytest.mark.asyncio async def test_grill_tree_redacts_string_elements(self, app): @@ -1144,13 +1144,13 @@ async def test_grill_tree_redacts_string_elements(self, app): d = h._safe_campaign_dir(cid) assert d is not None (d / "grill_tree.json").write_text( - json.dumps([{"id": "n1", "text": "ok"}, "leaked AKIAIOSFODNN7EXAMPLE here"]) + json.dumps([{"id": "n1", "text": "ok"}, "leaked glpat-IOSFODNN7EXAMPLE here"]) ) async with TestClient(TestServer(app)) as c: r = await c.get(f"/api/apps/auto-research/campaigns/{cid}/grill-tree") assert r.status == 200 body = await r.text() - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body @pytest.mark.asyncio async def test_grill_tree_redacts_nested_list_elements(self, app): @@ -1173,13 +1173,15 @@ async def test_grill_tree_redacts_nested_list_elements(self, app): d = h._safe_campaign_dir(cid) assert d is not None (d / "grill_tree.json").write_text( - json.dumps([{"id": "n1", "text": "ok"}, ["benign", "leaked AKIAIOSFODNN7EXAMPLE here"]]) + json.dumps( + [{"id": "n1", "text": "ok"}, ["benign", "leaked glpat-IOSFODNN7EXAMPLE here"]] + ) ) async with TestClient(TestServer(app)) as c: r = await c.get(f"/api/apps/auto-research/campaigns/{cid}/grill-tree") assert r.status == 200 body = await r.text() - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body @pytest.mark.asyncio async def test_grill_tree_non_list_fails_closed(self, app): @@ -1201,14 +1203,16 @@ async def test_grill_tree_non_list_fails_closed(self, app): # A dict (not a list) with an embedded secret simulates tampering. d = h._safe_campaign_dir(cid) assert d is not None - (d / "grill_tree.json").write_text(json.dumps({"text": "leaked AKIAIOSFODNN7EXAMPLE here"})) + (d / "grill_tree.json").write_text( + json.dumps({"text": "leaked glpat-IOSFODNN7EXAMPLE here"}) + ) async with TestClient(TestServer(app)) as c: r = await c.get(f"/api/apps/auto-research/campaigns/{cid}/grill-tree") assert r.status == 200 body = await r.json() text = json.dumps(body) assert body["tree"] == [] - assert "AKIAIOSFODNN7EXAMPLE" not in text + assert "glpat-IOSFODNN7EXAMPLE" not in text @pytest.mark.asyncio async def test_grill_tree_empty_when_absent(self, app): diff --git a/test/test_auto_research_watchdog.py b/test/test_auto_research_watchdog.py index d00e67ef9bc..af53b7bc85c 100644 --- a/test/test_auto_research_watchdog.py +++ b/test/test_auto_research_watchdog.py @@ -718,9 +718,9 @@ def test_read_finding_file_redacts(self, tmp_path: Path): from kiro_crew.apps.builtins.auto_research import handlers as h p = tmp_path / "cycle_001.json" - p.write_text(json.dumps({"summary": "leaked AKIAIOSFODNN7EXAMPLE here"})) + p.write_text(json.dumps({"summary": "leaked glpat-IOSFODNN7EXAMPLE here"})) out = h._read_finding_file(p) - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(out) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(out) def test_read_finding_file_bad_json_returns_empty(self, tmp_path: Path): from kiro_crew.apps.builtins.auto_research import handlers as h diff --git a/test/test_autonudge.py b/test/test_autonudge.py index dac9e71bab6..dc93eda5df6 100644 --- a/test/test_autonudge.py +++ b/test/test_autonudge.py @@ -215,7 +215,7 @@ async def test_credentials_in_updated_message_are_redacted(self, monkeypatch): svc = self._fake_svc() app = self._client_app(monkeypatch, svc) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async with TestClient(TestServer(app)) as client: resp = await client.patch( "/api/autonudge/loop-1", json={"message": f"poll with key {secret}"} @@ -230,7 +230,9 @@ async def test_exfiltration_url_in_updated_message_is_redacted(self, monkeypatch # A credential in the query is an unconditional exfil marker, so this # probe is deterministic rather than dependent on host heuristics. - probe = "post results to https://evil.example.com/collect?aws_key=AKIAIOSFODNN7EXAMPLE now" + probe = ( + "post results to https://evil.example.com/collect?aws_key=glpat-IOSFODNN7EXAMPLE now" + ) svc = self._fake_svc() app = self._client_app(monkeypatch, svc) async with TestClient(TestServer(app)) as client: diff --git a/test/test_autonudge_authz_cov80.py b/test/test_autonudge_authz_cov80.py index cec8b425565..bc7b7acfdcd 100644 --- a/test/test_autonudge_authz_cov80.py +++ b/test/test_autonudge_authz_cov80.py @@ -1117,13 +1117,13 @@ class TestNormalizeBannerTruncate: def test_a_credential_straddling_the_cap_is_masked_not_sliced(self) -> None: # 20-char key starts 10 chars before the cap and runs past it: a # slice-before-redact (the old ``objective[:cap]``) would keep the raw - # 10-char prefix ``AKIAIOSFOD`` because the truncated token does not + # 10-char prefix ``glpat-IOSFOD`` because the truncated token does not # match the scanner. - straddling = "x" * (MAX_BANNER_CHARS - 10) + "AKIAIOSFODNN7EXAMPLE" + " tail" + straddling = "x" * (MAX_BANNER_CHARS - 10) + "glpat-IOSFODNN7EXAMPLE" + " tail" value, error = normalize_banner(straddling, absent_ok=True, truncate=True) assert error is None assert len(value) <= MAX_BANNER_CHARS - assert "AKIA" not in value, "a raw credential prefix survived the cap cut" + assert "glpat-" not in value, "a raw credential prefix survived the cap cut" def test_a_long_credential_free_objective_truncates_instead_of_dropping(self) -> None: value, error = normalize_banner( diff --git a/test/test_autonudge_banner.py b/test/test_autonudge_banner.py index d16bf2438e4..e5ffc6dde53 100644 --- a/test/test_autonudge_banner.py +++ b/test/test_autonudge_banner.py @@ -440,7 +440,7 @@ async def test_a_non_string_banner_is_never_logged_by_value(self, tmp_path, capl the entire record — args included — into the emitted text. It is kept as a cheap guard for the non-caplog handler shape, not as proven coverage. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "xoxb-IOSFODNN7EXAMPL" self._write_store(tmp_path, [secret]) svc = AutoNudgeService(base_dir=tmp_path) try: @@ -542,15 +542,15 @@ async def test_a_valid_persisted_credential_banner_is_scrubbed_at_load(self, tmp file, direct agent ``svc.add``, or persisted before this scrub existed) is credential-scrubbed at load and re-persisted, so ``GET /api/autonudge`` (``asdict``), the WS broadcast, and the fire path can never serve it raw.""" - self._write_store(tmp_path, "deploy with AKIAIOSFODNN7EXAMPLE now") + self._write_store(tmp_path, "deploy with xoxb-IOSFODNN7EXAMPL now") svc = AutoNudgeService(base_dir=tmp_path) try: await svc.start() stored = svc._loops["abc123"].banner - assert "AKIAIOSFODNN7EXAMPLE" not in stored, "the credential survived the load scrub" + assert "xoxb-IOSFODNN7EXAMPL" not in stored, "the credential survived the load scrub" assert "[REDACTED" in stored, "the load-path scrub did not run" on_disk = json.loads((tmp_path / "autonudge.json").read_text(encoding="utf-8")) - assert "AKIAIOSFODNN7EXAMPLE" not in on_disk["loops"][0]["banner"] + assert "xoxb-IOSFODNN7EXAMPL" not in on_disk["loops"][0]["banner"] finally: svc.stop() @@ -561,7 +561,7 @@ async def test_a_persisted_credential_banner_over_the_cap_is_blanked(self, tmp_p credential is masked and kept — the test above), but an over-cap value is treated as absent, so no raw prefix of a straddling secret can survive a slice — there is no slice.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "xoxb-IOSFODNN7EXAMPL" straddling = "x" * (MAX_BANNER_CHARS - 10) + secret + " trailing context " * 5 assert len(straddling) > MAX_BANNER_CHARS, "fixture must exceed the cap" self._write_store(tmp_path, straddling) @@ -570,7 +570,7 @@ async def test_a_persisted_credential_banner_over_the_cap_is_blanked(self, tmp_p await svc.start() assert svc._loops["abc123"].banner == "", "the over-cap banner was not blanked" on_disk = json.loads((tmp_path / "autonudge.json").read_text(encoding="utf-8")) - assert "AKIA" not in on_disk["loops"][0]["banner"] + assert "xoxb-" not in on_disk["loops"][0]["banner"] finally: svc.stop() @@ -653,15 +653,15 @@ async def test_a_persisted_credential_message_is_scrubbed_at_load(self, tmp_path """A message reaching the store past the authorized write paths is credential-scrubbed at load and re-persisted, so ``GET /api/autonudge`` (``asdict``) and the WS broadcast can never serve it raw.""" - self._write_store(tmp_path, "run the deploy with AKIAIOSFODNN7EXAMPLE now") + self._write_store(tmp_path, "run the deploy with xoxb-IOSFODNN7EXAMPL now") svc = AutoNudgeService(base_dir=tmp_path) try: await svc.start() stored = svc._loops["abc123"].message - assert "AKIAIOSFODNN7EXAMPLE" not in stored, "the credential survived the load scrub" + assert "xoxb-IOSFODNN7EXAMPL" not in stored, "the credential survived the load scrub" assert "[REDACTED" in stored, "the message load-path scrub did not run" on_disk = json.loads((tmp_path / "autonudge.json").read_text(encoding="utf-8")) - assert "AKIAIOSFODNN7EXAMPLE" not in on_disk["loops"][0]["message"] + assert "xoxb-IOSFODNN7EXAMPL" not in on_disk["loops"][0]["message"] finally: svc.stop() @@ -956,7 +956,7 @@ async def test_a_banner_redaction_grows_past_the_cap_is_rejected_on_add( """ from aiohttp.test_utils import TestClient, TestServer - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "xoxb-IOSFODNN7EXAMPL" at_cap_with_secret = "b" * (MAX_BANNER_CHARS - len(secret)) + secret assert len(at_cap_with_secret) == MAX_BANNER_CHARS, "fixture is not at the cap" svc = self._svc() @@ -984,7 +984,7 @@ async def test_a_banner_redaction_grows_past_the_cap_is_rejected_on_update( """ from aiohttp.test_utils import TestClient, TestServer - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "xoxb-IOSFODNN7EXAMPL" at_cap_with_secret = "b" * (MAX_BANNER_CHARS - len(secret)) + secret svc = self._svc() async with TestClient(TestServer(self._app(monkeypatch, svc))) as client: @@ -1038,7 +1038,7 @@ class TestMonitorToolsCanSetTheBanner: the two redaction passes are the existing ones -- no second validation path. """ - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "xoxb-IOSFODNN7EXAMPL" @pytest.fixture() def default_install(self, monkeypatch): diff --git a/test/test_autonudge_fingerprint.py b/test/test_autonudge_fingerprint.py index 57ba279f0eb..b4d52be85e3 100644 --- a/test/test_autonudge_fingerprint.py +++ b/test/test_autonudge_fingerprint.py @@ -26,7 +26,7 @@ class TestTheRedactedProjectionCannotOverwriteTheStoredMessage: cannot drift apart. These are its non-regression arms. """ - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "glpat-IOSFODNN7EXAMPLE" @pytest.fixture() def audits(self, monkeypatch: pytest.MonkeyPatch) -> list[dict]: @@ -137,7 +137,7 @@ class TestAnEchoedBannerDoesNotOverwriteTheStoredOne: replaced the operator's stored banner with its own redaction -- irreversibly. """ - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "glpat-IOSFODNN7EXAMPLE" class _Svc: def __init__(self, row: object) -> None: @@ -256,7 +256,7 @@ async def test_a_rotated_secret_variant_is_not_mistaken_for_the_goal_already_see """ # One key-shaped literal, and a distinct same-shape variant derived from it, so # the two goals differ only inside the mask. - key_seen = "AKIAIOSFODNN7EXAMPLE" + key_seen = "glpat-IOSFODNN7EXAMPLE" seen = f"deploy with {key_seen} now" rotated = f"deploy with {key_seen[:-1] + 'F'} now" svc = AutoNudgeService(base_dir=tmp_path) @@ -287,7 +287,9 @@ async def test_a_current_fingerprint_still_succeeds(self, tmp_path, audits) -> N """POSITIVE CONTROL: the token must not refuse an ordinary save.""" svc = AutoNudgeService(base_dir=tmp_path) try: - armed = await svc.add(slot_key="chat-9-995", message="deploy with AKIAIOSFODNN7EXAMPLE") + armed = await svc.add( + slot_key="chat-9-995", message="deploy with glpat-IOSFODNN7EXAMPLE" + ) _loop, error, status = await authz.authorize_and_update_nudge( svc=svc, loop_id=armed.id, @@ -372,7 +374,7 @@ def test_a_persisted_token_that_is_not_generator_shaped_is_re_minted(self, tmp_p scrub this change exists to add. ADDRESSING_FIELDS are exempt, and this field was effectively a third one nobody declared. """ - planted = "AKIAIOSFODNN7EXAMPLE" + planted = "glpat-IOSFODNN7EXAMPLE" (tmp_path / "autonudge.json").write_text( json.dumps( { diff --git a/test/test_autonudge_handlers_cov80.py b/test/test_autonudge_handlers_cov80.py index dc31dc3aed8..1a89a187268 100644 --- a/test/test_autonudge_handlers_cov80.py +++ b/test/test_autonudge_handlers_cov80.py @@ -202,7 +202,7 @@ async def test_session_monitor_read_admits_webex_legacy_loop( async def test_session_monitor_read_redacts_provider_controlled_evidence( monkeypatch: pytest.MonkeyPatch, ) -> None: - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" loop = _monitor_loop(slot_key="chat-1-111") assert loop.monitor is not None loop.monitor.last_observation = { @@ -431,7 +431,7 @@ async def test_monitor_slot_read_refuses_non_owner_sessions_without_leaking( async def test_monitor_list_excludes_persistence_only_fields( monkeypatch: pytest.MonkeyPatch, ) -> None: - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" loop = _monitor_loop() assert loop.monitor is not None loop.monitor.extra_fields["raw_provider_payload"] = "must-not-escape" diff --git a/test/test_autonudge_quarantine_sidecar.py b/test/test_autonudge_quarantine_sidecar.py index 5f47fc1839a..c925da9d020 100644 --- a/test/test_autonudge_quarantine_sidecar.py +++ b/test/test_autonudge_quarantine_sidecar.py @@ -32,7 +32,7 @@ class TestTheQuarantineSidecarIsWrittenSafely: consistent file. Shape: a non-object sidecar is ignored rather than fatal. """ - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "glpat-IOSFODNN7EXAMPLE" def _store_with_one_unusable_row(self, tmp_path): good = {"id": "keep", "slot_key": "chat-1-1", "message": "fine", "idle_secs": 300} diff --git a/test/test_autonudge_refactor_contract.py b/test/test_autonudge_refactor_contract.py index 47d41422893..8547de770fb 100644 --- a/test/test_autonudge_refactor_contract.py +++ b/test/test_autonudge_refactor_contract.py @@ -345,7 +345,7 @@ _FIXED_NOW = 1_790_000_000.0 #: AWS's documented example key: credential-shaped, so the loader holds its row aside. -_HELD_ID = "AKIAIOSFODNN7EXAMPLE" +_HELD_ID = "glpat-IOSFODNN7EXAMPLE" #: ``autonudge.json`` as the golden scenario writes it, each ``monitor`` object folded #: to ````: those bytes belong to ``monitoring.models.monitor_state_to_dict``, @@ -519,7 +519,7 @@ "version": 1, "quarantined": [ { - "id": "AKIAIOSFODNN7EXAMPLE", + "id": "glpat-IOSFODNN7EXAMPLE", "slot_key": "chat-3-300", "message": "held aside" } diff --git a/test/test_autonudge_wake_judge_point.py b/test/test_autonudge_wake_judge_point.py index b52a700c9a9..a396a758d4f 100644 --- a/test/test_autonudge_wake_judge_point.py +++ b/test/test_autonudge_wake_judge_point.py @@ -871,7 +871,7 @@ def test_last_verdict_is_carried(self) -> None: assert state["last_verdict"]["outcome"] == "quiet" def test_scrub_drops_an_item_carrying_a_credential(self) -> None: - assert point.evidence_item("pr:x#1", point.KIND_PR_CHECKS, 1.0, "AKIA" + "A" * 16) is None + assert point.evidence_item("pr:x#1", point.KIND_PR_CHECKS, 1.0, "glpat-" + "A" * 16) is None def test_unknown_kind_is_dropped(self) -> None: assert point.evidence_item("s", "not-a-kind", 1.0, "hello") is None @@ -883,7 +883,7 @@ def test_scrub_drop_everything_leaves_no_evidence(self) -> None: "source": "s", "kind": point.KIND_PR_CHECKS, "age_s": 1.0, - "text": "AKIA" + "B" * 16, + "text": "glpat-" + "B" * 16, } ] ) @@ -1362,7 +1362,7 @@ def test_a_partial_scrub_shed_falls_back_rather_than_asking_a_half_question(self "source": "pr:acme/widgets#1", "kind": point.KIND_PR_COMMENT, "age_s": 2.0, - "text": "please rotate AKIA" + "D" * 16, + "text": "please rotate glpat-" + "D" * 16, }, ], trace=trace, @@ -1390,7 +1390,7 @@ def test_a_fallback_publishes_the_screened_count(self) -> None: "source": "s", "kind": point.KIND_PR_CHECKS, "age_s": 1.0, - "text": "AKIA" + "C" * 16, + "text": "glpat-" + "C" * 16, } ], trace=trace, diff --git a/test/test_aws_consent.py b/test/test_aws_consent.py index 52281b95732..4dbd10c081b 100644 --- a/test/test_aws_consent.py +++ b/test/test_aws_consent.py @@ -1422,7 +1422,7 @@ class TestAuditDecisionRedactsBeforeTruncate: ``detail`` still emits the bare ``service`` with no ``": "`` separator. """ - SECRET = "AKIAIOSFODNN7EXAMPLE" # 20-char AWS access key ID + SECRET = "glpat-IOSFODNN7EXAMPLE" # a GitLab-shaped fake token @staticmethod def _capture(monkeypatch): @@ -1448,7 +1448,7 @@ def test_a_credential_straddling_the_clip_is_fully_redacted(self, home, monkeypa assert len(calls) == 1 resources = calls[0]["resources"] - assert "AKIA" not in resources, resources + assert "glpat-" not in resources, resources assert resources.startswith("polly: ") # Redaction ran over the full text; only the redacted text was clipped. assert len(resources) <= len("polly: ") + 200 diff --git a/test/test_aws_control_app.py b/test/test_aws_control_app.py index 5fcfd63f08c..48fc059c9f1 100644 --- a/test/test_aws_control_app.py +++ b/test/test_aws_control_app.py @@ -542,7 +542,7 @@ def test_the_fallback_scrubs_a_credential_shaped_profile_name(self): from kiro_crew.dashboard.handlers import aws_consent as consent_handlers from kiro_crew.deploy import profiles as deploy_profiles - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" snapshot = _snapshot_of( _registry([_entry(secret, account=self.ACCOUNT)], default=secret), {secret: _identity(False, detail="ExpiredToken")}, @@ -1348,7 +1348,7 @@ def test_credential_bearing_artifact_is_refused(self, tmp_path, monkeypatch): version=1, description="", tags=[], - content="aws_secret_access_key = AKIAIOSFODNN7EXAMPLEKEYX", + content="aws_secret_access_key = glpat-IOSFODNN7EXAMPLEKEYX", ) with ( mock.patch.object(library, "get_default_store") as store, diff --git a/test/test_aws_control_app_hardening.py b/test/test_aws_control_app_hardening.py index 0914906898b..849fe274cfb 100644 --- a/test/test_aws_control_app_hardening.py +++ b/test/test_aws_control_app_hardening.py @@ -151,7 +151,7 @@ class TestRound16Hardening: def test_profile_and_account_names_are_redacted_on_the_way_out(self): # The profile registry is an agent-writable store, so a planted # credential in a profile NAME must not reach the dashboard verbatim. - planted = "prof-AKIAIOSFODNN7EXAMPLE" + planted = "prof-glpat-IOSFODNN7EXAMPLE" view = accounts_mod.ProfileView( name=planted, region="us-west-2", @@ -162,11 +162,11 @@ def test_profile_and_account_names_are_redacted_on_the_way_out(self): detail=f"probe failed for {planted}", ) out = view.to_dict() - assert "AKIAIOSFODNN7EXAMPLE" not in out["name"] - assert "AKIAIOSFODNN7EXAMPLE" not in out["detail"] + assert "glpat-IOSFODNN7EXAMPLE" not in out["name"] + assert "glpat-IOSFODNN7EXAMPLE" not in out["detail"] acct = accounts_mod.AccountView(account=ACCOUNT, profiles=[view]) - assert "AKIAIOSFODNN7EXAMPLE" not in acct.to_dict()["name"] + assert "glpat-IOSFODNN7EXAMPLE" not in acct.to_dict()["name"] def test_corrupt_runs_map_does_not_lose_a_completed_upload(self, tmp_path, monkeypatch): # The archive is already in S3 by the time the ledger is written: a @@ -370,7 +370,7 @@ def fake_get(profile, region, bucket, section, key, dest, *, account=None): assert Path(path).read_text(encoding="utf-8") == key def test_every_string_display_field_is_redacted(self): - planted = "AKIAIOSFODNN7EXAMPLE" + planted = "glpat-IOSFODNN7EXAMPLE" view = accounts_mod.ProfileView( name=f"p-{planted}", region=f"us-west-2-{planted}", @@ -868,7 +868,7 @@ def test_stderr_is_redacted_before_it_is_trimmed(self): # secret is placed so that a naive `err[:200]` would split it. from kiro_crew.deploy import engine - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" padded = "x" * 190 + secret + " trailing context" out = engine._trimmed_stderr(padded) @@ -1124,7 +1124,7 @@ def test_a_credential_shaped_profile_name_is_redacted_in_the_reconnect_command(s # would render verbatim into the guidance card and the clipboard. from kiro_crew.apps.builtins.aws_control.backend import accounts - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" plan = accounts.reconnect_plan(accounts.KIND_SSO, key) assert key not in plan["command"] # Still a usable command shape, not an empty string. diff --git a/test/test_aws_control_backup_conversations.py b/test/test_aws_control_backup_conversations.py index f61091e60f1..338d56fa3df 100644 --- a/test/test_aws_control_backup_conversations.py +++ b/test/test_aws_control_backup_conversations.py @@ -128,7 +128,7 @@ def test_a_symlinked_scratch_file_is_refused(self, tmp_path): MUTATION: drop `_O_NOFOLLOW` from the open and this reddens. """ secret = tmp_path / "credentials" - secret.write_bytes(b"aws_secret_access_key = AKIA-not-real\n") + secret.write_bytes(b"aws_secret_access_key = glpat--not-real\n") (tmp_path / "conversations.sqlite3").symlink_to(secret) fd = self._dir_fd(tmp_path) try: @@ -146,7 +146,7 @@ def test_a_hard_linked_scratch_file_is_refused(self, tmp_path): MUTATION: drop the `st_nlink` check and this reddens. """ secret = tmp_path / "credentials" - secret.write_bytes(b"aws_secret_access_key = AKIA-not-real\n") + secret.write_bytes(b"aws_secret_access_key = glpat--not-real\n") os.link(secret, tmp_path / "conversations.sqlite3") fd = self._dir_fd(tmp_path) try: @@ -296,7 +296,7 @@ def test_a_credential_in_a_conversation_is_redacted_before_it_ships( try: conn.execute( "INSERT INTO conversations_v2 (conversation_id, value) VALUES (?, ?)", - ("c1", "here is my key AKIAIOSFODNN7EXAMPLE, use it"), + ("c1", "here is my key glpat-IOSFODNN7EXAMPLE, use it"), ) conn.commit() finally: @@ -306,7 +306,7 @@ def test_a_credential_in_a_conversation_is_redacted_before_it_ships( _, db_bytes, _ = _export_to_tar(tmp_path) assert db_bytes is not None - assert b"AKIAIOSFODNN7EXAMPLE" not in db_bytes + assert b"glpat-IOSFODNN7EXAMPLE" not in db_bytes assert b"REDACTED" in db_bytes def test_the_redaction_is_byte_stable_across_exports(self, tmp_path, monkeypatch): @@ -328,7 +328,7 @@ def test_the_redaction_is_byte_stable_across_exports(self, tmp_path, monkeypatch try: conn.execute( "INSERT INTO conversations_v2 (conversation_id, value) VALUES (?, ?)", - ("c1", "key AKIAIOSFODNN7EXAMPLE and token ghp_" + "a" * 36), + ("c1", "key glpat-IOSFODNN7EXAMPLE and token ghp_" + "a" * 36), ) conn.commit() finally: diff --git a/test/test_aws_control_backup_ownership.py b/test/test_aws_control_backup_ownership.py index 8857705ae43..387e47cfa39 100644 --- a/test/test_aws_control_backup_ownership.py +++ b/test/test_aws_control_backup_ownership.py @@ -493,8 +493,8 @@ def test_a_foreign_label_is_redacted_and_bounded_before_it_is_rendered(self): assert cleaned.startswith("lap") and cleaned.endswith("top") assert backup.sanitize_label("") == "" assert backup.sanitize_label(12345) == "" - leaked = backup.sanitize_label("key AKIAIOSFODNN7EXAMPLE here") - assert "AKIAIOSFODNN7EXAMPLE" not in leaked + leaked = backup.sanitize_label("key glpat-IOSFODNN7EXAMPLE here") + assert "glpat-IOSFODNN7EXAMPLE" not in leaked def test_a_published_label_cannot_make_a_foreign_archive_restorable(self): # The whole point of the id/label split. A label is a string an install diff --git a/test/test_aws_control_backup_retry_backoff.py b/test/test_aws_control_backup_retry_backoff.py index 2154f301c6c..beabe555bb8 100644 --- a/test/test_aws_control_backup_retry_backoff.py +++ b/test/test_aws_control_backup_retry_backoff.py @@ -723,14 +723,14 @@ def test_a_credential_in_the_error_is_redacted_before_it_is_stored(self): record = _fail( ACCOUNT, backup.KIND_SNAPSHOT, - "1 file(s) are not text: AKIAIOSFODNN7EXAMPLE. They were NOT removed", + "1 file(s) are not text: glpat-IOSFODNN7EXAMPLE. They were NOT removed", ) - assert "AKIAIOSFODNN7EXAMPLE" not in record["error"] - assert "AKIA" not in record["error"] + assert "glpat-IOSFODNN7EXAMPLE" not in record["error"] + assert "glpat-" not in record["error"] assert "REDACTED" in record["error"] # And it is the STORED row that is clean, not just the returned dict. row = backup.nightly_failures(ACCOUNT)[backup.KIND_SNAPSHOT] - assert "AKIA" not in row["error"] + assert "glpat-" not in row["error"] def test_the_error_is_redacted_before_it_is_truncated(self): # Order, not just presence. Truncating first can cut a credential mid-token: the @@ -738,10 +738,10 @@ def test_the_error_is_redacted_before_it_is_truncated(self): # in a row that is served to a dashboard. Positioned so the 200-char bound falls # INSIDE the key, which is the only arrangement that can tell the two orders apart. backup.set_nightly(ACCOUNT, True) - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" prefix = "x" * (200 - len(key) + 10) # bound lands 10 chars into the key record = _fail(ACCOUNT, backup.KIND_SNAPSHOT, prefix + key) - assert "AKIA" not in record["error"], "a truncated credential fragment survived" + assert "glpat-" not in record["error"], "a truncated credential fragment survived" assert len(record["error"]) <= 200, "the length bound must still hold" def test_control_characters_are_stripped_from_the_error(self): diff --git a/test/test_aws_control_library.py b/test/test_aws_control_library.py index e94efa7c431..40319f6c51d 100644 --- a/test/test_aws_control_library.py +++ b/test/test_aws_control_library.py @@ -125,7 +125,7 @@ def test_redacts_name_and_joins_push_state_sorted(self, tmp_path, monkeypatch): ) newer = NS( slug="fresh", - name="key=AKIAIOSFODNN7EXAMPLEKEYX secret", + name="key=glpat-IOSFODNN7EXAMPLEKEYX secret", kind="markdown", version=1, updated_at="2026-06-01T00:00:00Z", @@ -139,7 +139,7 @@ def test_redacts_name_and_joins_push_state_sorted(self, tmp_path, monkeypatch): # Newest updatedAt sorts first. assert [r["slug"] for r in rows] == ["fresh", "pushed"] # The credential-shaped fragment in the name is redacted away. - assert "AKIAIOSFODNN7EXAMPLEKEYX" not in rows[0]["name"] + assert "glpat-IOSFODNN7EXAMPLEKEYX" not in rows[0]["name"] # An un-pushed artifact carries null push-state; the pushed one carries # the ledger's version. assert rows[0]["pushedVersion"] is None diff --git a/test/test_aws_control_routes.py b/test/test_aws_control_routes.py index f39bf3e9775..a147c23238d 100644 --- a/test/test_aws_control_routes.py +++ b/test/test_aws_control_routes.py @@ -66,11 +66,11 @@ def test_safe_error_runs_both_redaction_passes(self): # secret is the query payload, which must be gone.) beacon_payload = "QUJDREVGR0hJSktMTU5PUFFS" * 3 exc = AWSError( - "failed: aws_secret_access_key=AKIAIOSFODNN7EXAMPLEKEYX via " + "failed: aws_secret_access_key=glpat-IOSFODNN7EXAMPLEKEYX via " "https://collector.example.net/c?d=" + beacon_payload ) text = routes_mod._safe_error(exc) - assert "AKIAIOSFODNN7EXAMPLEKEYX" not in text + assert "glpat-IOSFODNN7EXAMPLEKEYX" not in text assert beacon_payload not in text # It is redacted, not passed through untouched. assert "[RE" in text or "redacted" in text.lower() @@ -585,7 +585,7 @@ def test_a_secret_straddling_the_window_never_reaches_the_browser(self): # trim then backs off to whitespace so no split run is shown either. window = 32 head = b"line one\nkey = " # 15 bytes - secret = b"AKIAIOSFODNN7EXAMPLE" # 20 bytes: straddles byte 32 + secret = b"glpat-IOSFODNN7EXAMPLE" # 20 bytes: straddles byte 32 tail = b"\nline three\n" data = head + secret + tail with ( @@ -596,8 +596,8 @@ def test_a_secret_straddling_the_window_never_reaches_the_browser(self): resp, headed = self._call(head=(data, len(data) + 1000)) body = _payload(resp) assert headed.call_args.kwargs["max_bytes"] == window + 64 - assert "AKIAIOSFODNN7EXAMPLE" not in body["content"] - assert "AKIAIOSFODNN" not in body["content"] + assert "glpat-IOSFODNN7EXAMPLE" not in body["content"] + assert "glpat-IOSFODNN" not in body["content"] assert body["truncated"] is True assert body["redacted"] is True assert body["content"].startswith("line one\n") @@ -648,12 +648,12 @@ def test_preview_redacts_credentials_like_every_other_egress(self): # A notes file that happens to hold an access key must render masked, # the same way listing and search names do -- the preview is a new # egress path and inherits the same floor. - secret = b"notes\naws_access_key_id = AKIAIOSFODNN7EXAMPLE\nmore notes\n" + secret = b"notes\naws_access_key_id = glpat-IOSFODNN7EXAMPLE\nmore notes\n" resp, _ = self._call(head=(secret, len(secret))) assert resp.status == 200 body = _payload(resp) content = body["content"] - assert "AKIAIOSFODNN7EXAMPLE" not in content + assert "glpat-IOSFODNN7EXAMPLE" not in content assert "REDACTED" in content assert content.startswith("notes\n") assert content.endswith("more notes\n") diff --git a/test/test_builtin_app_lifecycle.py b/test/test_builtin_app_lifecycle.py index d42c6ca4191..20ea1a39fc2 100644 --- a/test/test_builtin_app_lifecycle.py +++ b/test/test_builtin_app_lifecycle.py @@ -322,8 +322,8 @@ def test_passes_through_clean_string(self): def test_redacts_credentials(self): from kiro_crew.apps.routes import _redact_warning - result = _redact_warning("error: AKIA1234567890ABCDEF leaked") - assert "AKIA" not in result or "[REDACTED]" in result + result = _redact_warning("error: glpat-1234567890ABCDEF leaked") + assert "glpat-" not in result or "[REDACTED]" in result # ── _notify_builtin_service edge cases ── diff --git a/test/test_capability_agents_plugins.py b/test/test_capability_agents_plugins.py index f14c3c44256..bc77a3a6a02 100644 --- a/test/test_capability_agents_plugins.py +++ b/test/test_capability_agents_plugins.py @@ -593,7 +593,7 @@ def test_short_token_is_still_scrubbed(self): def test_credential_shapes_still_caught(self): from kiro_crew.dashboard.handlers.discover import _redact_external - assert "AKIAIOSFODNN7EXAMPLE" not in _redact_external("AKIAIOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in _redact_external("glpat-IOSFODNN7EXAMPLE") def test_benign_text_passes_through(self): from kiro_crew.dashboard.handlers.discover import _redact_external @@ -604,22 +604,22 @@ def test_benign_text_passes_through(self): def test_already_redacted_label_is_not_re_mangled(self): """A credential shape inside a named param keeps the core's own label. - `redact_credentials` turns `?token=AKIA…` into `?token=[REDACTED: + `redact_credentials` turns `?token=glpat-…` into `?token=[REDACTED: credential]`; without a negative lookahead the scrub re-matches that value (its class stops at the space) and leaves `[REDACTED] credential]`. The secret is removed either way — this keeps the message readable. """ from kiro_crew.dashboard.handlers.discover import _redact_external - out = _redact_external("?token=AKIAIOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in out + out = _redact_external("?token=glpat-IOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in out assert out == "?token=[REDACTED: credential]" def test_redaction_is_idempotent(self): """Re-redacting an already-redacted string must be a no-op.""" from kiro_crew.dashboard.handlers.discover import _redact_external - once = _redact_external("?token=AKIAIOSFODNN7EXAMPLE&api_key=abc123") + once = _redact_external("?token=glpat-IOSFODNN7EXAMPLE&api_key=abc123") assert _redact_external(once) == once diff --git a/test/test_channel_send_target.py b/test/test_channel_send_target.py index 433772a1d9e..6b6a5f6796a 100644 --- a/test/test_channel_send_target.py +++ b/test/test_channel_send_target.py @@ -178,10 +178,10 @@ async def test_credentials_are_redacted_before_the_wire(self) -> None: # own stream redaction. transport = _Transport() await mod._send_to_channel_target( - _state(webex=transport), "webex", "user:a@b.com", "key AKIAIOSFODNN7EXAMPLE here" + _state(webex=transport), "webex", "user:a@b.com", "key glpat-IOSFODNN7EXAMPLE here" ) - assert "AKIAIOSFODNN7EXAMPLE" not in transport.sent[0][1] + assert "glpat-IOSFODNN7EXAMPLE" not in transport.sent[0][1] @pytest.mark.asyncio async def test_a_delimiter_split_credential_is_redacted_too(self) -> None: @@ -193,10 +193,10 @@ async def test_a_delimiter_split_credential_is_redacted_too(self) -> None: """ transport = _Transport() await mod._send_to_channel_target( - _state(webex=transport), "webex", "user:a@b.com", "AKIA**IOSF**ODNN7EXAMPLE" + _state(webex=transport), "webex", "user:a@b.com", "glpat-**IOSF**ODNN7EXAMPLE" ) - assert "AKIAIOSFODNN7EXAMPLE" not in transport.sent[0][1].replace("*", "") + assert "glpat-IOSFODNN7EXAMPLE" not in transport.sent[0][1].replace("*", "") @pytest.mark.asyncio async def test_broadcast_mentions_are_defanged_where_the_platform_parses_them(self) -> None: @@ -232,10 +232,10 @@ async def test_credentials_are_still_redacted_without_the_defang(self) -> None: """Skipping the defang must not skip the display-form credential scan.""" transport = _Transport(mention_grammars=False) await mod._send_to_channel_target( - _state(webex=transport), "webex", "user:a@b.com", "AKIA**IOSF**ODNN7EXAMPLE" + _state(webex=transport), "webex", "user:a@b.com", "glpat-**IOSF**ODNN7EXAMPLE" ) - assert "AKIAIOSFODNN7EXAMPLE" not in transport.sent[0][1].replace("*", "") + assert "glpat-IOSFODNN7EXAMPLE" not in transport.sent[0][1].replace("*", "") class TestAuditing: diff --git a/test/test_channel_slots.py b/test/test_channel_slots.py index 1293859c4fe..c65ee3b180c 100644 --- a/test/test_channel_slots.py +++ b/test/test_channel_slots.py @@ -546,13 +546,13 @@ def test_restores_model_and_reasoning_effort_through_shared_helper( def test_redacts_titles_and_messages(self, dashboard_state: Any) -> None: slot = channel_slots.surface_channel_session( dashboard_state, - _session("slack:1.1", title="key AKIAIOSFODNN7EXAMPLE"), + _session("slack:1.1", title="key glpat-IOSFODNN7EXAMPLE"), {}, - [{"role": "assistant", "content": "token AKIAIOSFODNN7EXAMPLE"}], + [{"role": "assistant", "content": "token glpat-IOSFODNN7EXAMPLE"}], ) assert slot is not None - assert "AKIAIOSFODNN7EXAMPLE" not in slot.title - assert "AKIAIOSFODNN7EXAMPLE" not in slot.messages[0]["content"] + assert "glpat-IOSFODNN7EXAMPLE" not in slot.title + assert "glpat-IOSFODNN7EXAMPLE" not in slot.messages[0]["content"] class _FakeLog: diff --git a/test/test_chat_backfill.py b/test/test_chat_backfill.py index 7b180460f5c..78c0cffff47 100644 --- a/test/test_chat_backfill.py +++ b/test/test_chat_backfill.py @@ -246,7 +246,7 @@ async def test_markdown_is_converted_to_slack_mrkdwn(self, tmp_path): async def test_credentials_are_redacted(self, tmp_path): state = _state(tmp_path) slot = state.get_or_create_slot("s1") - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" _seed(slot, [("user", "here are creds"), ("assistant", f"key is {secret}")]) posted = await _drain(state, slot) @@ -340,7 +340,7 @@ async def test_ansi_credential_straddling_a_split_boundary_is_redacted(self, tmp state = _state(tmp_path) slot = state.get_or_create_slot("s1") - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" split_secret = secret[:6] + "\x1b[0m" + secret[6:] # split_message reserves room for CONTINUATION and, with no newline to @@ -372,10 +372,10 @@ async def test_conversion_cannot_reassemble_a_credential(self, tmp_path): """ state = _state(tmp_path) slot = state.get_or_create_slot("s1") - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" # An ANSI reset dropped into the middle of the key: invisible to the # credential regex, removed entirely by _strip_ansi. - split_secret = secret[:4] + "\x1b[0m" + secret[4:] + split_secret = secret[:6] + "\x1b[0m" + secret[6:] _seed(slot, [("user", "paste"), ("assistant", f"key is {split_secret}")]) posted = await _drain(state, slot) @@ -399,7 +399,7 @@ async def test_credential_straddling_the_mrkdwn_boundary_is_redacted(self, tmp_p """ state = _state(tmp_path) slot = state.get_or_create_slot("s1") - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" filler = "x" * (SLACK_MAX_TEXT - 10) content = filler + secret assert len(content) > SLACK_MAX_TEXT diff --git a/test/test_chat_follow_default.py b/test/test_chat_follow_default.py index beebcb6b726..a99c4bb3c39 100644 --- a/test/test_chat_follow_default.py +++ b/test/test_chat_follow_default.py @@ -50,8 +50,8 @@ PATH = "/api/chat/slots/follow-default" #: Fake AWS access-key shapes, built by concatenation as the repo's other redaction #: tests build them, so no secret scanner reads a key literal here. -_FAKE_KEY = "AKIA" + "IOSFODNN7EXAMPLE" -_OTHER_FAKE_KEY = "AKIA" + "IOSFODNN7EXAMPLF" +_FAKE_KEY = "glpat-" + "IOSFODNN7EXAMPLE" +_OTHER_FAKE_KEY = "glpat-" + "IOSFODNN7EXAMPLF" OLD = "claude-fable-5" PICK = "claude-sonnet-5" diff --git a/test/test_chat_mirror_link_delivery.py b/test/test_chat_mirror_link_delivery.py index 0957b6b88d0..5f53c250350 100644 --- a/test/test_chat_mirror_link_delivery.py +++ b/test/test_chat_mirror_link_delivery.py @@ -441,7 +441,7 @@ async def test_no_slack_mrkdwn_conversion_on_a_non_slack_channel(self, tmp_path, async def test_credentials_are_redacted(self, tmp_path, monkeypatch): state, transport = self._linked(tmp_path, monkeypatch) slot = state.get_or_create_slot("s1") - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" slot.append("user", "creds") slot.append("assistant", f"key is {secret}") slot.drain() diff --git a/test/test_chat_persistence_composition_contract.py b/test/test_chat_persistence_composition_contract.py index b61fd7db367..ab9786f0524 100644 --- a/test/test_chat_persistence_composition_contract.py +++ b/test/test_chat_persistence_composition_contract.py @@ -1103,7 +1103,7 @@ def test_undo_restores_the_facade_binding(self) -> None: original = cp.redact_credentials with pytest.MonkeyPatch.context() as patched: patched.setattr(cp, "redact_credentials", lambda text: ("x", [])) - entry = cp._build_message_entry_uncached({"role": "assistant", "content": "AKIA"}) + entry = cp._build_message_entry_uncached({"role": "assistant", "content": "glpat-"}) assert entry is not None and entry["content"] == "x" assert cp.redact_credentials is original @@ -1158,7 +1158,7 @@ def _scenario_full_save(state) -> dict: _rows( slot, ("user", "hello", 6, {"mid": "m-1", HUMAN_TURN_META_KEY: True}), - ("assistant", "the key is AKIAIOSFODNN7EXAMPLE", 7, {"mid": "m-2"}), + ("assistant", "the key is glpat-IOSFODNN7EXAMPLE", 7, {"mid": "m-2"}), ("system", "a notice", 8, {"mid": "m-3"}), ) ok = cp._save_slot_to_history(state, slot, force=True) diff --git a/test/test_chat_regenerate_cov80.py b/test/test_chat_regenerate_cov80.py index 8741240e964..aa6e855a57e 100644 --- a/test/test_chat_regenerate_cov80.py +++ b/test/test_chat_regenerate_cov80.py @@ -306,7 +306,7 @@ async def test_switch_variant_broadcasts_redacted_content(state) -> None: slot.append("user", "what is the key?") slot.append("assistant", "v2") slot.messages[-1]["variants"] = [ - {"content": "the key is AKIAIOSFODNN7EXAMPLE", "ts": "t1"}, + {"content": "the key is glpat-IOSFODNN7EXAMPLE", "ts": "t1"}, {"content": "v2", "ts": "t2"}, ] async with _client(state) as client: @@ -317,9 +317,9 @@ async def test_switch_variant_broadcasts_redacted_content(state) -> None: msg_type, payload = state.broadcast_ws.call_args.args assert msg_type == "chat_variant_switch" assert payload["index"] == 0 - assert "AKIAIOSFODNN7EXAMPLE" not in payload["content"] + assert "glpat-IOSFODNN7EXAMPLE" not in payload["content"] # The stored row keeps the real content; only the wire copy is redacted. - assert slot.messages[-1]["content"] == "the key is AKIAIOSFODNN7EXAMPLE" + assert slot.messages[-1]["content"] == "the key is glpat-IOSFODNN7EXAMPLE" assert slot.messages[-1]["ts"] == "t1" @@ -632,7 +632,7 @@ async def test_edit_resend_delivers_the_owners_edit_as_typed(state) -> None: async with _client(state) as client: resp = await client.post( "/api/chat/slots/s1/edit-resend", - json={"index": 0, "content": "use AKIAIOSFODNN7EXAMPLE please"}, + json={"index": 0, "content": "use glpat-IOSFODNN7EXAMPLE please"}, ) assert resp.status == 200 await asyncio.sleep(0) @@ -641,8 +641,8 @@ async def test_edit_resend_delivers_the_owners_edit_as_typed(state) -> None: # delivered as typed into both the persisted row and the turn input, the # same rule an idle send and a steer follow. An app-driven edit still # redacts (test_queued_user_text_display covers that boundary). - assert slot.messages[-1]["content"] == "use AKIAIOSFODNN7EXAMPLE please" - assert run.await_args.args[2] == "use AKIAIOSFODNN7EXAMPLE please" + assert slot.messages[-1]["content"] == "use glpat-IOSFODNN7EXAMPLE please" + assert run.await_args.args[2] == "use glpat-IOSFODNN7EXAMPLE please" @pytest.mark.asyncio diff --git a/test/test_chat_runner_coverage.py b/test/test_chat_runner_coverage.py index 1fc36a2d70a..a6366dc6c95 100644 --- a/test/test_chat_runner_coverage.py +++ b/test/test_chat_runner_coverage.py @@ -553,7 +553,7 @@ async def test_collapsed_coding_id_cannot_be_counted_by_unrelated_approval(self, state, client = _runner_state(tmp_path) client.mcp_session_report = MagicMock(return_value=None) slot = _slot() - coding_tool_call_id = "AKIAIOSFODNN7EXAMPLE" + coding_tool_call_id = "glpat-IOSFODNN7EXAMPLE" _set_stream( client, [ @@ -866,7 +866,7 @@ def _approve_when_registered() -> None: #: Fixture tokens for the glued-credential cases (made up, not real keys). -_AKIA_SAMPLE = "AKIA" + "5Q7XTR2M9LBC4WZN" +_AKIA_SAMPLE = "glpat-" + "5Q7XTR2M9LBC4WZN" _PEM_BEGIN = "-----BEGIN " + "PRIVATE KEY-----" _PEM_END = "-----END " + "PRIVATE KEY-----" _GLUED_PAT_A = "ghp_" + "eG7e5uHyQp2Lw9Rk4Ts8Vb1Nx6Jm3Cd0Zf5" @@ -889,7 +889,7 @@ class TestBlockedLinkCardRecords: """ H = "h.example-sink.net" - KEY = "AKIA" + "IOSFODNN7EXAMPLE" # AWS docs example key, split so no literal sits in the repo + KEY = "glpat-" + "IOSFODNN7EXAMPLE" # a fake token, split so no literal sits in the repo @staticmethod def _flush(deltas: list[str]) -> tuple[str, list[dict]]: @@ -1360,7 +1360,7 @@ def test_a_credential_a_glued_neighbour_cut_into_withholds_the_segment(self): [ "x " + _GLUED_PAT_A, _GLUED_PAT_B + " y https://h.example-sink.net/p?aws_access_key_id=", - "AKIA" + "5Q7XTR2M9LBC4WZN", + "glpat-" + "5Q7XTR2M9LBC4WZN", "¬e=" + _GLUED_PAT_B[-8:] + " z", ], id="an-unrelated-copy-of-the-tail", @@ -1371,7 +1371,7 @@ def test_a_credential_a_glued_neighbour_cut_into_withholds_the_segment(self): _GLUED_PAT_B + " y", " https://h.example-sink.net/p?note=" + _GLUED_PAT_B[3:] - + "&id=AKIA" + + "&id=glpat-" + "5Q7XTR2M9LBC4WZN z", ], id="a-blocked-address-quoting-the-body", @@ -1449,7 +1449,7 @@ def test_a_presigned_link_cut_anywhere_in_two_deltas_saves_no_key(self): for cut in range(1, len(reply) - 1, 3): deltas = [reply[:cut], reply[cut:]] content, _ = self._flush(deltas) - assert self.KEY[4:] not in content, cut + assert self.KEY[6:] not in content, cut if content != chat_runner._SEGMENT_UNCHECKED_TEXT: streamed = "".join(chat_runner._redact_delta(d)[0] for d in deltas) main = redact_credentials(redact_exfiltration_urls(streamed)[0])[0] @@ -1663,7 +1663,8 @@ def _key_split_presigned_deltas() -> list[str]: rows ``website/src/test/fixtures/credInUrl.json`` and ``blockedLinkOneOne.json`` still render).""" host = "my-bucket.s3.us-east-1.amazonaws.com" - key = TestBlockedLinkCardRecords.KEY + # A presigned address carries a key ID in its credential field. + key = "AKIA" + "IOSFODNN7EXAMPLE" deltas: list[str] = [] for i, name in enumerate(("report.csv", "invoice.pdf")): url = ( @@ -1679,7 +1680,7 @@ def _key_split_presigned_deltas() -> list[str]: def test_key_split_links_are_withheld_not_saved_unredacted(self): """A delta blocked each address's head, but the whole text keeps the - address (its key tagged): main's save never showed that address, so + address (a credential tag inside it): main's save never showed it, so under default refuse the segment is withheld, and no key is saved.""" content, links = self._flush(self._key_split_presigned_deltas()) assert (content, links) == (chat_runner._SEGMENT_UNCHECKED_TEXT, []) diff --git a/test/test_chat_runner_coverage_output.py b/test/test_chat_runner_coverage_output.py index 3fef0eb6272..bb942952e7c 100644 --- a/test/test_chat_runner_coverage_output.py +++ b/test/test_chat_runner_coverage_output.py @@ -167,19 +167,19 @@ class TestFlushFileChanges: def test_credentials_are_scrubbed_from_before_and_after(self, tmp_path): """A secret in a non-sensitive config must not reach message meta.""" target = tmp_path / "config.ini" - target.write_text("key=AKIAIOSFODNN7EXAMPLE\nafter\n", newline="\n") + target.write_text("key=glpat-IOSFODNN7EXAMPLE\nafter\n", newline="\n") slot = _slot() slot.append("assistant", "done", "msg msg-a", broadcast=False) slot._file_changes = [ - {"path": str(target), "content": "key=AKIAIOSFODNN7EXAMPLE\nbefore\n"} + {"path": str(target), "content": "key=glpat-IOSFODNN7EXAMPLE\nbefore\n"} ] chat_runner._flush_file_changes(slot) changes = slot.messages[-1]["meta"]["file_changes"] assert len(changes) == 1 - assert "AKIAIOSFODNN7EXAMPLE" not in changes[0]["before"] - assert "AKIAIOSFODNN7EXAMPLE" not in changes[0]["after"] + assert "glpat-IOSFODNN7EXAMPLE" not in changes[0]["before"] + assert "glpat-IOSFODNN7EXAMPLE" not in changes[0]["after"] assert slot._dirty is True assert slot._file_changes == [] @@ -241,9 +241,9 @@ def test_empty_string_passes_through(self): assert chat_runner._redact_acp_string("") == "" def test_credential_is_scrubbed(self): - out = chat_runner._redact_acp_string("token AKIAIOSFODNN7EXAMPLE") + out = chat_runner._redact_acp_string("token glpat-IOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in out + assert "glpat-IOSFODNN7EXAMPLE" not in out class TestOauthUrlCredentialGate: @@ -264,7 +264,7 @@ def test_unparseable_url_is_refused(self): assert oauth_url_contains_credential("https://[bad-ipv6/x") is True def test_credential_signature_inside_an_oauth_param_is_refused(self): - url = "https://example.test/authorize?state=AKIAIOSFODNN7EXAMPLE1" + url = "https://example.test/authorize?state=glpat-IOSFODNN7EXAMPLE1" assert oauth_url_contains_credential(url) is True @@ -289,7 +289,7 @@ def test_credential_bearing_url_renders_a_rejected_banner(self, tmp_path): state, slot = _state(tmp_path), _slot() chat_runner._emit_mcp_oauth_request( - state, slot, "svc", "https://example.test/a?state=AKIAIOSFODNN7EXAMPLE1" + state, slot, "svc", "https://example.test/a?state=glpat-IOSFODNN7EXAMPLE1" ) assert slot.messages[-1]["meta"]["rejected_url"] is True @@ -404,12 +404,12 @@ def test_failure_records_the_redacted_error(self, tmp_path): self._open_banner(state, slot) chat_runner._mark_mcp_oauth_completed( - state, slot, "github", False, "denied for AKIAIOSFODNN7EXAMPLE" + state, slot, "github", False, "denied for glpat-IOSFODNN7EXAMPLE" ) meta = slot.messages[-1]["meta"] assert meta["failed"] is True - assert "AKIAIOSFODNN7EXAMPLE" not in meta["error"] + assert "glpat-IOSFODNN7EXAMPLE" not in meta["error"] assert "authentication failed" in slot.messages[-1]["content"] def test_untimestamped_banner_cannot_be_updated(self, tmp_path): @@ -619,7 +619,7 @@ def test_pending_variants_are_attached_and_broadcast(self, tmp_path): def test_credentials_in_the_segment_are_redacted(self, tmp_path): state, slot = _state(tmp_path), _slot() - chat_runner._flush_segment(state, slot, "secret AKIAIOSFODNN7EXAMPLE here") + chat_runner._flush_segment(state, slot, "secret glpat-IOSFODNN7EXAMPLE here") # Target the assistant row by role, not `messages[-1]`: a redacted # segment now also appends a notice row after it, and asserting on the @@ -629,7 +629,7 @@ def test_credentials_in_the_segment_are_redacted(self, tmp_path): # that cannot distinguish "no assistant row" from "the flush threw". assistants = [m for m in slot.messages if m.get("role") == "assistant"] assert len(assistants) == 1, f"expected one assistant row, got {slot.messages}" - assert "AKIAIOSFODNN7EXAMPLE" not in assistants[0]["content"] + assert "glpat-IOSFODNN7EXAMPLE" not in assistants[0]["content"] def test_a_redacted_credential_is_described_not_noticed(self, tmp_path): """The lock tag replaces the grey notice: the row carries one record per @@ -740,7 +740,7 @@ def test_records_come_from_the_one_whole_text_pass(self, tmp_path): state, slot = _state(tmp_path), _slot() url = "https://collector.example-sink.net/v1/ingest?d=" + "eyJhIjoiYiJ9" * 30 - key = "AKIA" + "5Q7XTR2M9LBC4WZN" + key = "glpat-" + "5Q7XTR2M9LBC4WZN" raw = f"key {key} then [see]({url}) done." text = "" for delta in (raw[:6], raw[6:60], raw[60:]): @@ -755,9 +755,9 @@ def test_records_come_from_the_one_whole_text_pass(self, tmp_path): chat_runner._flush_segment(state, slot, text) content, meta = slot.messages[0]["content"], slot.messages[0]["meta"] - assert key[4:] not in content and "eyJ" not in content + assert key[6:] not in content and "eyJ" not in content assert [r["domain"] for r in meta["blocked_links"]] == ["collector.example-sink.net"] - assert [r["rule"] for r in meta["redactions"]] == ["aws_access_key_id"] + assert [r["rule"] for r in meta["redactions"]] == ["gitlab_token"] def test_trailing_stop_event_is_replaced_below_the_segment(self, tmp_path): state, slot = _state(tmp_path), _slot() @@ -867,11 +867,11 @@ def test_terminal_status_completes_the_card_with_a_redacted_error(self, tmp_path entry = {"sessionId": "s2", "role": "worker", "initialQuery": "do it"} chat_runner._native_subagent_sync(state, slot, [entry], tracker) - entry["status"] = {"type": "failed", "message": "boom AKIAIOSFODNN7EXAMPLE"} + entry["status"] = {"type": "failed", "message": "boom glpat-IOSFODNN7EXAMPLE"} chat_runner._native_subagent_sync(state, slot, [entry], tracker) assert tracker["s2"]["done"] is True - assert "AKIAIOSFODNN7EXAMPLE" not in tracker["s2"]["error"] + assert "glpat-IOSFODNN7EXAMPLE" not in tracker["s2"]["error"] def test_status_message_surfaces_as_the_current_tool(self, tmp_path): state, slot = _state(tmp_path), _slot() @@ -957,9 +957,9 @@ def test_done_result_marks_a_truncated_feed(self): assert out.startswith(chat_runner.NATIVE_SUBAGENT_DONE_TRUNC_MARKER) def test_card_feed_redacts_before_the_broadcast(self): - feed = chat_runner._native_card_feed({"native:x": ["AKIAIOSFODNN7EXAMPLE"]}, "native:x") + feed = chat_runner._native_card_feed({"native:x": ["glpat-IOSFODNN7EXAMPLE"]}, "native:x") - assert "AKIAIOSFODNN7EXAMPLE" not in feed + assert "glpat-IOSFODNN7EXAMPLE" not in feed def test_empty_card_feed_is_empty(self): assert chat_runner._native_card_feed(None, "native:x") == "" diff --git a/test/test_chat_runner_coverage_turn_start.py b/test/test_chat_runner_coverage_turn_start.py index f53ddb949ca..86b068bd1a7 100644 --- a/test/test_chat_runner_coverage_turn_start.py +++ b/test/test_chat_runner_coverage_turn_start.py @@ -705,7 +705,7 @@ def test_resolved_skill_body_is_appended_and_redacted(self, tmp_path): state, slot = _state(tmp_path), _slot() skills = MagicMock() skills.resolve_dollar_skills.return_value = [ - ("$deploy", "deploy", "step one AKIAIOSFODNN7EXAMPLE") + ("$deploy", "deploy", "step one glpat-IOSFODNN7EXAMPLE") ] with patch.object(chat_runner, "_get_skills", return_value=skills): @@ -715,7 +715,7 @@ def test_resolved_skill_body_is_appended_and_redacted(self, tmp_path): assert count == 1 assert "[Skill: deploy]" in expanded - assert "AKIAIOSFODNN7EXAMPLE" not in expanded + assert "glpat-IOSFODNN7EXAMPLE" not in expanded assert slot.messages[-1]["role"] == "system" diff --git a/test/test_chat_steer.py b/test/test_chat_steer.py index 1572cce9794..95241101792 100644 --- a/test/test_chat_steer.py +++ b/test/test_chat_steer.py @@ -407,7 +407,7 @@ async def test_raced_steer_persists_send_id_on_new_turn_row( {"id": "s-1"}, "has spaces", "a/b+c=", - "AKIAIOSFODNN7EXAMPLE", + "glpat-IOSFODNN7EXAMPLE", ], ids=[ "non-string", diff --git a/test/test_chat_tags.py b/test/test_chat_tags.py index f9ef2fa2342..047252ac9d7 100644 --- a/test/test_chat_tags.py +++ b/test/test_chat_tags.py @@ -837,11 +837,11 @@ async def test_update_tag_redacts_credentials_in_name(self, tmp_path, monkeypatc tag = await (await client.post("/api/chat/tags", json={"name": "Safe"})).json() resp = await client.patch( f"/api/chat/tags/{tag['id']}", - json={"name": "key-AKIAIOSFODNN7EXAMPLE"}, + json={"name": "key-glpat-IOSFODNN7EXAMPLE"}, ) assert resp.status == 200 data = await resp.json() - assert "AKIAIOSFODNN7EXAMPLE" not in data["name"] + assert "glpat-IOSFODNN7EXAMPLE" not in data["name"] @pytest.mark.asyncio async def test_update_tag_redacts_credential_straddling_truncation(self, tmp_path, monkeypatch): @@ -855,11 +855,11 @@ async def test_update_tag_redacts_credential_straddling_truncation(self, tmp_pat tag = await (await client.post("/api/chat/tags", json={"name": "Redact"})).json() resp = await client.patch( f"/api/chat/tags/{tag['id']}", - json={"name": "x" * 50 + "AKIAIOSFODNN7EXAMPLE"}, + json={"name": "x" * 50 + "glpat-IOSFODNN7EXAMPLE"}, ) assert resp.status == 200 data = await resp.json() - assert "AKIA" not in data["name"] + assert "glpat-" not in data["name"] @pytest.mark.asyncio async def test_create_tag_redacts_credential_straddling_truncation(self, tmp_path, monkeypatch): @@ -869,11 +869,11 @@ async def test_create_tag_redacts_credential_straddling_truncation(self, tmp_pat async with TestClient(TestServer(app)) as client: resp = await client.post( "/api/chat/tags", - json={"name": "x" * 50 + "AKIAIOSFODNN7EXAMPLE"}, + json={"name": "x" * 50 + "glpat-IOSFODNN7EXAMPLE"}, ) assert resp.status == 201 data = await resp.json() - assert "AKIA" not in data["name"] + assert "glpat-" not in data["name"] @pytest.mark.asyncio async def test_delete_tag_persists_vocab_before_slots(self, tmp_path, monkeypatch): diff --git a/test/test_chat_threads.py b/test/test_chat_threads.py index 2c1d0130930..660ff0a501c 100644 --- a/test/test_chat_threads.py +++ b/test/test_chat_threads.py @@ -511,7 +511,7 @@ def test_unreadable_sidecar_is_refused_never_overwritten(tmp_path): M("m"): "not-a-list", # A key that is not a minted row id is not a thread: the # summary route hands keys to the dashboard as they are. - "AKIAIOSFODNN7EXAMPLE": [ + "glpat-IOSFODNN7EXAMPLE": [ {"id": "3" * 32, "role": "user", "content": "x", "ts": ""} ], M("n"): [ @@ -522,13 +522,13 @@ def test_unreadable_sidecar_is_refused_never_overwritten(tmp_path): "role": "user", "content": "ok", "ts": "2026-09-22T07:41:00+00:00", - "token": "AKIA...", + "token": "glpat-...", }, # Metadata not in the writer's shape is not a reply the # store wrote: an id or ts that could carry prose (a # credential an agent put there) never reaches the # dashboard, since only ``content`` is redacted on the way out. - {"id": "AKIAIOSFODNN7EXAMPLE", "role": "user", "content": "x", "ts": ""}, + {"id": "glpat-IOSFODNN7EXAMPLE", "role": "user", "content": "x", "ts": ""}, {"id": "1" * 32, "role": "user", "content": "x", "ts": "ghp_secret"}, {"id": "2" * 32, "role": "system", "content": "x", "ts": ""}, ], @@ -1392,7 +1392,7 @@ def test_a_credential_straddling_the_line_cap_is_scrubbed_before_the_cut(): """The envelope leaves the dashboard's storage, so a crewmate row is redacted on the way out -- and BEFORE the per-line cap, or a secret straddling the cap would be cut to a fragment the redactor cannot recognise and leave as plain text.""" - secret = "AKIA" + "Q" * 16 + secret = "glpat-" + "Q" * 16 prefix = "x" * 30 cap = len(prefix) + 12 # the cut lands inside the key line = chat_threads._line(chat_threads.ROLE_ASSISTANT, prefix + secret, cap) diff --git a/test/test_chat_utils.py b/test/test_chat_utils.py index a6e8346410c..d1168cc8d47 100644 --- a/test/test_chat_utils.py +++ b/test/test_chat_utils.py @@ -28,21 +28,21 @@ class TestRedactDeep: def test_string(self): - # AKIAIOSFODNN7EXAMPLE is a well-known test AWS key - result = _redact_deep("key AKIAIOSFODNN7EXAMPLE here") - assert "AKIAIOSFODNN7EXAMPLE" not in result + # glpat-IOSFODNN7EXAMPLE is a fake GitLab-shaped token + result = _redact_deep("key glpat-IOSFODNN7EXAMPLE here") + assert "glpat-IOSFODNN7EXAMPLE" not in result def test_dict(self): - result = _redact_deep({"a": "AKIAIOSFODNN7EXAMPLE"}) - assert "AKIAIOSFODNN7EXAMPLE" not in result["a"] + result = _redact_deep({"a": "glpat-IOSFODNN7EXAMPLE"}) + assert "glpat-IOSFODNN7EXAMPLE" not in result["a"] def test_list(self): - result = _redact_deep(["AKIAIOSFODNN7EXAMPLE"]) - assert "AKIAIOSFODNN7EXAMPLE" not in result[0] + result = _redact_deep(["glpat-IOSFODNN7EXAMPLE"]) + assert "glpat-IOSFODNN7EXAMPLE" not in result[0] def test_nested(self): - result = _redact_deep({"a": [{"b": "AKIAIOSFODNN7EXAMPLE"}]}) - assert "AKIAIOSFODNN7EXAMPLE" not in result["a"][0]["b"] + result = _redact_deep({"a": [{"b": "glpat-IOSFODNN7EXAMPLE"}]}) + assert "glpat-IOSFODNN7EXAMPLE" not in result["a"][0]["b"] def test_non_string_passthrough(self): assert _redact_deep(42) == 42 @@ -229,8 +229,8 @@ def test_collapse_keeps_the_max_seq_and_never_mutates_input(self): class TestRedactForDisplay: def test_redacts_credentials(self): - result = _redact_for_display("key AKIAIOSFODNN7EXAMPLE here") - assert "AKIAIOSFODNN7EXAMPLE" not in result + result = _redact_for_display("key glpat-IOSFODNN7EXAMPLE here") + assert "glpat-IOSFODNN7EXAMPLE" not in result def test_content_cache_misses_when_exempt_host_set_changes(self, monkeypatch): """The exempt-host set is an input to the battery, so it is part of the key.""" @@ -278,7 +278,7 @@ def counted_credentials(value): monkeypatch.setattr(chat_utils, "redact_credentials", counted_credentials) monkeypatch.setattr(display_battery, "redact_exfiltration_urls", counted_exfiltration) monkeypatch.setattr(display_battery, "redact_credentials", counted_credentials) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" messages = [ { "role": "assistant", @@ -313,7 +313,7 @@ def test_content_cache_key_is_fixed_size_and_fully_accounted(self, monkeypatch): the byte cap. So the key footprint must not move with the size of that set, and the accounted bytes must cover the digest and the redacted output. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" texts = [f"row {i} carries {secret}" for i in range(64)] def key_footprint(hosts: frozenset[str]) -> int: @@ -367,7 +367,7 @@ def counted_credentials(value): monkeypatch.setattr(chat_utils, "redact_credentials", counted_credentials) monkeypatch.setattr(display_battery, "redact_exfiltration_urls", counted_exfiltration) monkeypatch.setattr(display_battery, "redact_credentials", counted_credentials) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" rows = chat_utils.SLOT_DETAIL_MAX_LIMIT messages = [ { @@ -426,7 +426,7 @@ def counted_credentials(value): monkeypatch.setattr(chat_utils, "redact_credentials", counted_credentials) monkeypatch.setattr(display_battery, "redact_exfiltration_urls", counted_exfiltration) monkeypatch.setattr(display_battery, "redact_credentials", counted_credentials) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" rows = 12_000 messages = [ { @@ -510,7 +510,7 @@ def test_content_cache_key_is_a_keyed_mac_over_text_and_hosts(self, monkeypatch) """ hosts = frozenset({"docs.contoso.sharepoint.com"}) monkeypatch.setattr(chat_utils, "_exempt_exact_hosts", lambda: hosts) - text = "key AKIAIOSFODNN7EXAMPLE here" + text = "key glpat-IOSFODNN7EXAMPLE here" raw = text.encode("utf-8") hosts_bytes = "\0".join(sorted(hosts)).encode("utf-8") (digest, length), input_bytes = chat_utils._display_redaction_cache_key(text) @@ -541,8 +541,8 @@ def test_short_ascii_passthrough(self): assert result == "hello world" def test_redacts_credentials(self): - result = _redact_tool_field("key AKIAIOSFODNN7EXAMPLE here") - assert "AKIAIOSFODNN7EXAMPLE" not in result + result = _redact_tool_field("key glpat-IOSFODNN7EXAMPLE here") + assert "glpat-IOSFODNN7EXAMPLE" not in result def test_ascii_truncation(self): # ASCII: 1 byte per char, so 200 chars = 200 bytes; cap at 50. diff --git a/test/test_cli_chat_consent_surface.py b/test/test_cli_chat_consent_surface.py index 4cfd6b74ae5..d7c6b40ff1d 100644 --- a/test/test_cli_chat_consent_surface.py +++ b/test/test_cli_chat_consent_surface.py @@ -935,7 +935,7 @@ def test_audit_scrubs_a_credential_out_of_the_tool_identity(self, monkeypatch): import kiro_crew.cli_chat as cli_chat - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" trace: list = [] gate = self._gate() monkeypatch.setattr( diff --git a/test/test_cli_chat_permission.py b/test/test_cli_chat_permission.py index 3a8102caede..52a1ab0dfac 100644 --- a/test/test_cli_chat_permission.py +++ b/test/test_cli_chat_permission.py @@ -114,7 +114,7 @@ async def test_the_audit_precedes_the_transport( ), # No canonical name: the title is all there is, so scrub it -- SEL # does not redact for its callers. - (dict(title="deploy with AKIAIOSFODNN7EXAMPLE"), None, "AKIAIOSFODNN7EXAMPLE"), + (dict(title="deploy with glpat-IOSFODNN7EXAMPLE"), None, "glpat-IOSFODNN7EXAMPLE"), ], ) async def test_the_audited_identity_is_not_model_authored( @@ -213,7 +213,7 @@ async def test_a_prompt_nobody_can_answer_denies_without_reading_stdin( # Capped, with the cut made explicit. ("echo " + "x" * 400, "... [truncated]", "x" * 400), # Redacted on the way to the screen. - ("deploy --key AKIAIOSFODNN7EXAMPLE", None, "AKIAIOSFODNN7EXAMPLE"), + ("deploy --key glpat-IOSFODNN7EXAMPLE", None, "glpat-IOSFODNN7EXAMPLE"), # Nothing to show for a non-shell call. (None, None, "Command:"), ], diff --git a/test/test_cli_doctor_member_memory.py b/test/test_cli_doctor_member_memory.py index 34ed52c77b3..6d27d64323d 100644 --- a/test/test_cli_doctor_member_memory.py +++ b/test/test_cli_doctor_member_memory.py @@ -231,7 +231,7 @@ def test_dispatchability_is_silent_for_an_nfd_only_legacy_name(members, capsys): def test_nondispatchable_member_name_is_reported_by_count_without_disclosure(members, capsys): cfg, _, _, writes = members - name = "AKIAIOSFODNN7EXAMPLE" + name = "glpat-IOSFODNN7EXAMPLE" cfg.agents[name] = KiroCrewAgentConfig() cfg.save() cfg = KiroCrewConfig.load() @@ -256,7 +256,7 @@ def test_nondispatchable_member_name_is_reported_by_count_without_disclosure(mem def test_memory_binding_diagnostic_skips_nondispatchable_record(members, capsys): cfg, home, private_store, writes = members - name = "AKIAIOSFODNN7EXAMPLE" + name = "glpat-IOSFODNN7EXAMPLE" cfg.agents[name] = KiroCrewAgentConfig() cfg.save() cfg = KiroCrewConfig.load() @@ -296,7 +296,7 @@ def _raise(name): def test_dispatchability_survives_a_platform_composition_failure(members, capsys, monkeypatch): cfg, _, _, writes = members - name = "AKIAIOSFODNN7EXAMPLE" + name = "glpat-IOSFODNN7EXAMPLE" cfg.agents[name] = KiroCrewAgentConfig() cfg.save() cfg = KiroCrewConfig.load() @@ -318,7 +318,7 @@ def test_dispatchability_survives_a_platform_composition_failure(members, capsys def test_memory_bindings_survive_a_platform_composition_failure(members, capsys, monkeypatch): cfg, home, _, writes = members - name = "AKIAIOSFODNN7EXAMPLE" + name = "glpat-IOSFODNN7EXAMPLE" cfg.agents[name] = KiroCrewAgentConfig() cfg.save() cfg = KiroCrewConfig.load() diff --git a/test/test_command_surface_fixes.py b/test/test_command_surface_fixes.py index d5dc32b5fa4..9571a348b8d 100644 --- a/test/test_command_surface_fixes.py +++ b/test/test_command_surface_fixes.py @@ -492,7 +492,7 @@ async def test_a_hook_reply_is_redacted_before_it_reaches_the_channel( ) -> None: """This path skips TurnDriver, which is what redacts everything else.""" _patch_pipeline(monkeypatch) - leaked = "key AKIAIOSFODNN7EXAMPLE here" + leaked = "key glpat-IOSFODNN7EXAMPLE here" renderer = _PipelineRenderer() persisted: list[tuple[str, str, bool]] = [] @@ -502,9 +502,9 @@ async def test_a_hook_reply_is_redacted_before_it_reaches_the_channel( ctx_builder=_CtxBuilder(HookResult.reply(leaked)), ) - assert renderer.chunks and "AKIAIOSFODNN7EXAMPLE" not in renderer.chunks[0] + assert renderer.chunks and "glpat-IOSFODNN7EXAMPLE" not in renderer.chunks[0] # And the transcript records what was shown, not the raw credential. - assert "AKIAIOSFODNN7EXAMPLE" not in persisted[0][1] + assert "glpat-IOSFODNN7EXAMPLE" not in persisted[0][1] @pytest.mark.asyncio diff --git a/test/test_computer_use_policy_cov80.py b/test/test_computer_use_policy_cov80.py index 955a3dc53b9..a62e7da36f9 100644 --- a/test/test_computer_use_policy_cov80.py +++ b/test/test_computer_use_policy_cov80.py @@ -253,7 +253,7 @@ def test_egress_pass_routes_through_the_platform_seam(self) -> None: assert policy.redact_result("zibble wobble") == "zibble wobble" def test_a_credential_shaped_string_does_not_survive_verbatim(self) -> None: - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" assert secret not in policy.redact_result(f"key={secret}") diff --git a/test/test_conductor_base_work_ledger.py b/test/test_conductor_base_work_ledger.py index e37186eac81..3aecfca4f99 100644 --- a/test/test_conductor_base_work_ledger.py +++ b/test/test_conductor_base_work_ledger.py @@ -489,7 +489,7 @@ async def test_a_session_send_hand_back_redacts_the_decision(tmp_path, monkeypat its crew-log entry hold the same redacted text, never the raw secret.""" recorded: list[dict[str, Any]] = [] item_id, slots = await _board_with_blocked_item(tmp_path, monkeypatch, recorded) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" resp = await _session_send( monkeypatch, slots, caller=PIPELINE, target=WORKER, message=f"use key {secret}" diff --git a/test/test_config_agent_fields_redaction.py b/test/test_config_agent_fields_redaction.py index 8cae7d80de5..37ef36ac6a7 100644 --- a/test/test_config_agent_fields_redaction.py +++ b/test/test_config_agent_fields_redaction.py @@ -39,7 +39,7 @@ # Shapes _redact_external verifiably alters (probed against the real chain): # a credential-shaped token, and a URL with a conventionally-named secret param. -_CRED_DESCRIPTION = "helper agent AKIAIOSFODNN7EXAMPLE for builds" +_CRED_DESCRIPTION = "helper agent glpat-IOSFODNN7EXAMPLE for builds" _EXFIL_TRIGGERS = "post results to https://collector.example.com/x?token=abc123" # Benign strings the redactors leave byte-identical, including non-ASCII. _BENIGN_DESCRIPTION = "Reviews pull requests and summarizes diffs." @@ -135,7 +135,7 @@ def test_suspicious_agent_fields_leave_masked(self): assert masked["agents"]["shady"]["description"] == _SENSITIVE_MASK assert masked["agents"]["shady"]["triggers"] == _SENSITIVE_MASK body = json.dumps(masked) - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body assert "collector.example.com" not in body def test_benign_agent_fields_are_untouched(self): @@ -182,7 +182,7 @@ def test_suspicious_record_key_is_removed_not_leaked(self): masked = _masked_config_dict(cfg) assert _CRED_DESCRIPTION not in masked["agents"] assert "plain" in masked["agents"] - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(masked) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(masked) # save() still carries the record — only the browser view drops it. assert _CRED_DESCRIPTION in cfg.to_dict()["agents"] @@ -196,7 +196,7 @@ def test_name_references_to_removed_record_are_masked(self): masked = _masked_config_dict(cfg) assert masked["default_agent"] == _SENSITIVE_MASK assert masked["session"]["pool_agent"] == _SENSITIVE_MASK - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(masked) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(masked) def test_benign_name_references_are_untouched(self): cfg = KiroCrewConfig() @@ -257,7 +257,7 @@ async def test_get_response_masks_agent_free_text(self, tmp_path, monkeypatch): body = await resp.json() assert body["agents"]["kirocrew"]["description"] == _SENSITIVE_MASK assert body["agents"]["kirocrew"]["triggers"] == _SENSITIVE_MASK - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(body) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(body) @pytest.mark.asyncio async def test_patch_echo_masks_agent_free_text(self, tmp_path, monkeypatch): @@ -279,7 +279,7 @@ async def test_patch_echo_masks_agent_free_text(self, tmp_path, monkeypatch): body = await resp.json() assert body["agents"]["kirocrew"]["description"] == _SENSITIVE_MASK assert body["agents"]["kirocrew"]["triggers"] == _SENSITIVE_MASK - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(body) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(body) # The PATCH wrote only its own path; the stored free text is untouched. stored = json.loads(cfg_path.read_text(encoding="utf-8")) assert stored["agents"]["kirocrew"]["description"] == _CRED_DESCRIPTION diff --git a/test/test_connections_mint_flow.py b/test/test_connections_mint_flow.py index e5e73164732..f9a924a5958 100644 --- a/test/test_connections_mint_flow.py +++ b/test/test_connections_mint_flow.py @@ -877,7 +877,7 @@ async def ensure_ready(self) -> None: async def test_a_credential_bearing_url_is_disposed_and_retried_once( monkeypatch: pytest.MonkeyPatch, protected_pids: set[int], caplog ): - tainted = "https://auth.example.com/authorize?client_id=abc&access_token=AKIAIOSFODNN7EXAMPLE" + tainted = "https://auth.example.com/authorize?client_id=abc&access_token=glpat-IOSFODNN7EXAMPLE" class _Tainted(_FakeClient): def __init__(self, **kwargs: Any) -> None: @@ -907,8 +907,8 @@ def __init__(self, **kwargs: Any) -> None: assert fresh.shutdowns == 0 assert protected_pids == {fresh._pid} assert logged == ["ok url_minted=True"] - assert "AKIAIOSFODNN7EXAMPLE" not in caplog.text - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(logged) + assert "glpat-IOSFODNN7EXAMPLE" not in caplog.text + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(logged) await mint._dispose_mint(mint._mints["notion"]) assert fresh.shutdowns == 1 @@ -941,7 +941,7 @@ def _screen(_url: str) -> bool: async def test_a_second_credential_bearing_url_surfaces_failure_without_a_third_attempt( monkeypatch: pytest.MonkeyPatch, protected_pids: set[int], caplog ): - tainted = "https://auth.example.com/authorize?client_id=abc&access_token=AKIAIOSFODNN7EXAMPLE" + tainted = "https://auth.example.com/authorize?client_id=abc&access_token=glpat-IOSFODNN7EXAMPLE" class _Tainted(_FakeClient): def __init__(self, **kwargs: Any) -> None: @@ -973,8 +973,8 @@ def __init__(self, **kwargs: Any) -> None: assert [client.shutdowns for client in _FakeClient.instances] == [1, 1] assert protected_pids == set() assert logged == ["error reason=mint_url_rejected"] - assert "AKIAIOSFODNN7EXAMPLE" not in caplog.text - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(logged) + assert "glpat-IOSFODNN7EXAMPLE" not in caplog.text + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(logged) assert "auth.example.com" not in caplog.text assert tainted not in json.dumps(view) @@ -1018,10 +1018,10 @@ def __init__(self, **kwargs: Any) -> None: "tainted", [ # The credential IS the host label: a redacted host would name nothing. - "https://AKIAIOSFODNN7EXAMPLE.example.com/authorize?client_id=abc", + "https://glpat-IOSFODNN7EXAMPLE.example.com/authorize?client_id=abc", # The credential is a PATH segment: the diagnostic pair carries the # redaction tag, which is not a path a user could type. - "https://idp.example.com/AKIAIOSFODNN7EXAMPLE/authorize", + "https://idp.example.com/glpat-IOSFODNN7EXAMPLE/authorize", # Nameable host+path, but the extension loader would refuse the host, # so naming it would advertise an entry that gets skipped on load. _EXEMPTIBLE_URL.replace(_EXEMPTIBLE_HOST, "localhost", 1), @@ -1030,9 +1030,9 @@ def __init__(self, **kwargs: Any) -> None: _EXEMPTIBLE_URL.replace(_EXEMPTIBLE_HOST, _EXEMPTIBLE_HOST + ":8443", 1), # Nameable, loader-valid host+path, but a fixed credential in the query # is refused unconditionally -- the allowlist would not clear it. - f"https://{_EXEMPTIBLE_HOST}{_EXEMPTIBLE_PATH}?access_token=AKIAIOSFODNN7EXAMPLE", + f"https://{_EXEMPTIBLE_HOST}{_EXEMPTIBLE_PATH}?access_token=glpat-IOSFODNN7EXAMPLE", # Same, for a fragment: providers never emit one, the gate never allows one. - _EXEMPTIBLE_URL + "#AKIAIOSFODNN7EXAMPLE", + _EXEMPTIBLE_URL + "#glpat-IOSFODNN7EXAMPLE", ], ids=[ "credential-in-host", @@ -1055,9 +1055,9 @@ async def test_a_rejection_the_helper_cannot_name_leaves_the_card_unnamed( assert view is not None assert _state_only(view) == {"state": "failed", "reason": "mint_url_rejected"} assert logged == ["error reason=mint_url_rejected"] - assert "AKIAIOSFODNN7EXAMPLE" not in caplog.text - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(logged) - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(view) + assert "glpat-IOSFODNN7EXAMPLE" not in caplog.text + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(logged) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(view) @pytest.mark.asyncio diff --git a/test/test_connections_warm_activation.py b/test/test_connections_warm_activation.py index 9e056e43758..7cf5985cddf 100644 --- a/test/test_connections_warm_activation.py +++ b/test/test_connections_warm_activation.py @@ -236,7 +236,7 @@ async def test_a_url_carrying_a_credential_is_refused_rather_than_stored(_stub_a [ { "serverName": "linear", - "oauthUrl": "https://linear.example/authorize?state=AKIA" + "IOSFODNN7EXAMPLE1", + "oauthUrl": "https://linear.example/authorize?state=glpat-" + "IOSFODNN7EXAMPLE1", } ], ) diff --git a/test/test_core_path_redact_before_bound.py b/test/test_core_path_redact_before_bound.py index 880a0623480..acfdeef11d2 100644 --- a/test/test_core_path_redact_before_bound.py +++ b/test/test_core_path_redact_before_bound.py @@ -34,8 +34,8 @@ _REPO_ROOT = Path(__file__).resolve().parents[1] -# A fake AWS access key id: matches (?:AKIA|ASIA)[A-Z0-9]{16}, asserted absent. -_TOKEN = "AKIA" + "STRADDLE0123456A" +# A fake GitLab-shaped token: matches glpat-[A-Za-z0-9_-]{16,}, asserted absent. +_TOKEN = "glpat-" + "STRADDLE0123456A" class TestTelegramOptionLabelStraddle: diff --git a/test/test_cpp_wiring_enterprise_wave2.py b/test/test_cpp_wiring_enterprise_wave2.py index fa737731f62..a77bc87e548 100644 --- a/test/test_cpp_wiring_enterprise_wave2.py +++ b/test/test_cpp_wiring_enterprise_wave2.py @@ -317,8 +317,8 @@ def test_context_redact_runs_enterprise_policy(enterprise_ctx) -> None: assert "[REDACTED-SSO]" in mcp_core.redact("token=SSO-COOKIE") assert "[REDACTED-SSO]" in agent.redact("token=SSO-COOKIE") # Baseline credential redaction is preserved (delegated to security.redact). - out = mcp_core.redact("AKIAIOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in out + out = mcp_core.redact("glpat-IOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in out # ── telemetry (point 5) ── diff --git a/test/test_crew_log_emit_continuity.py b/test/test_crew_log_emit_continuity.py index 4a3133a166f..5d2426d4c16 100644 --- a/test/test_crew_log_emit_continuity.py +++ b/test/test_crew_log_emit_continuity.py @@ -204,10 +204,10 @@ def test_a_credential_in_the_task_text_never_reaches_the_log(): _open_session() emit.on_turn_started(SESSION, 1, "user") emit.on_subagent_spawned( - SESSION, 1, agent_id="sub-1", task="deploy with AKIAIOSFODNN7EXAMPLE now" + SESSION, 1, agent_id="sub-1", task="deploy with glpat-IOSFODNN7EXAMPLE now" ) assert emit.flush() - assert "AKIAIOSFODNN7EXAMPLE" not in _opener("subagent/spawned")["task"] + assert "glpat-IOSFODNN7EXAMPLE" not in _opener("subagent/spawned")["task"] def test_a_completed_child_records_the_credits_it_billed(): diff --git a/test/test_crew_routing_and_delegation.py b/test/test_crew_routing_and_delegation.py index 2039cdf5c2a..8346da97ba0 100644 --- a/test/test_crew_routing_and_delegation.py +++ b/test/test_crew_routing_and_delegation.py @@ -201,7 +201,7 @@ def test_memory_refusal_redacts_before_bounding_and_does_not_record_a_binding( from kiro_crew import mcp_core from kiro_crew.memory_stores import UnknownMemoryStore - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" reason = f"private memory unavailable: /home/alice/private/memory.db {secret} " + "x" * 1200 monkeypatch.setattr( mcp_core, "resolve_agent_bindings", Mock(side_effect=UnknownMemoryStore(reason)) diff --git a/test/test_crew_teams.py b/test/test_crew_teams.py index 58f5e721115..e219e5eac10 100644 --- a/test/test_crew_teams.py +++ b/test/test_crew_teams.py @@ -1002,7 +1002,7 @@ async def test_registry_view_admits_roster_names_and_refuses_unsafe_ones(self): failing the display-name rule) is ``unknown_member`` on every write.""" from kiro_crew.config.loader import KiroCrewConfig - eggbot, hidden = "dr. eggbot", "AKIAIOSFODNN7EXAMPLE" + eggbot, hidden = "dr. eggbot", "glpat-IOSFODNN7EXAMPLE" cfg = KiroCrewConfig() cfg.agents = { name: KiroCrewAgentConfig(kiro_agent="kirocrew") for name in (eggbot, hidden, RADAR) diff --git a/test/test_crew_turn_proxy_reply.py b/test/test_crew_turn_proxy_reply.py index 0844c01ff71..7152b2c115e 100644 --- a/test/test_crew_turn_proxy_reply.py +++ b/test/test_crew_turn_proxy_reply.py @@ -36,7 +36,7 @@ class TestTheCrewsReplyIsRedactedBeforeItReachesTheCaller: in a transcript, so it is redacted on the way out like every other peer reply. """ - _KEY = "AKIAIOSFODNN7EXAMPLE" + _KEY = "glpat-IOSFODNN7EXAMPLE" @pytest.mark.asyncio async def test_a_non_streamed_reply_is_redacted(self, monkeypatch): @@ -134,7 +134,7 @@ async def test_a_leading_bom_does_not_hide_an_escaped_credential(self, monkeypat _wire_handler(monkeypatch, status=_connected()) _capture_stream(monkeypatch) # The literal bytes never spell the key id: only a JSON decode produces it. - escaped = b"\\u0041" + self._KEY[1:].encode() + escaped = ("\\u%04x" % ord(self._KEY[0])).encode() + self._KEY[1:].encode() event = b"\xef\xbb\xbf" + b'data: {"delta": "key ' + escaped + b'"}\n\n' _install_session(monkeypatch, [], resp=_FakeResp(status=200, chunks=(event,))) resp = await mod.api_crew_turn(_turn_request({"message": "hi", "thread": "t"})) @@ -162,7 +162,7 @@ async def test_a_bom_split_across_chunks_is_still_stripped(self, monkeypatch): _wire_handler(monkeypatch, status=_connected()) _capture_stream(monkeypatch) - escaped = b"\\u0041" + self._KEY[1:].encode() + escaped = ("\\u%04x" % ord(self._KEY[0])).encode() + self._KEY[1:].encode() stream = b"\xef\xbb\xbf" + b'data: {"delta": "key ' + escaped + b'"}\n\n' _install_session( monkeypatch, @@ -370,7 +370,7 @@ class TestTheCrewsRefusalIsRedactedBeforeItIsCut: redacted whole, and only then cut. """ - _KEY = "AKIAIOSFODNN7EXAMPLE" + _KEY = "glpat-IOSFODNN7EXAMPLE" @staticmethod def _detail(out): @@ -409,7 +409,9 @@ async def test_a_credential_written_as_a_json_escape_is_redacted(self, monkeypat _wire_handler(monkeypatch, status=_connected()) _capture_stream(monkeypatch) # The literal bytes never spell the key id: only a JSON decode produces it. - escaped = '{"detail": "refused for \\u0041' + self._KEY[1:] + '"}' + escaped = ( + '{"detail": "refused for ' + ("\\u%04x" % ord(self._KEY[0])) + self._KEY[1:] + '"}' + ) assert self._KEY not in escaped _install_session(monkeypatch, [], resp=_FakeResp(status=403, text=escaped)) out = await mod.api_crew_turn(_turn_request({"message": "hi", "thread": "t"})) @@ -459,7 +461,7 @@ class TestANonStreamedCrewErrorIsARefusalNotAContentTypeComplaint: capped, redacted slice the streamed frame carries. """ - _KEY = "AKIAIOSFODNN7EXAMPLE" + _KEY = "glpat-IOSFODNN7EXAMPLE" @staticmethod def _payload(resp): diff --git a/test/test_cron_channel_delivery.py b/test/test_cron_channel_delivery.py index e0339342b72..2b1aac2a262 100644 --- a/test/test_cron_channel_delivery.py +++ b/test/test_cron_channel_delivery.py @@ -46,7 +46,7 @@ DISCORD_CONVERSATION = "C_DISCORD" #: A credential shaped exactly like the one the redactors exist to catch. -LEAKED_KEY = "AKIAIOSFODNN7EXAMPLE" +LEAKED_KEY = "glpat-IOSFODNN7EXAMPLE" # ─── Doubles ───────────────────────────────────────────────────────────── @@ -877,12 +877,12 @@ class TestChannelEgressMeetsTheDisplayFloor: Cron results, run-failure alerts, crash alerts and subagent completions all land here, and NONE of them passes a renderer -- a renderer is where a turn gets the display-form floor. So a literal-only scan at this chokepoint is a - gap every one of those callers inherits: neither `AKIA****` nor - `[AKIA](https://x)` matches a credential pattern as written, and the + gap every one of those callers inherits: neither `glpat-****` nor + `[glpat-](https://x)` matches a credential pattern as written, and the client renders the markup away and shows the reader an intact key. """ - _COLLAPSING = "AKIA**IOSFODNN7EXAMPLE**" + _COLLAPSING = "glpat-**IOSFODNN7EXAMPLE**" @pytest.mark.asyncio async def test_a_markdown_collapse_credential_never_reaches_the_transport(self): @@ -896,7 +896,7 @@ async def test_a_markdown_collapse_credential_never_reaches_the_transport(self): ) body = _sent(tr) assert body - assert "AKIAIOSFODNN7EXAMPLE" not in body.replace("*", "") + assert "glpat-IOSFODNN7EXAMPLE" not in body.replace("*", "") assert self._COLLAPSING not in body @pytest.mark.asyncio diff --git a/test/test_cron_script.py b/test/test_cron_script.py index 1328a3f011c..87473c46253 100644 --- a/test/test_cron_script.py +++ b/test/test_cron_script.py @@ -217,12 +217,12 @@ def test_nonzero_exit_redacts_stderr_before_truncating(self): longer matches and the raw tail reaches the cron result. """ # Built at runtime so no credential-shaped literal lands in the repo. - fake_key = "AKIA" + "B" * 16 # matches the AWS access-key-id pattern + fake_key = "xoxb-" + "B" * 15 # matches the Slack token pattern # Sized so the 1000-char tail window starts 2 chars into the credential: # a slice-then-redact order keeps "IA" + all 16 B's but drops the # "AK" prefix, so the pattern does not match and the tail leaks. padding = "p" * 100 - trailing = "e" * 982 + trailing = "." * 982 # the token body cannot absorb a "." stderr_text = padding + fake_key + trailing assert len(stderr_text) - 1000 == len(padding) + 2 mock_proc = MagicMock() @@ -231,12 +231,12 @@ def test_nonzero_exit_redacts_stderr_before_truncating(self): with patch("subprocess.Popen", return_value=mock_proc): result = run_command_sandboxed("boom") assert result["status"] == "error" - assert "B" * 16 not in result["output"] + assert "B" * 15 not in result["output"] assert fake_key not in result["output"] # Positive proof the payload flowed through redaction (not a vacuous # pass on an empty result): the marker's tail survives the tail slice. assert "credential]" in result["output"] - assert "e" * 50 in result["output"] + assert "." * 50 in result["output"] def test_nonzero_exit_short_stderr_stays_whole(self): """A stderr already shorter than the 1000-char bound is kept whole.""" @@ -680,13 +680,13 @@ def test_a_credential_in_the_terminal_stderr_is_redacted(self, tmp_path): 'import sys\n' 'sys.stderr.write("W" * 900 + "\\n")\n' 'sys.stderr.flush()\n' - 'raise RuntimeError("boom AKIAIOSFODNN7EXAMPLE")\n', + 'raise RuntimeError("boom xoxb-IOSFODNN7EXAMPL")\n', ) with patch("pathlib.Path.home", return_value=tmp_path): result = run_script_sandboxed(script_path + ":run", "test-job-id") assert result["status"] == "error" - assert "AKIAIOSFODNN7EXAMPLE" not in result["error"] + assert "xoxb-IOSFODNN7EXAMPL" not in result["error"] assert "[REDACTED" in result["error"] def test_a_credential_straddling_the_bound_does_not_leak_a_fragment( @@ -709,7 +709,7 @@ def test_a_credential_straddling_the_bound_does_not_leak_a_fragment( tmp_path, 'import os, sys\n' 'sys.stderr.write("W" * 300)\n' - 'sys.stderr.write("AKIAIOSFODNN7EXAMPLE")\n' + 'sys.stderr.write("xoxb-IOSFODNN7EXAMPL")\n' 'sys.stderr.write("X" * 481)\n' 'sys.stderr.flush()\n' 'os._exit(2)\n', @@ -718,7 +718,7 @@ def test_a_credential_straddling_the_bound_does_not_leak_a_fragment( result = run_script_sandboxed(script_path + ":run", "test-job-id") assert result["status"] == "error" - assert "AKIAIOSFODNN7EXAMPLE" not in result["error"] + assert "xoxb-IOSFODNN7EXAMPL" not in result["error"] # The discriminator: the exact fragment the slice-then-redact order # leaves behind. Absent under redact-then-slice; present under the bug. assert "KIAIOSFODNN7EXAMPLE" not in result["error"] @@ -1368,18 +1368,18 @@ def test_rpc_disconnect_empty_stderr(self, tmp_path): def test_stderr_tail_redacts_credentials(self, tmp_path): from kiro_crew.cron_script import McpToolClient stderr_path = tmp_path / "stderr.log" - stderr_path.write_text("boom AKIA1234567890123456 failure") + stderr_path.write_text("boom xoxb-123456789012345 failure") client = object.__new__(McpToolClient) client._stderr_file = SimpleNamespace(name=str(stderr_path)) tail = client._stderr_tail() - assert "AKIA1234567890123456" not in tail + assert "xoxb-123456789012345" not in tail assert "boom" in tail def test_stderr_tail_redacts_exfiltration_urls(self, tmp_path): from kiro_crew.cron_script import McpToolClient stderr_path = tmp_path / "stderr.log" # Long innocuous query (>= 200 chars) triggers redact_exfiltration_urls' - # length-based heuristic. We can't use a credential-shaped value (AKIA, + # length-based heuristic. We can't use a credential-shaped value (xoxb-, # base64 blob) because redact_credentials runs first and would replace # it before the URL redactor sees it, leaving a short benign query. long_query = "data=" + ("a" * 250) @@ -1443,7 +1443,7 @@ def test_notify_redacts_credentials(self): with patch( "kiro_crew.cron_script.loopback_urlopen", return_value=mock_response ) as mock_urlopen: - ctx.notify("secret AKIA1234567890123456 text") + ctx.notify("secret xoxb-123456789012345 text") # Verify the request was made (redaction happens internally) mock_urlopen.assert_called_once() @@ -2143,12 +2143,12 @@ def test_bad_json_output_redacts_before_truncating(self, tmp_path): the raw head reaches the diagnostic. """ # Built at runtime so no credential-shaped literal lands in the repo. - fake_key = "AKIA" + "B" * 16 # matches the AWS access-key-id pattern + fake_key = "xoxb-" + "B" * 15 # matches the Slack token pattern # Sized so the 200-char head window ends 10 chars into the credential: - # a slice-then-redact order keeps "AKIA" + 6 B's — too short for the + # a slice-then-redact order keeps "xoxb-" + 6 B's — too short for the # pattern to match, so the raw head leaks into the diagnostic. padding = "p" * 190 - stdout_text = padding + fake_key + "e" * 50 + stdout_text = padding + fake_key + "." * 50 mock_proc = MagicMock() mock_proc.returncode = 0 mock_proc.communicate.return_value = (stdout_text, "") @@ -2159,7 +2159,7 @@ def test_bad_json_output_redacts_before_truncating(self, tmp_path): ): result = run_script_sandboxed("/f.py:run", "j1", "") assert result["status"] == "error" - assert "AKIA" not in result["error"] + assert "xoxb-" not in result["error"] assert fake_key not in result["error"] # Positive proof the payload flowed through redaction (not a vacuous # pass on an empty diagnostic): the 200-char head window ends 10 chars @@ -2193,14 +2193,14 @@ def _spy(text: str) -> str: return real_redact(text) monkeypatch.setattr(cron_script, "redact", _spy) - fake_key = "AKIA" + "B" * 16 # matches the AWS access-key-id pattern + fake_key = "xoxb-" + "B" * 15 # matches the Slack token pattern # The -500 cut lands ONE character into the key: slice-then-redact # would leak the 19-char fragment, and a window that failed to reach # back past the cut would leak it the same way. # Newline-separated filler: the window then starts inside an ordinary # short line, so only that line's severed remainder is masked and the # straddling credential is still exercised against the pattern pass. - stderr_text = ("n" * 100 + "\n") * 200 + "W" * 300 + fake_key + "X" * 481 + stderr_text = ("n" * 100 + "\n") * 200 + "W" * 300 + fake_key + "." * 481 mock_proc = MagicMock() mock_proc.returncode = 1 mock_proc.communicate.return_value = ("", stderr_text) @@ -2240,7 +2240,7 @@ def _spy(text: str) -> str: return real_redact(text) monkeypatch.setattr(cron_script, "redact", _spy) - fake_key = "AKIA" + "B" * 16 # matches the AWS access-key-id pattern + fake_key = "xoxb-" + "B" * 15 # matches the Slack token pattern # The 200-char head cut lands 10 chars into the key; the trailing run # pushes the capture far past the window so the bound is discriminating. stdout_text = "p" * 190 + fake_key + "e" * 30000 diff --git a/test/test_cron_script_sessions.py b/test/test_cron_script_sessions.py index 2361ba9a77a..27361b31f7f 100644 --- a/test/test_cron_script_sessions.py +++ b/test/test_cron_script_sessions.py @@ -24,7 +24,7 @@ _JOB = "nightly-dispatch" # Assembled at runtime so the source never holds a credential-shaped literal. -_FAKE_KEY = "AKIA" + "1234567890123456" +_FAKE_KEY = "glpat-" + "1234567890123456" class _Resp: diff --git a/test/test_cron_secret_env_grant_endpoint.py b/test/test_cron_secret_env_grant_endpoint.py index 41adbef6e4f..397db2d09af 100644 --- a/test/test_cron_secret_env_grant_endpoint.py +++ b/test/test_cron_secret_env_grant_endpoint.py @@ -184,7 +184,7 @@ async def test_unknown_secret_error_does_not_echo_a_credential_shaped_name(self, job = svc.add_job( "j", "args", every_secs=3600, script=spec, session_key="dashboard:conftest-slot" ) - shaped = "AKIAIOSFODNN7EXAMPLE" # credential-shaped, slug-valid, not in the vault + shaped = "glpat-IOSFODNN7EXAMPLE" # credential-shaped, slug-valid, not in the vault pin = compute_secret_env_pin( spec, "", @@ -521,10 +521,12 @@ def test_owner_view_grant_map_is_redacted(self): exfil-URL-shaped content must not reach the dashboard raw.""" from kiro_crew.dashboard.handlers.cron import _redacted_grant_map - out = _redacted_grant_map({"AWS_KEY": "https://evil.example/exfil?d=AKIAIOSFODNN7EXAMPLE"}) + out = _redacted_grant_map( + {"AWS_KEY": "https://evil.example/exfil?d=glpat-IOSFODNN7EXAMPLE"} + ) assert out is not None serialized = str(out) - assert "AKIAIOSFODNN7EXAMPLE" not in serialized + assert "glpat-IOSFODNN7EXAMPLE" not in serialized assert _redacted_grant_map({}) is None # A benign product-written mapping passes through unchanged. assert _redacted_grant_map({"MY_TOKEN": "slack-sandbox"}) == {"MY_TOKEN": "slack-sandbox"} @@ -810,7 +812,7 @@ async def test_approve_refuses_source_the_display_cannot_show_verbatim(self, cro app, svc = self._app_and_svc() SecretVault(loader_config_dir()).set_sync("slack-sandbox", "xoxb-1") - body = 'KEY = "AKIAIOSFODNN7EXAMPLE"\ndef run(ctx): pass\n' + body = 'KEY = "glpat-IOSFODNN7EXAMPLE"\ndef run(ctx): pass\n' spec = _grant_script(cron_home, body=body) job = svc.add_job( "j", diff --git a/test/test_cron_turn_stats_footer.py b/test/test_cron_turn_stats_footer.py index 20a6a45771a..ff0b999303a 100644 --- a/test/test_cron_turn_stats_footer.py +++ b/test/test_cron_turn_stats_footer.py @@ -114,7 +114,7 @@ def test_stats_drop_non_finite_numbers_and_unbounded_models() -> None: def test_stats_redact_a_credential_shaped_model() -> None: - key = "AKIA" + "ABCDEFGHIJKLMNOP" + key = "glpat-" + "ABCDEFGHIJKLMNOP" stats = turn_stats_meta(10, 0.0, 0.0, key) assert stats is not None assert key not in stats.get("model", "") diff --git a/test/test_cross_surface_mirror.py b/test/test_cross_surface_mirror.py index b643a55eb91..21222bf4bba 100644 --- a/test/test_cross_surface_mirror.py +++ b/test/test_cross_surface_mirror.py @@ -270,7 +270,7 @@ async def test_applies_redaction_pipeline(self, tmp_path): state.sessions.get_mirror_link = MagicMock( return_value=ChannelLink("telegram", channel_id="123") ) - raw = "see https://evil.example/exfil?q=1 and AKIAIOSFODNN7EXAMPLE" + raw = "see https://evil.example/exfil?q=1 and glpat-IOSFODNN7EXAMPLE" expected = redact_credentials(redact_exfiltration_urls(raw)[0])[0] await _deliver_cross_surface_reply(state, "k", raw) assert tp.send_message.await_args.args[1] == expected @@ -279,7 +279,7 @@ async def test_applies_redaction_pipeline(self, tmp_path): async def test_a_markdown_split_credential_is_redacted_in_display_form(self, tmp_path): """This leg passes no RENDERER, and a renderer is where a turn gets that floor. - ``AKIA**IOSF**ODNN7EXAMPLE`` survives a byte-for-byte scan and the client + ``glpat-**IOSF**ODNN7EXAMPLE`` survives a byte-for-byte scan and the client reassembles it whole once it renders the emphasis away, so the mirror has to scan the DISPLAYED form — the same argument, and the same context-aware redactor, as the Slack chokepoint already applies. @@ -291,10 +291,10 @@ async def test_a_markdown_split_credential_is_redacted_in_display_form(self, tmp return_value=ChannelLink("telegram", channel_id="123") ) - await _deliver_cross_surface_reply(state, "k", "token AKIA**IOSF**ODNN7EXAMPLE ok") + await _deliver_cross_surface_reply(state, "k", "token glpat-**IOSF**ODNN7EXAMPLE ok") sent = tp.send_message.await_args.args[1] - assert "AKIAIOSFODNN7EXAMPLE" not in sent.replace("*", "") + assert "glpat-IOSFODNN7EXAMPLE" not in sent.replace("*", "") @pytest.mark.asyncio async def test_send_failure_is_swallowed(self, tmp_path): @@ -450,7 +450,7 @@ async def test_truncates_and_redacts(self, tmp_path): state.sessions.get_mirror_link = MagicMock( return_value=ChannelLink("telegram", channel_id="123") ) - raw = "tok AKIAIOSFODNN7EXAMPLE " + "x" * 800 + raw = "tok glpat-IOSFODNN7EXAMPLE " + "x" * 800 await _deliver_cross_surface_user_message(state, "k", raw) sent = tp.send_message.await_args.args[1] # _prepare_mirror_msg redacts over the FULL text (redact_via_context) diff --git a/test/test_dashboard.py b/test/test_dashboard.py index 6aece345bb2..c18ccd7bdea 100644 --- a/test/test_dashboard.py +++ b/test/test_dashboard.py @@ -72,7 +72,7 @@ def test_load_redacts_preexisting_rows(self, monkeypatch, tmp_path) -> None: """Rows persisted before delivery-time redaction are redacted at load.""" monkeypatch.setattr("kiro_crew.dashboard.state.config_dir", lambda: tmp_path) path = tmp_path / "notifications.jsonl" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" row = { "kind": "cron", "title": "Job", @@ -176,9 +176,9 @@ def test_bus_sink_is_redacting_deliver_note(self, monkeypatch, tmp_path) -> None start_time=0.0, ) note = state.notification_bus.push( - payload_from_legacy("cron", "key AKIAIOSFODNN7EXAMPLE via bus", "b") + payload_from_legacy("cron", "key glpat-IOSFODNN7EXAMPLE via bus", "b") ) - assert "AKIAIOSFODNN7EXAMPLE" not in note["title"] + assert "glpat-IOSFODNN7EXAMPLE" not in note["title"] def test_deliver_note_redacts_nested_strings(self, monkeypatch, tmp_path) -> None: """Redaction descends into nested structures like action labels. @@ -198,26 +198,26 @@ def test_deliver_note_redacts_nested_strings(self, monkeypatch, tmp_path) -> Non { "ts": "2026-07-12T00:00:00Z", "kind": "cron", - "title": "key AKIAIOSFODNN7EXAMPLE in title", + "title": "key glpat-IOSFODNN7EXAMPLE in title", "body": "b", "actions": [ - {"id": "a1", "label": "key AKIAIOSFODNN7EXAMPLE in label"}, + {"id": "a1", "label": "key glpat-IOSFODNN7EXAMPLE in label"}, ], - "extra": {"nested": ["key AKIAIOSFODNN7EXAMPLE in list"]}, + "extra": {"nested": ["key glpat-IOSFODNN7EXAMPLE in list"]}, } ) note = state._notification_log[0] # Top-level strings still redacted - assert "AKIAIOSFODNN7EXAMPLE" not in note["title"] + assert "glpat-IOSFODNN7EXAMPLE" not in note["title"] # Nested strings inside lists of dicts redacted - assert "AKIAIOSFODNN7EXAMPLE" not in note["actions"][0]["label"] + assert "glpat-IOSFODNN7EXAMPLE" not in note["actions"][0]["label"] assert note["actions"][0]["id"] == "a1" # Arbitrary nesting (dict -> list) redacted - assert "AKIAIOSFODNN7EXAMPLE" not in note["extra"]["nested"][0] + assert "glpat-IOSFODNN7EXAMPLE" not in note["extra"]["nested"][0] # Persisted JSONL is clean too loaded = _load_notifications() - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(loaded[0]) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(loaded[0]) def test_state_loads_existing_on_init(self, monkeypatch, tmp_path) -> None: """DashboardState.__init__ loads existing notifications from disk.""" diff --git a/test/test_dashboard_approval.py b/test/test_dashboard_approval.py index 94efe1f899c..8db0f39be62 100644 --- a/test/test_dashboard_approval.py +++ b/test/test_dashboard_approval.py @@ -729,7 +729,7 @@ async def test_blocked_row_and_audit_redact_the_model_authored_title(self, tmp_p # internal-content-scan and Semgrep's # `detected-aws-access-key-id-value`. Splitting satisfies both, and # matches the existing sentinels in code_review_sage's tests. - secret = "AKIA" + "1234567890ABCDEF" + secret = "glpat-" + "1234567890ABCDEF" state, client = _make_state( tmp_path, context_builder=_context_builder(), @@ -861,7 +861,7 @@ class TestDenyRowTitleRedaction: # Assembled at runtime, never as one literal: the redactor only fires on # credential-SHAPED input, and a real key shape in the source trips the # source-text scanners (internal-content-scan, Semgrep). - _SECRET = "AKIA" + "1234567890ABCDEF" + _SECRET = "glpat-" + "1234567890ABCDEF" def _invalid_title(self) -> str: # Over MAX_TOOL_NAME_LEN with is_shell False, so _validate_tool_name diff --git a/test/test_dashboard_chat.py b/test/test_dashboard_chat.py index cfb0042ebdf..d07edfcb814 100644 --- a/test/test_dashboard_chat.py +++ b/test/test_dashboard_chat.py @@ -75,7 +75,7 @@ async def test_partial_assistant_text_redacted(self, tmp_path: Path) -> None: async def _stream_then_die(msg): yield LLMEvent( - kind=EVENT_TEXT_CHUNK, text="partial output with AKIA1234567890ABCDEF secret" + kind=EVENT_TEXT_CHUNK, text="partial output with glpat-1234567890ABCDEF secret" ) raise AcpProcessDied("pipe broken") @@ -92,7 +92,7 @@ async def _stream_then_die(msg): assistant_msgs = [m for m in slot.messages if m.get("role") == "assistant"] assert assistant_msgs, "Expected at least one assistant message with redacted content" for m in assistant_msgs: - assert "AKIA1234567890ABCDEF" not in m.get("content", "") + assert "glpat-1234567890ABCDEF" not in m.get("content", "") assert slot._queue == [ { "id": slot._queue[0]["id"], @@ -115,7 +115,7 @@ async def test_cancelled_error_redacts_partial_text(self, tmp_path: Path) -> Non state, slot, client, _run_chat = self._make_state_and_slot(tmp_path) async def _stream_then_cancel(msg): - yield LLMEvent(kind=EVENT_TEXT_CHUNK, text="partial with AKIA1234567890ABCDEF key") + yield LLMEvent(kind=EVENT_TEXT_CHUNK, text="partial with glpat-1234567890ABCDEF key") raise asyncio.CancelledError() client.stream = _stream_then_cancel @@ -126,7 +126,7 @@ async def _stream_then_cancel(msg): assistant_msgs = [m for m in slot.messages if m.get("role") == "assistant"] assert assistant_msgs, "Expected at least one assistant message with redacted content" for m in assistant_msgs: - assert "AKIA1234567890ABCDEF" not in m.get("content", "") + assert "glpat-1234567890ABCDEF" not in m.get("content", "") # ── Transient backend 5xx retry on the interactive chat path ── diff --git a/test/test_dashboard_chat_compaction.py b/test/test_dashboard_chat_compaction.py index 897e1dd61cd..6781d325281 100644 --- a/test/test_dashboard_chat_compaction.py +++ b/test/test_dashboard_chat_compaction.py @@ -551,10 +551,10 @@ async def test_failed_compaction_reason_is_redacted(self, tmp_path, monkeypatch) the provider's text as untrusted. """ slot = await self._run_failed_compaction( - tmp_path, monkeypatch, "auth failed for AKIAIOSFODNN7EXAMPLE key" + tmp_path, monkeypatch, "auth failed for glpat-IOSFODNN7EXAMPLE key" ) notice = self._compaction_notice(slot) - assert "AKIAIOSFODNN7EXAMPLE" not in notice + assert "glpat-IOSFODNN7EXAMPLE" not in notice assert "Compaction failed:" in notice @pytest.mark.asyncio diff --git a/test/test_dashboard_chat_fork.py b/test/test_dashboard_chat_fork.py index 2df0b77c9e2..262ce35eb95 100644 --- a/test/test_dashboard_chat_fork.py +++ b/test/test_dashboard_chat_fork.py @@ -507,7 +507,7 @@ async def test_fork_redacts_credentials_in_assistant_messages(self, tmp_path): state = _make_state(tmp_path) slot = state.get_or_create_slot("src") slot.append("user", "show me the key", "msg msg-u") - slot.append("assistant", "Here: AKIAIOSFODNN7EXAMPLE", "msg msg-a") + slot.append("assistant", "Here: glpat-IOSFODNN7EXAMPLE", "msg msg-a") slot.drain() app = _make_app(state) @@ -518,7 +518,7 @@ async def test_fork_redacts_credentials_in_assistant_messages(self, tmp_path): new_slot = state._slots.get(data["key"]) assistant_msgs = [m for m in new_slot.messages if m["role"] == "assistant"] - assert "AKIAIOSFODNN7EXAMPLE" not in assistant_msgs[0]["content"] + assert "glpat-IOSFODNN7EXAMPLE" not in assistant_msgs[0]["content"] assert "[REDACTED" in assistant_msgs[0]["content"] @pytest.mark.asyncio @@ -529,7 +529,7 @@ async def test_fork_redacts_credentials_in_llm_generated_title(self, tmp_path): """ state = _make_state(tmp_path) slot = state.get_or_create_slot("src") - slot.title = "Leaked AKIAIOSFODNN7EXAMPLE key" + slot.title = "Leaked glpat-IOSFODNN7EXAMPLE key" slot._titled = True slot.append("user", "hi", "msg msg-u") slot.append("assistant", "ok", "msg msg-a") @@ -540,11 +540,11 @@ async def test_fork_redacts_credentials_in_llm_generated_title(self, tmp_path): resp = await client.post("/api/chat/slots/src/fork", json={}) data = await resp.json() - assert "AKIAIOSFODNN7EXAMPLE" not in data["title"] + assert "glpat-IOSFODNN7EXAMPLE" not in data["title"] assert "[REDACTED" in data["title"] assert data["title"].startswith("↳ Fork of ") new_slot = state._slots.get(data["key"]) - assert "AKIAIOSFODNN7EXAMPLE" not in new_slot.title + assert "glpat-IOSFODNN7EXAMPLE" not in new_slot.title @pytest.mark.asyncio async def test_fork_rejects_bool_index(self, tmp_path): diff --git a/test/test_dashboard_chat_pagination_suffix.py b/test/test_dashboard_chat_pagination_suffix.py index 76951cfb3be..7b6c900afeb 100644 --- a/test/test_dashboard_chat_pagination_suffix.py +++ b/test/test_dashboard_chat_pagination_suffix.py @@ -105,7 +105,7 @@ async def test_save_redacted_row_does_not_duplicate_the_persisted_suffix( redact_exfiltration_urls, ) - secret = "key AKIAIOSFODNN7EXAMPLE here" + secret = "key glpat-IOSFODNN7EXAMPLE here" redacted, _ = redact_exfiltration_urls(secret) redacted, _ = redact_credentials(redacted) assert redacted != secret, "fixture needs content the real redactor changes" @@ -191,7 +191,7 @@ def red(text: str) -> str: # Two different credential KINDS rather than two near-identical keys: an # access-key id and a labelled secret-key assignment redact to the same tag, # so no second key-shaped literal is needed to make the bodies collide. - mine = "key AKIAIOSFODNN7EXAMPLE here" + mine = "key glpat-IOSFODNN7EXAMPLE here" theirs = "key aws_secret_access_key=x here" assert mine != theirs, "fixture needs two DISTINCT bodies" assert ( diff --git a/test/test_dashboard_chat_pins.py b/test/test_dashboard_chat_pins.py index 42039a04e12..41f2147e07c 100644 --- a/test/test_dashboard_chat_pins.py +++ b/test/test_dashboard_chat_pins.py @@ -541,7 +541,7 @@ async def test_delete_by_id_persist_failure_returns_500_and_rolls_back(tmp_path, @pytest.mark.asyncio async def test_create_pin_redacts_credentials_in_preview(tmp_path): """A preview containing a credential is redacted before storage and listing.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async with _client(tmp_path) as client: state: DashboardState = client.app["state"] resp = await client.post( @@ -569,7 +569,7 @@ async def test_create_pin_redacts_credentials_in_preview(tmp_path): async def test_create_pin_redacts_credential_straddling_truncation_boundary(tmp_path): """A credential straddling the 200-char truncation boundary must not survive as an unrecognized fragment: redaction runs BEFORE truncation.""" - secret = "AKIAIOSFODNN7EXAMPLE" # 20 chars + secret = "glpat-IOSFODNN7EXAMPLE" # 22 chars preview = "x" * 181 + secret + " trailing text beyond the cap" async with _client(tmp_path) as client: state: DashboardState = client.app["state"] @@ -655,7 +655,7 @@ async def _patched_read(request, max_bytes=65536): async def test_list_re_redacts_stale_unredacted_previews_from_disk(tmp_path): """A pre-existing pin with an unredacted credential in chat_pins.json is redacted at the list output boundary (stored text is never trusted).""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async with _client(tmp_path) as client: state: DashboardState = client.app["state"] # Simulate a stale on-disk record that predates redaction @@ -681,7 +681,7 @@ async def test_duplicate_create_re_redacts_stale_unredacted_preview(tmp_path): """A duplicate POST for an already-pinned message takes the idempotent `existing` branch -- that response path must re-redact too, or a stale unredacted credential on disk is returned verbatim.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async with _client(tmp_path) as client: state: DashboardState = client.app["state"] # Simulate a stale on-disk record that predates redaction diff --git a/test/test_dashboard_chat_prompt_prep.py b/test/test_dashboard_chat_prompt_prep.py index 0383163c20c..b97a13b20f7 100644 --- a/test/test_dashboard_chat_prompt_prep.py +++ b/test/test_dashboard_chat_prompt_prep.py @@ -388,7 +388,7 @@ def test_incidental_dollar_not_audited(self, tmp_path, monkeypatch): def test_credentials_redacted_in_loaded_body(self, tmp_path, monkeypatch): from kiro_crew.dashboard.chat_runner import _expand_dollar_skills - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" state = self._state_with_skills( tmp_path, monkeypatch, diff --git a/test/test_dashboard_chat_regenerate.py b/test/test_dashboard_chat_regenerate.py index 0eb7e57cd22..02729bff7e9 100644 --- a/test/test_dashboard_chat_regenerate.py +++ b/test/test_dashboard_chat_regenerate.py @@ -247,7 +247,7 @@ async def test_save_slot_redacts_variants(self, tmp_path, monkeypatch): slot.append("assistant", "safe content") # Plant a fake credential inside a variant slot.messages[-1]["variants"] = [ - {"content": "AKIAIOSFODNN7EXAMPLE secret stuff", "ts": "t1"}, + {"content": "glpat-IOSFODNN7EXAMPLE secret stuff", "ts": "t1"}, {"content": "safe content", "ts": "t2"}, ] slot.messages[-1]["variant_idx"] = 1 @@ -259,9 +259,9 @@ async def test_save_slot_redacts_variants(self, tmp_path, monkeypatch): persisted = state.conversation_log.read_messages(key) ai = [m for m in persisted if m.get("role") == "assistant"][0] assert "variants" in ai - # The AKIA key must not appear in either variant after redaction + # The glpat- key must not appear in either variant after redaction for v in ai["variants"]: - assert "AKIAIOSFODNN7EXAMPLE" not in v.get("content", "") + assert "glpat-IOSFODNN7EXAMPLE" not in v.get("content", "") @pytest.mark.asyncio async def test_switch_variant_rejects_when_running(self, tmp_path, monkeypatch): @@ -503,7 +503,7 @@ async def test_prepare_messages_redacts_variant_content(self, tmp_path, monkeypa slot.append("user", "hi") slot.append("assistant", "safe") slot.messages[-1]["variants"] = [ - {"content": "AKIAIOSFODNN7EXAMPLE leaked key", "ts": "t1"}, + {"content": "glpat-IOSFODNN7EXAMPLE leaked key", "ts": "t1"}, {"content": "safe", "ts": "t2"}, ] from kiro_crew.dashboard.chat import _prepare_messages @@ -511,7 +511,7 @@ async def test_prepare_messages_redacts_variant_content(self, tmp_path, monkeypa prepared = _prepare_messages(slot.messages, False, live_child="") ai = [m for m in prepared if m.get("role") == "assistant"][0] for v in ai["variants"]: - assert "AKIAIOSFODNN7EXAMPLE" not in v.get("content", "") + assert "glpat-IOSFODNN7EXAMPLE" not in v.get("content", "") @pytest.mark.asyncio async def test_switch_variant_corrupt_entry(self, tmp_path, monkeypatch): diff --git a/test/test_dashboard_chat_segments.py b/test/test_dashboard_chat_segments.py index 8118d5f211e..7736f98660f 100644 --- a/test/test_dashboard_chat_segments.py +++ b/test/test_dashboard_chat_segments.py @@ -135,7 +135,7 @@ async def _fake_register(text, message_ts, session_key): from kiro_crew.dashboard.chat import _flush_segment - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async def _run(): _flush_segment(state, slot, f'key={secret}') @@ -228,9 +228,9 @@ async def test_credential_split_across_chunks_never_streamed_raw(self, tmp_path, """ from kiro_crew.providers.base import EVENT_COMPLETE, EVENT_TEXT_CHUNK, LLMEvent - # AKIAIOSFODNN7EXAMPLE split exactly as in the pentest reproduction. + # glpat-IOSFODNN7EXAMPLE split exactly as in the pentest reproduction. events = [ - LLMEvent(kind=EVENT_TEXT_CHUNK, text="The access key is AKIA"), + LLMEvent(kind=EVENT_TEXT_CHUNK, text="The access key is glpat-"), LLMEvent(kind=EVENT_TEXT_CHUNK, text="IOSFODNN7"), LLMEvent(kind=EVENT_TEXT_CHUNK, text="EXAMPLE"), LLMEvent(kind=EVENT_COMPLETE), @@ -252,10 +252,10 @@ async def test_credential_split_across_chunks_never_streamed_raw(self, tmp_path, wire = "".join(contents) # No individual frame — and not the reassembled wire — leaks the key. for frame in contents: - assert "AKIAIOSFODNN7EXAMPLE" not in frame - assert "AKIAIOSFODNN7EXAMPLE" not in wire + assert "glpat-IOSFODNN7EXAMPLE" not in frame + assert "glpat-IOSFODNN7EXAMPLE" not in wire # The credential fragments must not be recoverable across frames. - assert "AKIA" not in wire.replace("[REDACTED: credential]", "") + assert "glpat-" not in wire.replace("[REDACTED: credential]", "") assert "[REDACTED: credential]" in wire assert wire == "The access key is [REDACTED: credential]" @@ -273,7 +273,7 @@ async def test_credential_split_across_thinking_chunks_not_streamed_raw( ) events = [ - LLMEvent(kind=EVENT_THINKING_CHUNK, text="the key looks like AKIA"), + LLMEvent(kind=EVENT_THINKING_CHUNK, text="the key looks like glpat-"), LLMEvent(kind=EVENT_THINKING_CHUNK, text="IOSFODNN7"), LLMEvent(kind=EVENT_THINKING_CHUNK, text="EXAMPLE"), LLMEvent(kind=EVENT_TEXT_CHUNK, text="done"), @@ -295,9 +295,9 @@ async def test_credential_split_across_thinking_chunks_not_streamed_raw( ] wire = "".join(thinking) for frame in thinking: - assert "AKIAIOSFODNN7EXAMPLE" not in frame - assert "AKIAIOSFODNN7EXAMPLE" not in wire - assert "AKIA" not in wire.replace("[REDACTED: credential]", "") + assert "glpat-IOSFODNN7EXAMPLE" not in frame + assert "glpat-IOSFODNN7EXAMPLE" not in wire + assert "glpat-" not in wire.replace("[REDACTED: credential]", "") assert "[REDACTED: credential]" in wire @pytest.mark.asyncio diff --git a/test/test_dashboard_chat_tool_calls.py b/test/test_dashboard_chat_tool_calls.py index ad4fd1e6371..3a5c028c2f0 100644 --- a/test/test_dashboard_chat_tool_calls.py +++ b/test/test_dashboard_chat_tool_calls.py @@ -677,7 +677,7 @@ async def test_refinement_redacts_credentials_in_input(self, tmp_path, monkeypat kind=EVENT_TOOL_CALL_UPDATE, title="echo secret", tool_kind="execute", - tool_input='{"command":"echo AKIAIOSFODNN7EXAMPLE"}', + tool_input='{"command":"echo glpat-IOSFODNN7EXAMPLE"}', tool_call_id="tc-cred", ), LLMEvent(kind=EVENT_COMPLETE), @@ -691,10 +691,10 @@ async def test_refinement_redacts_credentials_in_input(self, tmp_path, monkeypat tool_msgs = [m for m in slot.messages if m.get("role") == "tool"] # Credential must not appear in the persisted meta. - assert "AKIAIOSFODNN7EXAMPLE" not in tool_msgs[0]["meta"].get("input", "") + assert "glpat-IOSFODNN7EXAMPLE" not in tool_msgs[0]["meta"].get("input", "") # Or in any of the broadcast payloads. for call in state.broadcast_ws.call_args_list: - assert "AKIAIOSFODNN7EXAMPLE" not in str(call.args[1]) + assert "glpat-IOSFODNN7EXAMPLE" not in str(call.args[1]) @pytest.mark.asyncio async def test_refinement_handler_swallows_exceptions(self, tmp_path, monkeypatch): diff --git a/test/test_dashboard_chat_unflushed_tail.py b/test/test_dashboard_chat_unflushed_tail.py index 5829dc6dd2a..28c3b7efbce 100644 --- a/test/test_dashboard_chat_unflushed_tail.py +++ b/test/test_dashboard_chat_unflushed_tail.py @@ -218,7 +218,7 @@ def test_id_less_boundary_matches_a_row_redacted_on_load(self): from kiro_crew.dashboard.chat_handlers import _append_unflushed_tail from kiro_crew.security import redact_credentials, redact_exfiltration_urls - raw = "AKIAIOSFODNN7EXAMPLE" + raw = "glpat-IOSFODNN7EXAMPLE" loaded, _ = redact_exfiltration_urls(raw) loaded, _ = redact_credentials(loaded) assert loaded != raw, "fixture no longer exercises a real redaction" diff --git a/test/test_dashboard_cron_script_source.py b/test/test_dashboard_cron_script_source.py index 11d6eef3e3a..c7fbe8e7f88 100644 --- a/test/test_dashboard_cron_script_source.py +++ b/test/test_dashboard_cron_script_source.py @@ -233,13 +233,13 @@ async def test_credentials_redacted(self, crons_home: Path) -> None: # Scripts are LLM-writeable, so their content is agent-influenced text: # raw credential patterns must not reach the dashboard verbatim. script = crons_home / "crons" / "leaky.py" - script.write_text('KEY = "AKIAIOSFODNN7EXAMPLE"\n') + script.write_text('KEY = "glpat-IOSFODNN7EXAMPLE"\n') state = _make_state(_make_job(script=f"{script}:run")) async with TestClient(TestServer(_make_app(state))) as client: resp = await client.get("/api/crons/j1/script") assert resp.status == 200 data = await resp.json() - assert "AKIAIOSFODNN7EXAMPLE" not in data["source"] + assert "glpat-IOSFODNN7EXAMPLE" not in data["source"] # The display does not equal the raw body, so the approval flow must # treat this script as unreviewable (the operator cannot read the span). assert data["reviewable"] is False @@ -250,15 +250,15 @@ async def test_metadata_fields_redacted(self, crons_home: Path) -> None: # content, so a credential-shaped name must not ride out unredacted on # the metadata fields either. A credential pattern is a legal Python # identifier and a legal file name, so both fields are reachable. - script = crons_home / "crons" / "AKIAIOSFODNN7EXAMPLE.py" + script = crons_home / "crons" / "glpat-IOSFODNN7EXAMPLE.py" script.write_text(SCRIPT_BODY) - state = _make_state(_make_job(script=f"{script}:AKIAIOSFODNN7EXAMPLE")) + state = _make_state(_make_job(script=f"{script}:glpat-IOSFODNN7EXAMPLE")) async with TestClient(TestServer(_make_app(state))) as client: resp = await client.get("/api/crons/j1/script") assert resp.status == 200 data = await resp.json() - assert "AKIAIOSFODNN7EXAMPLE" not in data["file"] - assert "AKIAIOSFODNN7EXAMPLE" not in data["function"] + assert "glpat-IOSFODNN7EXAMPLE" not in data["file"] + assert "glpat-IOSFODNN7EXAMPLE" not in data["function"] @windows_only @pytest.mark.asyncio diff --git a/test/test_dashboard_files_coverage.py b/test/test_dashboard_files_coverage.py index 6bf3c1ccd1a..61517cf6bef 100644 --- a/test/test_dashboard_files_coverage.py +++ b/test/test_dashboard_files_coverage.py @@ -158,7 +158,7 @@ async def test_a_credential_straddling_the_read_cap_is_still_masked(self, tmp_pa A cut first severs a credential at the cap and serves its prefix as real bytes; whoever writes the file chooses the offset. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f = tmp_path / "padded.txt" f.write_bytes(("a" * (files_mod._FILE_READ_CAP - 10) + secret + "\nkeep\n").encode("utf-8")) async with TestClient(TestServer(self._client_app())) as client: @@ -187,7 +187,7 @@ def b64(raw: str) -> str: jwt = b64('{"alg":"HS256","typ":"JWT"}') + "." + b64("x" * 3000) + "." + "s" * 43 head = (jwt + "\n") * 4 cap, margin = files_mod._FILE_READ_CAP, files_mod._STREAM_HOLDBACK_JWT_MAX - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" filler = "a" * (cap + margin - 6 - len(head)) f = tmp_path / "shrink.txt" f.write_bytes((head + filler + secret + "\nkeep\n").encode("utf-8")) @@ -418,7 +418,7 @@ async def test_resolve_escaping_project_is_400(self, tmp_path, mock_sel, monkeyp @pytest.mark.asyncio async def test_credentials_in_content_are_redacted(self, tmp_path, mock_sel): f = tmp_path / "creds.txt" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f.write_text(f"aws_access_key_id={secret}\n", encoding="utf-8", newline="\n") async with TestClient(TestServer(self._client_app())) as client: resp = await client.get(f"/api/file-read?path={f}") diff --git a/test/test_dashboard_handlers_core_coverage_stt_runtime.py b/test/test_dashboard_handlers_core_coverage_stt_runtime.py index 08f59c06b80..d3ffb498755 100644 --- a/test/test_dashboard_handlers_core_coverage_stt_runtime.py +++ b/test/test_dashboard_handlers_core_coverage_stt_runtime.py @@ -831,7 +831,7 @@ async def test_transcript_is_returned_and_redacted(self, monkeypatch) -> None: a chance to screen what was said.""" monkeypatch.setattr( "kiro_crew.transcribe.transcribe_audio", - AsyncMock(return_value="the key is AKIAIOSFODNN7EXAMPLE thanks"), + AsyncMock(return_value="the key is glpat-IOSFODNN7EXAMPLE thanks"), ) field = SimpleNamespace( name="audio", @@ -841,7 +841,7 @@ async def test_transcript_is_returned_and_redacted(self, monkeypatch) -> None: resp = await core_mod.api_stt_transcribe(_multipart_req(field)) assert resp.status == 200 text = json.loads(resp.body)["text"] - assert "AKIAIOSFODNN7EXAMPLE" not in text + assert "glpat-IOSFODNN7EXAMPLE" not in text # The surrounding speech survives: redaction replaces the secret, it does # not discard the transcript the user is waiting for. assert text.startswith("the key is ") diff --git a/test/test_dashboard_save_tool.py b/test/test_dashboard_save_tool.py index b13b522d0c4..3091c0eec76 100644 --- a/test/test_dashboard_save_tool.py +++ b/test/test_dashboard_save_tool.py @@ -1218,7 +1218,7 @@ def test_the_page_is_run_over_the_read_the_tab_is_served(glue): #: Assembled at runtime, like the credential-shaped values in ``test_member_dashboard_routes``: #: a literal of this shape in the diff is a finding against the PR whatever the code #: around it is for. Do not join these back up. -_KEY = "AKIA" + "IOSFODNN7" + "EXAMPLE" +_KEY = "glpat-" + "IOSFODNN7" + "EXAMPLE" def _keyed_package() -> dict[str, Any]: diff --git a/test/test_dashboard_tools.py b/test/test_dashboard_tools.py index a8ed39e6a70..9620f47fc95 100644 --- a/test/test_dashboard_tools.py +++ b/test/test_dashboard_tools.py @@ -803,10 +803,10 @@ def test_both_halves_run_through_the_same_scrub(self) -> None: leaked = dashboard_agentic.WriteRefused( "unknown_field", "tok", - "no dashboard field 'tok'. Try AKIAIOSFODNN7EXAMPLE instead.", + "no dashboard field 'tok'. Try glpat-IOSFODNN7EXAMPLE instead.", ) - assert "AKIAIOSFODNN7EXAMPLE" not in dashboard_agentic.refusal_sentence(leaked) - assert "AKIAIOSFODNN7EXAMPLE" not in dashboard_agentic.refusal_entry(leaked)["reason"] + assert "glpat-IOSFODNN7EXAMPLE" not in dashboard_agentic.refusal_sentence(leaked) + assert "glpat-IOSFODNN7EXAMPLE" not in dashboard_agentic.refusal_entry(leaked)["reason"] # ------------------------------------------- the discard happens under the lock @@ -871,7 +871,7 @@ def _two_colliding_keys() -> dict[str, str]: Assembled at runtime, like every other credential in this suite: the internal-content scan reads this change's own diff. Do not join them up. """ - head = "AKIA" + "IOSFODNN7" + head = "glpat-" + "IOSFODNN7" return {f"{head}EXAMPLE": "first row", f"{head}SAMPLE2": "second row"} def test_both_values_survive_a_key_collision(self) -> None: @@ -888,7 +888,7 @@ def test_the_second_key_takes_a_numbered_suffix(self) -> None: assert len(suffixed) == 1, f"no suffixed key: {sorted(out)}" def test_a_third_collision_keeps_counting(self) -> None: - head = "AKIA" + "IOSFODNN7" + head = "glpat-" + "IOSFODNN7" raw = {f"{head}EXAMPLE": 1, f"{head}SAMPLE2": 2, f"{head}SAMPLE3": 3} out = dashboard_agentic._redacted(raw) assert len(out) == 3, f"a row was lost: {out}" diff --git a/test/test_decisions_compaction_keep.py b/test/test_decisions_compaction_keep.py index c0ec73dde0d..3d2bf2c49f1 100644 --- a/test/test_decisions_compaction_keep.py +++ b/test/test_decisions_compaction_keep.py @@ -24,7 +24,7 @@ from kiro_crew.decisions.points import compaction_keep as point from kiro_crew.decisions.types import Answer, Choice -SECRET = "AKIAIOSFODNN7EXAMPLE" +SECRET = "glpat-IOSFODNN7EXAMPLE" def tool_row(index: int, *, tool: str = "execute_bash", inp: str = "ls", out: str = "ok") -> dict: diff --git a/test/test_decisions_judge_llm.py b/test/test_decisions_judge_llm.py index 63230a717c0..885c05980d1 100644 --- a/test/test_decisions_judge_llm.py +++ b/test/test_decisions_judge_llm.py @@ -1332,7 +1332,7 @@ async def _runner(prompt: str) -> str: answers = asyncio.run( gate.decide( gate.JUDGE_POINT, - {"since_last_tick": [{"text": "AKIAIOSFODNN7EXAMPLE"}]}, + {"since_last_tick": [{"text": "glpat-IOSFODNN7EXAMPLE"}]}, QUESTIONS, session_key="chat-1", config=_config(NudgeWakeConfig(provider="llm")), diff --git a/test/test_decisions_memory_recall.py b/test/test_decisions_memory_recall.py index 916f9a5189d..b1329dd9826 100644 --- a/test/test_decisions_memory_recall.py +++ b/test/test_decisions_memory_recall.py @@ -322,7 +322,7 @@ def test_a_snippet_is_redacted_before_it_is_clipped(self): would either send its tail or drop it silently; redact-then-clip replaces it whole and the placeholder is what the bound is applied to. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" raw = "x" * (mr.MAX_SNIPPET_CHARS - 4) + secret out = mr.scrubbed(raw, mr.MAX_SNIPPET_CHARS) assert secret not in out @@ -498,7 +498,7 @@ async def test_a_credential_in_a_snippet_refuses_the_whole_request(self, home, m A snippet is redacted first, so this is the second line of defence: a spelling ``scrubbed`` misses refuses the request rather than sending it. """ - state = mr.build_state("hi", [{"key": "a", "snippet": "AKIAIOSFODNN7EXAMPLE"}]) + state = mr.build_state("hi", [{"key": "a", "snippet": "glpat-IOSFODNN7EXAMPLE"}]) assert gate.scrub_reason(state, mr.build_questions([{"key": "a"}])) == ( gate.ERROR_SCRUBBED_CREDENTIAL ) diff --git a/test/test_decisions_message_steer.py b/test/test_decisions_message_steer.py index b0cb095a933..11e6b4d1225 100644 --- a/test/test_decisions_message_steer.py +++ b/test/test_decisions_message_steer.py @@ -18,16 +18,14 @@ import pytest -from kiro_crew import credential_patterns as _cred from kiro_crew.decisions import log as log_mod from kiro_crew.decisions.points import message_steer as ms from kiro_crew.decisions.types import Answer -#: An AWS key id assembled from the prefix list rather than written out, for the -#: reason ``test_decisions_gate`` gives: a contiguous key-shaped literal is refused -#: by the repo's own secret scanners, correctly, since neither they nor Semgrep can -#: tell a test vector from a leak. -_AWS_KEY = _cred.AWS_KEY_ID_PREFIXES.split("|")[0] + "A2B3C4D5E6F7G8H9" +#: A Secret-tier token assembled at run time rather than written out, for the +#: reason ``test_decisions_gate`` gives: a contiguous token literal is refused by +#: the repo's own secret scanners. +_AWS_KEY = "glpat-" + "A2B3C4D5E6F7G8H9" @pytest.fixture diff --git a/test/test_decisions_points.py b/test/test_decisions_points.py index 7ed11689d5a..8bbebbcfded 100644 --- a/test/test_decisions_points.py +++ b/test/test_decisions_points.py @@ -19,7 +19,6 @@ import pytest -from kiro_crew import credential_patterns as _cred from kiro_crew import decisions as core from kiro_crew.decisions.points import MAX_KEY_CHARS, as_text from kiro_crew.decisions.points import skills_select as sel @@ -816,7 +815,7 @@ def test_the_history_source_is_not_called_for_an_unsampled_turn(bg_loop, monkeyp # source rather than written out: a contiguous key-shaped literal is refused by # the repo's own secret scanners, correctly, since neither they nor Semgrep can # tell a test vector from a real leak. -_AWS_KEY = _cred.AWS_KEY_ID_PREFIXES.split("|")[0] + "A2B3C4D5E6F7G8H9" +_AWS_KEY = "glpat-" + "A2B3C4D5E6F7G8H9" _EXFIL_URL = "https://collector.example.invalid/x?sess" + "ion=" + "b" * 40 diff --git a/test/test_decisions_tool_risk.py b/test/test_decisions_tool_risk.py index 14a88d1ad6a..e11481798a3 100644 --- a/test/test_decisions_tool_risk.py +++ b/test/test_decisions_tool_risk.py @@ -266,21 +266,21 @@ async def test_a_credential_in_the_arguments_is_replaced_not_refused(self, home) with _answering(tr.TIER_RISKY, seen=seen): record = await tr.risk_record( tool="bash", - arguments="aws configure set aws_access_key_id AKIAIOSFODNN7EXAMPLE", + arguments="aws configure set aws_access_key_id glpat-IOSFODNN7EXAMPLE", policy="trust", session_key="chat-1", ) assert record is not None, "the call is annotated rather than dropped" sent = seen[0]["state"]["arguments"] - assert "AKIAIOSFODNN7EXAMPLE" not in sent + assert "glpat-IOSFODNN7EXAMPLE" not in sent assert "REDACTED" in sent @pytest.mark.asyncio async def test_the_redacted_state_gets_past_the_real_scrub(self, home): """End to end through ``gate.scrub_reason``, the code that actually decides.""" state = tr.build_state( - "bash", "aws configure set aws_access_key_id AKIAIOSFODNN7EXAMPLE", "set it up" + "bash", "aws configure set aws_access_key_id glpat-IOSFODNN7EXAMPLE", "set it up" ) assert gate.scrub_reason(state, tr.questions()) is None @@ -290,7 +290,7 @@ async def test_an_unredacted_credential_would_have_been_refused(self, home): """The counterfactual, so the redaction above is shown to be load-bearing.""" raw = { "tool": "bash", - "arguments": "aws configure set aws_access_key_id AKIAIOSFODNN7EXAMPLE", + "arguments": "aws configure set aws_access_key_id glpat-IOSFODNN7EXAMPLE", } assert gate.scrub_reason(raw, tr.questions()) == gate.ERROR_SCRUBBED_CREDENTIAL diff --git a/test/test_deny_bounded_write.py b/test/test_deny_bounded_write.py index 9675ea21aaf..e28e8dea02a 100644 --- a/test/test_deny_bounded_write.py +++ b/test/test_deny_bounded_write.py @@ -1546,7 +1546,7 @@ def test_a_collapsed_url_cannot_pull_a_severed_token_inside_the_cap(self) -> Non assert "ghp_" not in out and "attacker.example" not in out def test_a_credential_straddling_the_display_cap_leaks_no_fragment(self) -> None: - token = "AKIA" + "STRADDLE0123456A" + token = "glpat-" + "STRADDLE0123456A" cap = acp_dispatch._REQUEST_ID_LOG_CAP hostile = "x" * (cap - 9) + token + " tail" out = _loggable_request_id(hostile) @@ -1555,7 +1555,7 @@ def test_a_credential_straddling_the_display_cap_leaks_no_fragment(self) -> None def test_a_credential_straddling_the_cap_leaks_no_fragment(self) -> None: # Redact-before-bound: the cap falls inside the token; a slice taken # before redaction would leave the token's head in the output. - token = "AKIA" + "STRADDLE0123456A" + token = "glpat-" + "STRADDLE0123456A" cap = acp_dispatch._REQUEST_ID_LOG_CAP hostile = "x" * (cap - 9) + token + " tail" start = repr(hostile).index(token) diff --git a/test/test_deploy_round19_fixes.py b/test/test_deploy_round19_fixes.py index 98368dd499f..52adc4202a4 100644 --- a/test/test_deploy_round19_fixes.py +++ b/test/test_deploy_round19_fixes.py @@ -14,11 +14,11 @@ def test_f1_sanitize_response_redacts_credential_in_error(): - """Error response containing an AKIA key in local_dir path gets redacted.""" + """Error response containing a glpat- key in local_dir path gets redacted.""" from kiro_crew.deploy.handlers import _sanitize_response - payload = {"error": "local_dir not found: /tmp/AKIAIOSFODNN7EXAMPLE/build"} + payload = {"error": "local_dir not found: /tmp/glpat-IOSFODNN7EXAMPLE/build"} result = _sanitize_response(payload) - assert "AKIAIOSFODNN7EXAMPLE" not in result.get("error", "") + assert "glpat-IOSFODNN7EXAMPLE" not in result.get("error", "") assert "[REDACTED" in result.get("error", "") or "***" in result.get("error", "") @@ -26,11 +26,11 @@ def test_f1_sanitize_response_recursive_nested(): """Nested dicts and lists are recursively sanitized.""" from kiro_crew.deploy.handlers import _sanitize_response payload = { - "outer": {"inner": "token=AKIAIOSFODNN7EXAMPLE"}, - "list": ["safe", "AKIAIOSFODNN7EXAMPLE"], + "outer": {"inner": "token=glpat-IOSFODNN7EXAMPLE"}, + "list": ["safe", "glpat-IOSFODNN7EXAMPLE"], } result = _sanitize_response(payload) - assert "AKIAIOSFODNN7EXAMPLE" not in json.dumps(result) + assert "glpat-IOSFODNN7EXAMPLE" not in json.dumps(result) def test_f1_sanitize_response_idempotent_on_clean(): diff --git a/test/test_deploy_round6_fixes.py b/test/test_deploy_round6_fixes.py index d1371e7ee97..925368f24a2 100644 --- a/test/test_deploy_round6_fixes.py +++ b/test/test_deploy_round6_fixes.py @@ -11,13 +11,13 @@ def test_summarize_redacts_credential_snippets(): - """A finding whose snippet contains a raw AKIA key must be redacted in summarize output.""" - fake_key = "AKIAIOSFODNN7EXAMPLE" + """A finding whose snippet contains a raw glpat- key must be redacted in summarize output.""" + fake_key = "glpat-IOSFODNN7EXAMPLE" findings = [ Finding(kind="credential", snippet=fake_key, line=5, severity="credential"), ] result = summarize(findings) - assert fake_key not in result, "Raw AKIA key must not appear in summarize output" + assert fake_key not in result, "Raw glpat- key must not appear in summarize output" # The redaction should have replaced or masked it assert "[REDACTED" in result or "…" in result or len(fake_key) > len(result.split(fake_key[0])[0]) @@ -37,21 +37,21 @@ def test_summarize_redacts_internal_urls(): assert info_snippet in result # But a credential-severity finding MUST be masked findings_cred = [ - Finding(kind="credential", snippet="AKIAIOSFODNN7EXAMPLE", + Finding(kind="credential", snippet="glpat-IOSFODNN7EXAMPLE", line=3, severity="credential"), ] result_cred = summarize(findings_cred) - assert "AKIAIOSFODNN7EXAMPLE" not in result_cred + assert "glpat-IOSFODNN7EXAMPLE" not in result_cred def test_409_response_does_not_leak_akia_key(): """Integration: the 409 scan-blocked response body must not contain raw credentials.""" from kiro_crew.deploy.handlers import _redact_text - fake_key = "AKIAIOSFODNN7EXAMPLE" + fake_key = "glpat-IOSFODNN7EXAMPLE" raw_summary = f"⚠️ 1 potential issue(s):\n • line 5 [credential]: {fake_key}" redacted = _redact_text(raw_summary) - assert fake_key not in redacted, "Raw AKIA key must not appear in redacted response" + assert fake_key not in redacted, "Raw glpat- key must not appear in redacted response" def test_redact_text_passthrough_clean(): @@ -87,7 +87,7 @@ def test_text_file_with_credentials_still_caught(): with tempfile.TemporaryDirectory() as tmp: cred_path = Path(tmp) / "config.js" cred_path.write_text( - 'const key = "AKIAIOSFODNN7EXAMPLE";\n', encoding="utf-8" + 'const key = "glpat-IOSFODNN7EXAMPLE";\n', encoding="utf-8" ) findings, _ = _scan_tree(Path(tmp)) diff --git a/test/test_deploy_round8_fixes.py b/test/test_deploy_round8_fixes.py index 3c787f07a87..cc485a33a67 100644 --- a/test/test_deploy_round8_fixes.py +++ b/test/test_deploy_round8_fixes.py @@ -182,7 +182,7 @@ class TestF2PendingRedaction: """GET /api/deploy/pending redacts credential strings in entries.""" def test_pending_list_redacts_akia_in_scan_summary(self, tmp_path): - """A fake AKIA key in scan_summary must be redacted in the response.""" + """A fake glpat- key in scan_summary must be redacted in the response.""" pending.add_pending({ "site_id": "test-site", "local_dir": "/home/user/project", @@ -190,7 +190,7 @@ def test_pending_list_redacts_akia_in_scan_summary(self, tmp_path): "profile": "my-profile", "region": "us-east-1", "ttl_hours": 72, - "scan_summary": "Found key: AKIAIOSFODNN7EXAMPLE in config.js", + "scan_summary": "Found key: glpat-IOSFODNN7EXAMPLE in config.js", "content_digest": "", }) @@ -200,12 +200,12 @@ def test_pending_list_redacts_akia_in_scan_summary(self, tmp_path): entries = body["pending"] assert len(entries) == 1 summary = entries[0]["scan_summary"] - assert "AKIAIOSFODNN7EXAMPLE" not in summary + assert "glpat-IOSFODNN7EXAMPLE" not in summary def test_pending_list_redacts_in_site_id(self, tmp_path): """Credential patterns embedded in any field are redacted.""" pending.add_pending({ - "site_id": "site-AKIAIOSFODNN7EXAMPLE", + "site_id": "site-glpat-IOSFODNN7EXAMPLE", "local_dir": "", "artifact_slug": "", "profile": "", @@ -218,7 +218,7 @@ def test_pending_list_redacts_in_site_id(self, tmp_path): resp = _run(handlers._handle_pending_list(_FakeReq())) body = json.loads(resp.body) site_id_val = body["pending"][0]["site_id"] - assert "AKIAIOSFODNN7EXAMPLE" not in site_id_val + assert "glpat-IOSFODNN7EXAMPLE" not in site_id_val # ═══════════════════════════════════════════════════════════════════════════════ diff --git a/test/test_deploy_web_handlers.py b/test/test_deploy_web_handlers.py index a76cf194ce9..4abcd2e4368 100644 --- a/test/test_deploy_web_handlers.py +++ b/test/test_deploy_web_handlers.py @@ -103,7 +103,7 @@ def test_deploy_confirm_gate_returns_preview(monkeypatch): def test_deploy_scan_gate_blocks_secret(monkeypatch): _set_profile(monkeypatch) - leaky = "

AKIAABCDEFGHIJKLMNOP

" + leaky = "

glpat-ABCDEFGHIJKLMNOP

" monkeypatch.setattr(handlers, "get_default_store", lambda: _fake_store(content=leaky), raising=False) monkeypatch.setattr(handlers, "_HAS_ARTIFACTS", True) status, payload = _run(handlers._do_deploy({"site_id": "s", "artifact_slug": "a", "confirm": True})) @@ -114,7 +114,7 @@ def test_deploy_scan_gate_blocks_secret(monkeypatch): def test_deploy_credential_finding_cannot_be_overridden(monkeypatch): """Credential findings are hard-blocked — override_scan has no effect.""" _set_profile(monkeypatch) - leaky = "

AKIAABCDEFGHIJKLMNOP

" + leaky = "

glpat-ABCDEFGHIJKLMNOP

" monkeypatch.setattr(handlers, "get_default_store", lambda: _fake_store(content=leaky), raising=False) monkeypatch.setattr(handlers, "_HAS_ARTIFACTS", True) @@ -318,7 +318,7 @@ def test_deploy_local_dir_scan_gate(monkeypatch, tmp_path): monkeypatch.setattr(handlers, "_allowed_local_roots", lambda: [tmp_path.resolve()]) site = tmp_path / "site" site.mkdir() - (site / "index.html").write_text("

AKIAABCDEFGHIJKLMNOP

", encoding="utf-8") + (site / "index.html").write_text("

glpat-ABCDEFGHIJKLMNOP

", encoding="utf-8") status, payload = _run(handlers._do_deploy({"site_id": "s", "local_dir": str(site), "confirm": True})) assert status == 409 and payload["reason"] == "scan" @@ -330,7 +330,7 @@ def test_deploy_local_dir_scans_non_index_files(monkeypatch, tmp_path): site = tmp_path / "site" site.mkdir() (site / "index.html").write_text("

clean

", encoding="utf-8") - (site / "data.js").write_text("const k = 'AKIAABCDEFGHIJKLMNOP'", encoding="utf-8") + (site / "data.js").write_text("const k = 'glpat-ABCDEFGHIJKLMNOP'", encoding="utf-8") status, payload = _run(handlers._do_deploy({"site_id": "s", "local_dir": str(site), "confirm": True})) assert status == 409 and payload["reason"] == "scan" @@ -1252,18 +1252,18 @@ def test_allowed_local_roots_no_bare_tmp(monkeypatch, tmp_path): def test_scan_tree_nul_prepended_file_detects_credential(tmp_path): - """F1 R11: A file with NUL in first 8KiB containing AKIA key must still + """F1 R11: A file with NUL in first 8KiB containing glpat- key must still produce a credential finding. A binary-detection short-circuit must not skip the entire content scan, allowing NUL-prepended secrets to deploy.""" src = tmp_path / "src" src.mkdir() - # NUL byte + AKIA key in "JS" that a browser would still parse - payload = b"\x00// sneaky NUL-prepended file\nconst key = 'AKIAIOSFODNN7EXAMPLE';\n" + # NUL byte + glpat- key in "JS" that a browser would still parse + payload = b"\x00// sneaky NUL-prepended file\nconst key = 'glpat-IOSFODNN7EXAMPLE';\n" (src / "app.js").write_bytes(payload) findings, byte_size = handlers._scan_tree(src) cred_findings = [f for f in findings if f.severity == "credential"] assert len(cred_findings) >= 1, f"Expected credential finding, got: {findings}" - assert any("AKIA" in f.snippet for f in cred_findings) + assert any(f.snippet.startswith("glpa") for f in cred_findings) def test_scan_tree_real_binary_no_credentials_deploys_clean(tmp_path): diff --git a/test/test_deploy_web_profiles.py b/test/test_deploy_web_profiles.py index 52412ea4512..d08c61fec9e 100644 --- a/test/test_deploy_web_profiles.py +++ b/test/test_deploy_web_profiles.py @@ -173,7 +173,7 @@ def test_verify_backfill_audited(monkeypatch): def test_configure_set_refuses_credential_keys(): # Defense in depth: credential-material keys can never be written even if a # future caller passes them. - assert profiles_mod._configure_set("aws_access_key_id", "AKIA...", "p") is not None + assert profiles_mod._configure_set("aws_access_key_id", "glpat-...", "p") is not None assert profiles_mod._configure_set("aws_secret_access_key", "x", "p") is not None @@ -217,7 +217,7 @@ def fake_run_aws(args, profile, timeout=30): fake_aws = fakebin / "aws" fake_aws.write_text( "#!/usr/bin/env python3\nimport json\n" - 'print(json.dumps({"Credentials": {"AccessKeyId": "AKIATEST",' + 'print(json.dumps({"Credentials": {"AccessKeyId": "glpat-TEST",' ' "SecretAccessKey": "sk", "SessionToken": "tok",' ' "Expiration": "2026-01-01T00:00:00Z"}}))\n' ) @@ -228,7 +228,7 @@ def fake_run_aws(args, profile, timeout=30): out = json.loads(proc.stdout) assert out == { "Version": 1, - "AccessKeyId": "AKIATEST", + "AccessKeyId": "glpat-TEST", "SecretAccessKey": "sk", "SessionToken": "tok", "Expiration": "2026-01-01T00:00:00Z", @@ -277,7 +277,7 @@ def test_capacity_check_before_create_side_effect(monkeypatch): def test_profile_create_error_redacted_in_response(monkeypatch): """Raw aws-CLI stderr from create_aws_profile must be redacted before it reaches the dashboard response (the SEL audit keeps the raw text).""" - fake_key = "AKIAIOSFODNN7EXAMPLE" + fake_key = "glpat-IOSFODNN7EXAMPLE" monkeypatch.setattr(handlers.profiles_mod, "create_aws_profile", lambda *a, **k: f"aws configure failed: key {fake_key} rejected") resp = _run(handlers._handle_profiles_post( @@ -318,11 +318,11 @@ def add_gamma(): # --- profile redaction in GET response (item 1 R18) -------------------------- def test_profiles_get_redacts_credentials_in_note(monkeypatch): - """A note containing a fake AKIA key is redacted in the GET /profiles response.""" + """A note containing a fake glpat- key is redacted in the GET /profiles response.""" # GET also discovers CLI profiles via subprocess — mock it out (sandbox-free env). monkeypatch.setattr(profiles_mod, "discover_aws_profiles", lambda: []) # Register a profile with a credential-like value in the note field - fake_akia = "AKIAIOSFODNN7EXAMPLE" + fake_akia = "glpat-IOSFODNN7EXAMPLE" profiles_mod.save_registry({ "version": 2, "profiles": [ @@ -333,7 +333,7 @@ def test_profiles_get_redacts_credentials_in_note(monkeypatch): resp = _run(handlers._handle_profiles_get(_FakeReq())) import json as _json body = _json.loads(resp.text) - # The raw AKIA key must NOT appear in the response + # The raw glpat- key must NOT appear in the response assert fake_akia not in resp.text # But the profile entry should still be there assert len(body["profiles"]) == 1 diff --git a/test/test_design_tweak_backend.py b/test/test_design_tweak_backend.py index 31736a6256b..835a17511a2 100644 --- a/test/test_design_tweak_backend.py +++ b/test/test_design_tweak_backend.py @@ -1407,7 +1407,7 @@ def _serve(self, root, name, content): def test_labelled_credential_in_ordinary_file_is_refused(self, tmp_path): status, _, _ = self._serve( - tmp_path, "config.js", b"export const KEY = 'AKIA" + b"A" * 16 + b"';\n" + tmp_path, "config.js", b"export const KEY = 'glpat-" + b"A" * 16 + b"';\n" ) assert status == 403 diff --git a/test/test_design_tweak_backend_queue.py b/test/test_design_tweak_backend_queue.py index 4f2b9255276..b3f7e885033 100644 --- a/test/test_design_tweak_backend_queue.py +++ b/test/test_design_tweak_backend_queue.py @@ -591,8 +591,8 @@ def test_second_send_reports_already_and_does_not_reseal(self, isolated_queue): assert json.loads((isolated_queue / "r1.json").read_text())["sentAt"] == first_sent_at -# A canonical AWS example key — `redact_credentials` matches AKIA + 16 chars. -_FAKE_KEY = "AKIA" + "IOSFODNN7EXAMPLE" +# A fake GitLab-shaped token — `redact_credentials` matches glpat- + 16 chars. +_FAKE_KEY = "glpat-" + "IOSFODNN7EXAMPLE" _EXFIL_HOST = "evil.example.com" @@ -673,7 +673,7 @@ def test_credential_in_a_comment_level_note_is_redacted_too(self, queued_request def test_exfiltration_url_is_redacted_host_and_all(self, queued_request): """Also pins the ORDER: URLs are redacted before credentials. - A credential-first pass would rewrite only the `AKIA…` inside the query + A credential-first pass would rewrite only the `glpat-…` inside the query and leave a live, fetchable `https://evil.example.com/collect?key=…` standing. So the proof is that the URL was replaced WHOLE by the URL tag (which names the host by design), not merely stripped of its token. diff --git a/test/test_design_tweak_devproc.py b/test/test_design_tweak_devproc.py index 50ec242a33e..579aad90d03 100644 --- a/test/test_design_tweak_devproc.py +++ b/test/test_design_tweak_devproc.py @@ -486,7 +486,7 @@ def test_process_exit_redacts_credentials_from_the_log_tail( # Build the AWS-access-key-shaped fixture by concatenation so no # real-looking token literal sits in the source (the content scanner # reads added lines). - secret = "AKIA" + "IOSFODNN7" + "EXAMPLE" + secret = "glpat-" + "IOSFODNN7" + "EXAMPLE" payload = f"config error near key {secret} while starting" fake = FakePopen(pid=202, returncode=1) diff --git a/test/test_dev_fleet_app_sync.py b/test/test_dev_fleet_app_sync.py index 45a52b99223..52c2e9779d9 100644 --- a/test/test_dev_fleet_app_sync.py +++ b/test/test_dev_fleet_app_sync.py @@ -430,8 +430,8 @@ def test_redact_applied(): # Should not crash on normal strings assert _redact("hello world") == "hello world" # Should redact AWS keys - result = _redact("key=AKIAIOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in result + result = _redact("key=glpat-IOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in result # --- disk aggregation name derivation --- diff --git a/test/test_dev_fleet_app_worktrees.py b/test/test_dev_fleet_app_worktrees.py index 58c0abe8abd..80563c7e163 100644 --- a/test/test_dev_fleet_app_worktrees.py +++ b/test/test_dev_fleet_app_worktrees.py @@ -1017,7 +1017,7 @@ def test_reclaim_reports_a_teardown_that_left_the_home_behind(tmp_path): def test_reclaim_redacts_the_teardown_stderr(tmp_path): """Teardown stderr can carry a secret from the pod's own output.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" cp = SimpleNamespace(returncode=1, stdout="", stderr=f"stop failed: {secret}") with ( diff --git a/test/test_diag_procs.py b/test/test_diag_procs.py index 833579e857d..dd1a210a934 100644 --- a/test/test_diag_procs.py +++ b/test/test_diag_procs.py @@ -502,12 +502,14 @@ def test_cmdline_credentials_are_redacted(tmp_path: Path) -> None: table.add( GATEWAY, OUTSIDER, - cmdline=nul_argv(b"/v/bin/python3", b"-m", b"kiro_crew.cli", b"--key=AKIAIOSFODNN7EXAMPLE"), + cmdline=nul_argv( + b"/v/bin/python3", b"-m", b"kiro_crew.cli", b"--key=glpat-IOSFODNN7EXAMPLE" + ), env=dict(MARKER), ) roster = table.scan() rendered = roster.nodes[GATEWAY].cmdline - assert "AKIAIOSFODNN7EXAMPLE" not in rendered + assert "glpat-IOSFODNN7EXAMPLE" not in rendered assert "REDACTED" in rendered assert "kiro_crew.cli" in rendered, "redaction must not eat the identifying argv" @@ -774,16 +776,18 @@ def test_a_credential_straddling_the_bound_is_still_redacted(tmp_path: Path) -> table = FakeProcTable(tmp_path / "proc") # Pad so the credential sits astride MAX_CMDLINE_CHARS. pad = b"x" * (procs.MAX_CMDLINE_CHARS - 10) - argv = nul_argv(b"/v/bin/python3", b"-m", b"kiro_crew.cli", pad + b"--key=AKIAIOSFODNN7EXAMPLE") + argv = nul_argv( + b"/v/bin/python3", b"-m", b"kiro_crew.cli", pad + b"--key=glpat-IOSFODNN7EXAMPLE" + ) table.add(GATEWAY, OUTSIDER, cmdline=argv, env=dict(MARKER)) roster = table.scan() stored = roster.nodes[GATEWAY].cmdline assert len(stored) <= procs.MAX_CMDLINE_CHARS - assert "AKIAIOSFODNN7EXAMPLE" not in stored + assert "glpat-IOSFODNN7EXAMPLE" not in stored # Neither may a recognisable fragment of it survive the cut. for cut in range(6, 20): - assert "AKIAIOSFODNN7EXAMPLE"[:cut] not in stored + assert "glpat-IOSFODNN7EXAMPLE"[:cut] not in stored def test_a_credential_straddling_the_env_bound_is_still_redacted(tmp_path: Path) -> None: @@ -793,11 +797,11 @@ def test_a_credential_straddling_the_env_bound_is_still_redacted(tmp_path: Path) GATEWAY, OUTSIDER, cmdline=GATEWAY_ARGV, - env={**MARKER, "KIROCREW_HOME": pad + "AKIAIOSFODNN7EXAMPLE"}, + env={**MARKER, "KIROCREW_HOME": pad + "glpat-IOSFODNN7EXAMPLE"}, ) stored = table.scan().nodes[GATEWAY].env["KIROCREW_HOME"] assert len(stored) <= procs.MAX_PATH_CHARS - assert "AKIAIOSFODNN7EXAMPLE" not in stored + assert "glpat-IOSFODNN7EXAMPLE" not in stored def test_a_chain_deeper_than_the_recursion_limit_still_renders(tmp_path: Path) -> None: diff --git a/test/test_diagnose_probes.py b/test/test_diagnose_probes.py index b0d21733e5c..e73870f14ba 100644 --- a/test/test_diagnose_probes.py +++ b/test/test_diagnose_probes.py @@ -17,7 +17,7 @@ from kiro_crew import diagnose_probes as dp #: A credential-shaped value the redactor recognises; it must never reach a finding. -SECRET = "AKIA" + "Z7Q3XK2LM9PB4TWV" +SECRET = "glpat-" + "Z7Q3XK2LM9PB4TWV" HOUR_MS = 3600 * 1000 diff --git a/test/test_diagnostics.py b/test/test_diagnostics.py index 02aa7f237c9..0921aa62ed2 100644 --- a/test/test_diagnostics.py +++ b/test/test_diagnostics.py @@ -347,7 +347,7 @@ def test_path_collapses_counted_apart_from_secrets(tmp_path, monkeypatch): home = tmp_path / "home" _isolate(monkeypatch, home) # One real secret + a couple of home-path frames (no secret in them). - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" (home / "gateway.log").write_text( f"AWS key {secret}\n" f' File "{home}{os.sep}gateway.log", line 1, in a\n' diff --git a/test/test_directive_refusal_not_lost_marker_8635.py b/test/test_directive_refusal_not_lost_marker_8635.py index 2694237643f..c3f266fa8f1 100644 --- a/test/test_directive_refusal_not_lost_marker_8635.py +++ b/test/test_directive_refusal_not_lost_marker_8635.py @@ -330,7 +330,7 @@ def test_redaction_growth_cannot_strip_the_tag(self): re-attached at the cut, the way the App render marker already is.""" from kiro_crew.security import redact_credentials - tagged = session_directive.tag_refusal(("Error: " + ("AKIAIOSFODNN7EXAMPLE " * 380))[:7960]) + tagged = session_directive.tag_refusal(("Error: " + ("xoxb-IOSFODNN7EXAMPL " * 380))[:7960]) assert len(tagged) <= session_directive.MAX_TOOL_RESULT_CHARS grown, _ = redact_credentials(tagged) assert len(grown) > len(tagged), "redaction did not grow the text" diff --git a/test/test_discord_outbound_files.py b/test/test_discord_outbound_files.py index 9bac7e92411..ac53d62d498 100644 --- a/test/test_discord_outbound_files.py +++ b/test/test_discord_outbound_files.py @@ -25,7 +25,7 @@ _PNG = b"\x89PNG\r\n\x1a\n" + b"\x00" * 64 _JPEG = b"\xff\xd8\xff" + b"\x11" * 64 -_KEY = "AKIAIOSFODNN7EXAMPLE" +_KEY = "glpat-IOSFODNN7EXAMPLE" _TEST_UPLOAD_ROOT = "" @@ -156,7 +156,7 @@ async def test_live_frames_never_show_image_markup(self, tmp_path: Path, arrived @pytest.mark.asyncio async def test_image_removal_cannot_reassemble_a_credential(self, tmp_path: Path) -> None: - bodies = (f"{_KEY[:4]}![x]({(path := _png(tmp_path))}){_KEY[4:]}", f"[{_KEY[:4]}](![x]({path})https://example.com){_KEY[4:]}") + bodies = (f"{_KEY[:6]}![x]({(path := _png(tmp_path))}){_KEY[6:]}", f"[{_KEY[:6]}](![x]({path})https://example.com){_KEY[6:]}") for body in bodies: cli = await _turn(body) assert cli.uploaded_files and all(_KEY not in canonicalize_display(text) for text in _bodies(cli)) @@ -222,12 +222,12 @@ async def test_markup_stays_when_nothing_can_be_uploaded(self, tmp_path: Path, m monkeypatch.setattr(renderer_module, "sel", lambda: SimpleNamespace(log_api_access=lambda **kw: events.append(kw))) big = case in ("oversize", "near_cap") _shrink_file_cap(monkeypatch) if big else None - name = f"{_KEY[:4]}\u200b{_KEY[4:]}.png" if case == "near_cap" else "chart.png" + name = f"{_KEY[:6]}\u200b{_KEY[6:]}.png" if case == "near_cap" else "chart.png" path = tmp_path / "nope.png" if case == "sensitive" else _png(tmp_path, name=name, size=4096 if big else 0) markup, body = (m := f"![Revenue]({path})"), (f"```md\n{m}\n```\n" if case == "fenced" else f"Chart:\n\n{m}\n") caps = replace(DISCORD_CAPABILITIES, files_outbound=False) if case == "no_capability" else None root = str(tmp_path / "approved") if case == "sensitive" else str(tmp_path) - prefix = "y" * 1700 + f"\n\n{_KEY[:4]}**{_KEY[4:]}**\n\n" if case == "near_cap" else "" + prefix = "y" * 1700 + f"\n\n{_KEY[:6]}**{_KEY[6:]}**\n\n" if case == "near_cap" else "" cli = await _turn(prefix + body, uploads_allowed=case != "restricted", capabilities=caps, upload_root=root) # near_cap's redacted credential now draws the post-answer redaction # notice as its own trailing message, so the answer under test is the @@ -251,7 +251,7 @@ async def test_a_failed_upload_recovers_safely(self, tmp_path: Path, mode: str) for hidden in (False, True): path, (r, cli) = _png(tmp_path), _renderer() cli.edit_ok, _ = False, setattr(cli, mode, True) - await r.on_text_chunk((f"{_KEY[:4]}**{_KEY[4:]}**\n" if hidden else "Here it is.\n\n") + f"![Revenue]({path})") + await r.on_text_chunk((f"{_KEY[:6]}**{_KEY[6:]}**\n" if hidden else "Here it is.\n\n") + f"![Revenue]({path})") await r.on_done() assert cli.uploads, "the upload was never attempted" assert (recovered := [t for t, _ in cli.sent]) and all(_KEY not in canonicalize_display(t) for t in recovered) @@ -350,7 +350,7 @@ def _boom(name: str) -> Any: class TestDescriptionRedaction: - @pytest.mark.parametrize("streamed", [f"key AKIA\\{_KEY[4:]} here", f"https://x.example.com/u?k=AKIA\\{_KEY[4:]}", f"{_KEY[:4]}\u200b{_KEY[4:]}"]) + @pytest.mark.parametrize("streamed", [f"key glpat-\\{_KEY[6:]} here", f"https://x.example.com/u?k=glpat-\\{_KEY[6:]}", f"{_KEY[:6]}\u200b{_KEY[6:]}"]) def test_a_display_reassembled_credential_is_redacted(self, streamed: str) -> None: from kiro_crew.messaging.outbound_files import unescape_md from kiro_crew.security import redact_credentials @@ -552,7 +552,7 @@ class TestDisplayRedactionIsAFloor: #: A credential split by Markdown that Discord strips when it renders. The #: literal bytes carry ``**``, so a literal-form scan does not match; the #: rendered form is one contiguous key. - SPLIT_SECRET = "AKIA**IOSFODNN7**EXAMPLE" + SPLIT_SECRET = "glpat-**IOSFODNN7**EXAMPLE" @pytest.mark.asyncio async def test_a_restricted_session_still_gets_the_display_pass(self) -> None: diff --git a/test/test_discord_render_config.py b/test/test_discord_render_config.py index 49cd70766e7..ea08cff0de2 100644 --- a/test/test_discord_render_config.py +++ b/test/test_discord_render_config.py @@ -450,7 +450,7 @@ async def test_multi_line_reasoning_marks_every_line(self) -> None: @pytest.mark.asyncio async def test_reasoning_is_redacted_before_it_is_posted(self) -> None: - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" renderer, client, _ = _renderer(show_thinking=True) await renderer.on_turn_start() await renderer.on_thinking(f"the key is {secret}") diff --git a/test/test_discord_renderer.py b/test/test_discord_renderer.py index b3dfd627cee..b860d7d0808 100644 --- a/test/test_discord_renderer.py +++ b/test/test_discord_renderer.py @@ -730,7 +730,7 @@ async def test_a_cut_after_trailing_space_is_graded_on_the_trimmed_form( key. The assertion is therefore on the delivered forms: comparing the raw frames is what makes this hazard invisible. """ - head, tail = "AKIAIOSF", "ODNN7EXAMPLE" + head, tail = "glpat-IOSF", "ODNN7EXAMPLE" prefix = "word " * 20 src = prefix + head + " " + tail + " trailing prose here" r, cli = self._renderer(monkeypatch, len(prefix + head) + 3) @@ -821,7 +821,7 @@ async def test_no_safe_offset_withholds_the_text_instead_of_sending_it( seal then redacts that buffer as one string -- where the key is intact and matches, so it is replaced rather than shown. """ - head, tail = "AKIAIOSF", "ODNN7EXAMPLE" + head, tail = "glpat-IOSF", "ODNN7EXAMPLE" src = self._straddling_source(head, tail) monkeypatch.setattr("kiro_crew.discord.renderer.safe_split_offset", lambda *a, **k: 0) r, cli = self._renderer(monkeypatch, self._LIMIT) @@ -852,11 +852,12 @@ async def test_a_presentation_fallback_retains_no_piece_over_the_budget( legitimately ends up wider than the budget. That growth is the protection working, not a boundary escaping. """ - head, tail = "AKIAIOSF", "ODNN7EXAMPLE" + head, tail = "glpat-IOSF", "ODNN7EXAMPLE" # One unbroken word, so the splitter cuts hard at the budget and the first # cut lands inside the credential. Several budgets wide, so a single graded # offset would leave a remainder many times the budget. - src = "a" * (self._LIMIT - len(head)) + head + tail + "b" * (self._LIMIT * 6) + # The trailing run is `.`, which the token's body cannot absorb. + src = "a" * (self._LIMIT - len(head)) + head + tail + "." * (self._LIMIT * 6) assert severs_a_credential( await asyncio.to_thread(split_markdown_safe, src, self._LIMIT), _redact_all, @@ -889,10 +890,10 @@ async def test_a_markup_span_covering_a_whole_piece_is_caught( Three pieces, where no neighbouring PAIR reveals anything -- the link needs its closing bracket, which is in the third piece -- while the full join - collapses the url to its label and puts that label against ``AKIA``. So the + collapses the url to its label and puts that label against ``glpat-``. So the middle piece is swallowed whole, which a pairwise grade cannot see. """ - key_head, key_tail = "AKIA", "IOSFODNN7EXAMPLE" + key_head, key_tail = "glpat-", "IOSFODNN7EXAMPLE" src = ( "a" * (self._LIMIT - len(key_head)) + key_head @@ -919,7 +920,7 @@ async def test_a_retained_buffer_holds_only_source_text( """ src = ( "a" * (self._LIMIT - 8) - + "AKIAIOSF" + + "glpat-IOSF" + "ODNN7EXAMPLE" + "\n\npara two\n\n```py\nx = 1\n```\n\npara three " + "c" * self._LIMIT @@ -941,7 +942,7 @@ async def test_a_boundary_is_graded_on_the_text_the_seal_delivers( and the two messages sit flush together. """ r, cli = self._renderer(monkeypatch, self._LIMIT) - r._buf = ["a" * (self._LIMIT - 8) + "AKIAIOSF" + "ODNN7EXAMPLE" + "b" * self._LIMIT] + r._buf = ["a" * (self._LIMIT - 8) + "glpat-IOSF" + "ODNN7EXAMPLE" + "b" * self._LIMIT] await r._rotate_on_length() await r._seal_current(extract_uploads=False) self._assert_no_key_on_screen([text for text, _ in cli.sent]) @@ -979,7 +980,7 @@ async def test_the_seals_own_split_grades_its_boundary( ) src = ( "a" * (DISCORD_MAX_TEXT - 100) - + "[l](https://x/AKIA" + + "[l](https://x/glpat-" + "*" * 300 + "IOSFODNN7EXAMPLE)" + "b" * 400 @@ -1057,7 +1058,7 @@ async def test_an_edit_of_the_open_bubble_is_graded_against_the_message_above( ) -> None: """The core B1 case: a note ends in a prefix, the answer bubble completes it. - The reasoning note ends ``...AKIA`` and the answer streamed into the fresh + The reasoning note ends ``...glpat-`` and the answer streamed into the fresh bubble below it begins ``IOSFODNN7EXAMPLE...``; the client renders the note's subtext marker away, so note-tail + bubble-head read as one key across two messages. The first answer frame is graded (fresh send), but the SECOND @@ -1067,7 +1068,7 @@ async def test_an_edit_of_the_open_bubble_is_graded_against_the_message_above( r, cli = self._renderer(monkeypatch) await r.on_turn_start() # Reasoning note whose tail is a credential PREFIX (matches nothing alone). - await r.on_thinking("here is the reasoning and the key is AKIA") + await r.on_thinking("here is the reasoning and the key is glpat-") await r._flush_thinking() # The note is now a delivered message; a fresh answer lands below it. await r.on_text_chunk("IOSFODNN7EXAMPLE") @@ -1094,7 +1095,7 @@ async def test_the_final_seal_edit_does_not_restore_the_key( """ r, cli = self._renderer(monkeypatch) await r.on_turn_start() - await r.on_thinking("reasoning ending in AKIA") + await r.on_thinking("reasoning ending in glpat-") await r._flush_thinking() # A single answer chunk: fresh send opens the bubble, then on_done seals it # by EDITING that same bubble -- the seal-edit path. @@ -1118,12 +1119,12 @@ async def test_the_record_still_lets_the_next_fresh_message_grade( """ r, cli = self._renderer(monkeypatch) await r.on_turn_start() - await r.on_text_chunk("the answer ends in AKIA") + await r.on_text_chunk("the answer ends in glpat-") await r.on_done() # Record must have captured the delivered frame (not stayed empty), so the # next fresh message has a real predecessor to grade against. assert r._sent_tail, "the delivered frame must be recorded for the next seam" - assert "AKIA" in r._sent_tail or _redact_all(r._sent_tail) != r._sent_tail + assert "glpat-" in r._sent_tail or _redact_all(r._sent_tail) != r._sent_tail @pytest.mark.asyncio async def test_a_transient_edit_failure_grades_the_fallback_against_sent_tail( @@ -1136,14 +1137,14 @@ async def test_a_transient_edit_failure_grades_the_fallback_against_sent_tail( message -- but on a transient failure the bubble is STILL ON SCREEN, so the fallback POST lands directly below that visible frame. Grading it against ``_bubble_above`` (the message ABOVE the bubble) would leave the seam to the - visible frame ungraded, and a frame ending ``AKIA`` + a fallback beginning + visible frame ungraded, and a frame ending ``glpat-`` + a fallback beginning ``IOSFODNN7EXAMPLE`` would deliver the key across the two. The fallback must grade against ``_sent_tail`` -- the frame the reader actually sees. """ r, cli = self._renderer(monkeypatch) await r.on_turn_start() # Fresh send opens a bubble whose delivered frame ends in a credential PREFIX. - await r.on_text_chunk("the streamed answer so far AKIA") + await r.on_text_chunk("the streamed answer so far glpat-") assert r._stream_mid is not None, "a live bubble must be open" # The seal will EDIT that open bubble; force a TRANSIENT edit failure so it # falls through to a fresh POST while the bubble stays visible. The POST @@ -1250,7 +1251,7 @@ async def test_a_deleted_bubble_grades_the_fallback_against_the_visible_neighbou r, cli = self._renderer(monkeypatch) await r.on_turn_start() r._stream_mid = "99" # a live bubble exists... - r._bubble_above = "the visible neighbour above ends in AKIA" # ...below THIS + r._bubble_above = "the visible neighbour above ends in glpat-" # ...below THIS r._record_sent("an innocuous deleted-bubble frame") # _sent_tail = deleted frame r._pending_note_tail = "" cli.edit_gone = True # the edit finds the bubble DELETED (404) @@ -1260,7 +1261,7 @@ async def test_a_deleted_bubble_grades_the_fallback_against_the_visible_neighbou frames = [t for t, _ in cli.sent] + [t for _m, t, _c in cli.edits] # The visible neighbour is what the reader sees above the POST; read them # together the way the grader must have accounted for. - neighbour = "the visible neighbour above ends in AKIA" + neighbour = "the visible neighbour above ends in glpat-" self._assert_no_key_on_screen( [_delivered_form(neighbour)] + [_delivered_form(f) for f in frames] ) diff --git a/test/test_discover_handlers_cov80.py b/test/test_discover_handlers_cov80.py index 27f2d2a913c..7748d2b59df 100644 --- a/test/test_discover_handlers_cov80.py +++ b/test/test_discover_handlers_cov80.py @@ -543,7 +543,7 @@ async def test_install_502_scrubs_the_provider_error( """ provider = _BundleProvider() provider.fetch_skill_bundle = AsyncMock( # type: ignore[method-assign] - side_effect=RuntimeError("fetch failed for key AKIAIOSFODNN7EXAMPLE") + side_effect=RuntimeError("fetch failed for key glpat-IOSFODNN7EXAMPLE") ) registry.register(provider) request = _mk("POST", "/i", state=state, body={"provider": "covprov", "skill_id": "cov-skill"}) @@ -551,7 +551,7 @@ async def test_install_502_scrubs_the_provider_error( assert response.status == 502 assert _body(response) == {"error": "Failed to fetch skill from provider"} logged = sel_mock.log_tool_invocation.call_args.kwargs["error"] - assert "AKIAIOSFODNN7EXAMPLE" not in logged + assert "glpat-IOSFODNN7EXAMPLE" not in logged assert "REDACTED" in logged diff --git a/test/test_display_split_safety.py b/test/test_display_split_safety.py index 457f9ad77d8..d23ca022427 100644 --- a/test/test_display_split_safety.py +++ b/test/test_display_split_safety.py @@ -110,8 +110,8 @@ def test_a_severed_key_is_reported(self, head: str, tail: str) -> None: pytest.param("plain prose ending here", " and continuing there", id="prose"), pytest.param("emphasis **spanning", " the cut** is harmless", id="emphasis-span"), pytest.param("a [link](https://ex.test/a,b) then", " more prose", id="whole-link"), - pytest.param("", "AKIAIOSFODNN7EXAMPLE is scrubbed here", id="key-wholly-in-tail"), - pytest.param("AKIAIOSFODNN7EXAMPLE is scrubbed here", "", id="key-wholly-in-head"), + pytest.param("", "glpat-IOSFODNN7EXAMPLE is scrubbed here", id="key-wholly-in-tail"), + pytest.param("glpat-IOSFODNN7EXAMPLE is scrubbed here", "", id="key-wholly-in-head"), ], ) def test_a_harmless_cut_is_allowed(self, head: str, tail: str) -> None: @@ -125,7 +125,7 @@ def test_a_cut_that_closes_a_link_is_reported(self) -> None: # Caught ONLY by canonicalising the concatenation: each half alone is an # unfinished link, and only together do they form a link that collapses to # its label, putting the two halves of the key side by side. - head = "[AKIA](https://ex.test/a,b" + head = "[glpat-](https://ex.test/a,b" tail = ")IOSFODNN7EXAMPLE" assert joins_to_a_credential(head, tail, _default_redactor) @@ -134,7 +134,7 @@ def test_a_cut_inside_a_link_target_is_reported(self) -> None: # link makes the concatenation collapse to the label, so the key inside the # URL disappears from that reading -- while on screen each half is an # unfinished link whose URL text stays visible, and the reader reads through. - head = "[l](https://ex.test/x/AKIAIOSF" + head = "[l](https://ex.test/x/glpat-IOSF" tail = "ODNN7EXAMPLE)" assert joins_to_a_credential(head, tail, _default_redactor) @@ -142,10 +142,10 @@ def test_a_cut_inside_a_link_target_is_reported(self) -> None: ("head", "tail", "seen_by_the_join"), [ pytest.param( - "[AKIA](https://ex.test/a,b", ")IOSFODNN7EXAMPLE", True, id="cut-closes-a-link" + "[glpat-](https://ex.test/a,b", ")IOSFODNN7EXAMPLE", True, id="cut-closes-a-link" ), pytest.param( - "[l](https://ex.test/x/AKIAIOSF", "ODNN7EXAMPLE)", False, id="cut-inside-a-url" + "[l](https://ex.test/x/glpat-IOSF", "ODNN7EXAMPLE)", False, id="cut-inside-a-url" ), ], ) @@ -202,7 +202,7 @@ def test_a_non_positive_limit_yields_nothing(self) -> None: assert safe_split_offset("anything", 0, _default_redactor) == 0 def test_the_offset_moves_back_off_a_severed_key(self) -> None: - head, tail = "[AKIA](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" + head, tail = "[glpat-](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" pad = "x" * 40 text = pad + head + tail + " tail prose" limit = len(pad) + len(head) @@ -223,7 +223,7 @@ def counting_redactor(text: str) -> str: calls += 1 return _default_redactor(text) - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" text = "x" * 2000 + key[:8] + key[8:] + " tail prose" limit = 2000 + 8 @@ -246,13 +246,13 @@ class TestSeversACredential: """ def test_one_piece_has_no_boundary(self) -> None: - assert not severs_a_credential(["AKIAIOSFODNN7EXAMPLE"], _default_redactor) + assert not severs_a_credential(["glpat-IOSFODNN7EXAMPLE"], _default_redactor) def test_innocent_pieces_stay_clean(self) -> None: assert not severs_a_credential(["ordinary ", "prose in ", "three parts"], _default_redactor) def test_a_key_severed_between_two_pieces_is_caught(self) -> None: - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" pieces = [key[:8], key[8:]] for piece in pieces: assert _default_redactor(piece) == piece, "each piece alone must look clean" @@ -265,18 +265,18 @@ def test_a_key_spanning_three_pieces_is_caught_though_no_pair_shows_it(self) -> report all three clean. This is why the middle piece being the whole of one message is not a defence. """ - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" pieces = [key[:6], key[6:13], key[13:]] assert severs_a_credential(pieces, _default_redactor) def test_a_markup_span_covering_a_whole_piece_is_caught(self) -> None: """Canonicalising DROPS a link's target, so a piece of any size can vanish. - Split ``AKIA[label](url)`` so the closing bracket lands in the third piece: + Split ``glpat-[label](url)`` so the closing bracket lands in the third piece: no neighbouring pair canonicalises to anything, while the full join - collapses the url away and puts the label straight against ``AKIA``. + collapses the url away and puts the label straight against ``glpat-``. """ - pieces = ["AKIA", "[IOSFODNN7EXAMPLE](https://ex.test/", "padpadpad)"] + pieces = ["glpat-", "[IOSFODNN7EXAMPLE](https://ex.test/", "padpadpad)"] assert severs_a_credential(pieces, _default_redactor) @pytest.mark.parametrize( @@ -304,7 +304,7 @@ def test_a_clean_heading_sequence_stays_clean(self) -> None: assert not severs_a_credential(pieces, _default_redactor) def test_balanced_link_reading_grades_the_full_sequence(self) -> None: - pieces = ["[AKIA](https://x/((a)))", "IOSFODNN7EXAMPLE"] + pieces = ["[glpat-](https://x/((a)))", "IOSFODNN7EXAMPLE"] assert severs_a_credential(pieces, _default_redactor) def test_the_pieces_are_graded_as_delivered_not_as_split(self) -> None: @@ -314,7 +314,7 @@ def test_the_pieces_are_graded_as_delivered_not_as_split(self) -> None: pattern tolerates; the delivered pair sits flush. Grading the raw form is exactly the miss this function's contract warns callers about. """ - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" raw = [key[:8] + "\n\n", " " + key[8:]] delivered = [piece.strip() for piece in raw] @@ -358,7 +358,7 @@ class TestSafeSplitOffsetGradesTheDeliveredForm: #: One trailing space is all it takes: the raw halves are separated by it and #: the delivered halves are not. - _KEY = "AKIAIOSFODNN7EXAMPLE" + _KEY = "glpat-IOSFODNN7EXAMPLE" def _text(self) -> tuple[str, int]: pad = "x" * 40 @@ -400,7 +400,7 @@ class TestTheDeliveredReadingCatchesWhatAPreSplitRedactionCannot: """ def test_a_rule_between_the_halves_hides_the_key_from_a_pre_split_scan(self) -> None: - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" halves = [key[:8] + "\n\n---\n", "\n" + key[8:] + " tail prose"] delivered = [_strip_hr(piece).strip() for piece in halves] @@ -473,15 +473,15 @@ class TestLinkReadingsAgreeWithoutAnOpener: _WINDOWS = [ "plain words and digits 123", - "AKIA**IOSF**ODNN__7EXA__MPLE", - "AKIA`IOSF`ODNN``7EXA``MPLE ```fenced```", - "AKIA~~IOSF~~ODNN||7EXA||MPLE", - "ODNN", - "AKIA\u200bIOSF\u200dODNN\ufeff7EXA\u00adMPLE", - "[AKIAIOSF] (ODNN) [7EXA] (MPLE) and no opener", + "glpat-**IOSF**ODNN__7EXA__MPLE", + "glpat-`IOSF`ODNN``7EXA``MPLE ```fenced```", + "glpat-~~IOSF~~ODNN||7EXA||MPLE", + "ODNN", + "glpat-\u200bIOSF\u200dODNN\ufeff7EXA\u00adMPLE", + "[glpat-IOSF] (ODNN) [7EXA] (MPLE) and no opener", "[label] (https://x/y) [other][ref] ((nested)) )(", - "\\[AKIA\\]\\(IOSF\\) \\*ODNN\\* \\`7EXA\\` \\", - "line one **AKIA\nIOSF** line two \n\n*_~`|", + "\\[glpat-\\]\\(IOSF\\) \\*ODNN\\* \\`7EXA\\` \\", + "line one **glpat-\nIOSF** line two \n\n*_~`|", "the opener held apart: ] ( and ]\n( and ]\u200b(", "", ] @@ -496,7 +496,7 @@ def test_every_link_reading_equals_the_canonical_form(self, window: str) -> None def test_the_equality_is_specific_to_the_missing_opener(self) -> None: """Control: with the opener present the readings genuinely diverge.""" - window = "[AKIAIOSF](https://x/a_(b))ODNN7EXAMPLE" + window = "[glpat-IOSF](https://x/a_(b))ODNN7EXAMPLE" readings = { canonicalize_display(window), _first_close_reading(window), diff --git a/test/test_display_time_redaction.py b/test/test_display_time_redaction.py index a0690946705..17b6f83e100 100644 --- a/test/test_display_time_redaction.py +++ b/test/test_display_time_redaction.py @@ -39,7 +39,7 @@ # A credential shape `redact_credentials` catches, kept in one place so a change # to the detector surfaces as one failure rather than six. -SECRET = "AKIAIOSFODNN7EXAMPLE" +SECRET = "glpat-IOSFODNN7EXAMPLE" def _seed(state, slot_key: str, role: str, content: str) -> None: diff --git a/test/test_display_verdicts.py b/test/test_display_verdicts.py index 5bdac41dac9..d14f333614f 100644 --- a/test/test_display_verdicts.py +++ b/test/test_display_verdicts.py @@ -22,7 +22,7 @@ #: Storage is off on a platform with no uid to prove the directory is owned #: (``test_storage_stays_off_without_a_uid`` covers that branch on POSIX). pytestmark = pytest.mark.skipif(os.name == "nt", reason="stored verdicts are POSIX-only") -SECRET = "AKIAIOSFODNN7EXAMPLE" +SECRET = "glpat-IOSFODNN7EXAMPLE" HOST = "docs.contoso.example" #: Clean only while HOST is exempt: its query trips the aggregate-length heuristic. LINK = f"https://{HOST}/view?" + "&".join(f"p{i}=value{i}" for i in range(30)) diff --git a/test/test_dynamic_dashboard.py b/test/test_dynamic_dashboard.py index 7d159480494..28d05d4c6b6 100644 --- a/test/test_dynamic_dashboard.py +++ b/test/test_dynamic_dashboard.py @@ -248,7 +248,7 @@ class TestWhatAnAgenticValueCarriesToThePage: #: An AWS access key id by shape, matching the redactor's own pattern. It is a #: documentation example and names no account. - KEY = "AKIAIOSFODNN7EXAMPLE" + KEY = "xoxb-IOSFODNN7EXAMPL" #: A long base64-looking query on a host nobody allowed, which is the shape the #: exfiltration redactor removes. @@ -658,7 +658,7 @@ def test_a_refusal_scrubs_the_field_name_and_the_sentence(self) -> None: it verbatim on the dashboard. Nothing between the refusal and that render inspects it, which is what makes this an output boundary. """ - secret = "AKIAIOSFODNN7EXAMPLE" # noqa: S105 - a public AWS doc example value + secret = "xoxb-IOSFODNN7EXAMPL" # noqa: S105 - a fake token entry = dashboard_agentic.refusal_entry( dashboard_agentic.WriteRefused("unknown_field", secret, f"no such field {secret}") ) @@ -1258,7 +1258,7 @@ def test_what_lands_through_the_package_path_is_redacted( }, ) model = self.read().model - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "xoxb-IOSFODNN7EXAMPL" written = dashboard_agentic.check_write(model, "rows", [{"key": secret}]) landed = json.dumps(written["value"]) assert secret not in landed, "a credential reached the stored value unscrubbed" diff --git a/test/test_dynamic_dashboard_cards.py b/test/test_dynamic_dashboard_cards.py index 99d71e94479..ad12b53271f 100644 --- a/test/test_dynamic_dashboard_cards.py +++ b/test/test_dynamic_dashboard_cards.py @@ -842,9 +842,9 @@ def test_markup_cannot_hide_a_split_credential_behind_a_character_reference(refe @pytest.mark.parametrize( "split", [ - "AKIAIOSFODNN7EXAMPLE", - "AKIAIOSFODNN7EXAMPLE", - "

AKIAIOSFOD

NN7EXAMPLE

", + "glpat-IOSFODNN7EXAMPLE", + "glpat-IOSFODNN7EXAMPLE", + "

glpat-IOSFOD

NN7EXAMPLE

", ], ) def test_markup_cannot_split_a_credential_token_across_tags(split): @@ -858,7 +858,7 @@ def test_markup_cannot_split_a_credential_token_across_tags(split): from kiro_crew.dashboard.card_lifecycle import _hides_secret, _redact, _redact_card_output - token = "AKIAIOSFODNN7EXAMPLE" + token = "glpat-IOSFODNN7EXAMPLE" assert _redact("

" + token + "

") != "

" + token + "

" markup = "

" + split + "

" assert token not in markup @@ -1154,9 +1154,9 @@ async def generate(*args, **kwargs): def test_a_stray_text_lt_before_a_tag_cannot_hide_a_split_credential(): from kiro_crew.dashboard import card_lifecycle - # A browser shows "x < AKIAIOSFODNN7EXAMPLE": the "< " is text, and the + # A browser shows "x < glpat-IOSFODNN7EXAMPLE": the "< " is text, and the # stray inside the paragraph is ignored. - split = "Deploy key: x < AKIAIOSFODNN7EXAMPLE" + split = "Deploy key: x < glpat-IOSFODNN7EXAMPLE" assert card_lifecycle._hides_secret(split) html = f'

{split}

' assert ( @@ -1169,14 +1169,14 @@ def test_a_stray_text_lt_before_a_tag_cannot_hide_a_split_credential(): # none of it, so a key split by one reads joined. # Every ending the HTML tokenizer honours. for comment in ("", "", "", "", "", ""): - assert card_lifecycle._hides_secret(f"Deploy key: AKIA{comment}IOSFODNN7EXAMPLE"), comment + assert card_lifecycle._hides_secret(f"Deploy key: glpat-{comment}IOSFODNN7EXAMPLE"), comment assert card_lifecycle._html_texts("ab")[1] == "ab" assert card_lifecycle._html_texts("abc")[1] == "abc" # A "b": "ab", "ab": "ab", "ab": "ab", @@ -1380,15 +1380,15 @@ def busy(key): "ab": "ab", "ac": "ac", - "x IOSF": "x IOSF", - "x IOSF": "x IOSF", - "x AKIA": "x AKIA", - "x IOSF": "x IOSF", - "x IOSF": "x IOSF", + "x IOSF": "x IOSF", + "x IOSF": "x IOSF", + "x glpat-": "x glpat-", + "x IOSF": "x IOSF", + "x IOSF": "x IOSF", "x b": "x b", - "x AKIA": "x AKIA", - "AKIA": "AKIA", - "AKIAIOSFX": "AKIAIOSFX", + "x glpat-": "x glpat-", + "glpat-": "glpat-", + "glpat-IOSFX": "glpat-IOSFX", } @@ -1403,9 +1403,10 @@ def test_cdata_is_kept_as_text_where_the_browser_would_hide_it(): """Showing more than the browser hides nothing; showing less could split a key.""" from kiro_crew.dashboard import card_lifecycle - # Chromium renders "AKIAX" here (a bogus comment inside a MathML text point). + # Chromium renders "glpat-X" here (a bogus comment inside a MathML text point). assert ( - card_lifecycle._html_texts("AKIAIOSFX")[1] == "AKIAIOSFX" + card_lifecycle._html_texts("glpat-IOSFX")[1] + == "glpat-IOSFX" ) diff --git a/test/test_ephemeral_sessions.py b/test/test_ephemeral_sessions.py index 103b8e6aaf1..81765fd1063 100644 --- a/test/test_ephemeral_sessions.py +++ b/test/test_ephemeral_sessions.py @@ -706,13 +706,13 @@ def test_post_redacts_credentials_in_http_error_body(self): code=502, msg="Bad Gateway", hdrs=None, - fp=io.BytesIO(b'{"error": "upstream rejected key AKIAIOSFODNN7EXAMPLE"}'), + fp=io.BytesIO(b'{"error": "upstream rejected key glpat-IOSFODNN7EXAMPLE"}'), ) from kiro_crew.mcp_core import _post result = _post("/api/lessons", {"rule": "x"}) - assert "AKIAIOSFODNN7EXAMPLE" not in result["error"] + assert "glpat-IOSFODNN7EXAMPLE" not in result["error"] assert "REDACTED" in result["error"] def test_learn_add_tool_maps_unknown_session_to_friendly_message(self): diff --git a/test/test_eval_subagent_deny_notice.py b/test/test_eval_subagent_deny_notice.py index 955afbffda8..df536dfe758 100644 --- a/test/test_eval_subagent_deny_notice.py +++ b/test/test_eval_subagent_deny_notice.py @@ -235,10 +235,10 @@ async def _reject(request_id) -> None: async def test_eval_gate_reason_is_redacted_before_it_reaches_the_model(monkeypatch): provider = _Provider(title="Run: aws s3 ls") await _run_eval_turn( - provider, monkeypatch, gate_reason="denied: token AKIAIOSFODNN7EXAMPLE1234 in args" + provider, monkeypatch, gate_reason="denied: token glpat-IOSFODNN7EXAMPLE1234 in args" ) (notice,) = provider.steered - assert "AKIAIOSFODNN7EXAMPLE1234" not in notice + assert "glpat-IOSFODNN7EXAMPLE1234" not in notice # ── Behavioural: eval judge ────────────────────────────────────────────────── diff --git a/test/test_fargate_closed_forward_remedy.py b/test/test_fargate_closed_forward_remedy.py index f724ef74a10..c169ddcfad6 100644 --- a/test/test_fargate_closed_forward_remedy.py +++ b/test/test_fargate_closed_forward_remedy.py @@ -167,7 +167,7 @@ class TestStdoutCaptureHygiene: def test_reason_text_is_never_surfaced(self) -> None: """Service-controlled text classifies; it is never shown or logged.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" stdout = f"{BANNER}\n\nSessionId: {SESSION_ID} : {IDLE_REASON} {secret}\n\n" msg = _tunnel(stdout=stdout)._exit_error(0) assert secret not in msg @@ -188,8 +188,8 @@ def test_credentials_redacted_before_matching(self) -> None: the reason text back to nobody, so there is no return value to observe it through. """ - raw = f"SessionId: {SESSION_ID} : closed AKIAIOSFODNN7EXAMPLE\n" - assert "AKIAIOSFODNN7EXAMPLE" not in _sanitize_ssm_stdout(raw) + raw = f"SessionId: {SESSION_ID} : closed glpat-IOSFODNN7EXAMPLE\n" + assert "glpat-IOSFODNN7EXAMPLE" not in _sanitize_ssm_stdout(raw) # The notice is still classifiable with the credential gone. assert _ssm_close_reason(raw) == "closed" diff --git a/test/test_file_change_snapshots.py b/test/test_file_change_snapshots.py index f3bbc2cbc6e..fc3499fec62 100644 --- a/test/test_file_change_snapshots.py +++ b/test/test_file_change_snapshots.py @@ -541,24 +541,24 @@ def test_after_empty_when_file_deleted_during_turn(self, tmp_path: Path): def test_redacts_credentials_in_after_content(self, tmp_path: Path): f = tmp_path / "config.ini" - f.write_text("aws_access_key_id=AKIAIOSFODNN7EXAMPLE\n") + f.write_text("aws_access_key_id=glpat-IOSFODNN7EXAMPLE\n") slot = _make_slot_with_assistant_message() slot._file_changes = [{"path": str(f), "content": "(empty)"}] _flush_file_changes(slot) changes = slot.messages[-1]["meta"]["file_changes"] - # AKIA key is scrubbed before reaching the UI. - assert "AKIAIOSFODNN7EXAMPLE" not in changes[0]["after"] + # glpat- key is scrubbed before reaching the UI. + assert "glpat-IOSFODNN7EXAMPLE" not in changes[0]["after"] def test_redacts_credentials_in_before_content(self, tmp_path: Path): f = tmp_path / "post-edit.ini" f.write_text("clean\n") slot = _make_slot_with_assistant_message() slot._file_changes = [ - {"path": str(f), "content": "aws_secret_access_key=AKIAIOSFODNN7EXAMPLE\n"} + {"path": str(f), "content": "aws_secret_access_key=glpat-IOSFODNN7EXAMPLE\n"} ] _flush_file_changes(slot) changes = slot.messages[-1]["meta"]["file_changes"] - assert "AKIAIOSFODNN7EXAMPLE" not in changes[0]["before"] + assert "glpat-IOSFODNN7EXAMPLE" not in changes[0]["before"] def test_an_unchanged_credential_line_is_not_turned_into_a_phantom_diff( self, tmp_path: Path @@ -1162,14 +1162,14 @@ def test_redaction_applies_to_content_block_before_in_flush(self, short_tmp_dir: slot = _make_slot_with_assistant_message() # Before content contains a credential (from content block) slot._file_changes = [ - {"path": str(f), "content": "aws_access_key_id=AKIAIOSFODNN7EXAMPLE\n"} + {"path": str(f), "content": "aws_access_key_id=glpat-IOSFODNN7EXAMPLE\n"} ] _flush_file_changes(slot) meta = slot.messages[-1].get("meta", {}) assert "file_changes" in meta changes = meta["file_changes"] - # The AKIA key in before must be scrubbed - assert "AKIAIOSFODNN7EXAMPLE" not in changes[0]["before"] + # The glpat- key in before must be scrubbed + assert "glpat-IOSFODNN7EXAMPLE" not in changes[0]["before"] def test_chip_scrub_is_the_exfil_first_composition(self, short_tmp_dir: Path): """A long-query exfil URL in chip content loses its WHOLE url. @@ -1204,7 +1204,7 @@ def test_sensitive_path_refused_even_with_diff_old_text(self): — credentials must never enter message meta regardless of source.""" result = _snapshot_write_target( {"command": "strReplace", "path": "~/.aws/credentials"}, - diff_old_text="[default]\naws_access_key_id=AKIAEXAMPLE\n", + diff_old_text="[default]\naws_access_key_id=glpat-EXAMPLE\n", diff_path="~/.aws/credentials", ) # Must be None — sensitive path refusal takes priority diff --git a/test/test_file_grep.py b/test/test_file_grep.py index 0b73a4fe11e..61a72dc4a56 100644 --- a/test/test_file_grep.py +++ b/test/test_file_grep.py @@ -781,11 +781,11 @@ async def test_a_credential_on_the_matching_line_is_redacted( root = tmp_path / "secrets" root.mkdir() (root / "settings.py").write_text( - 'AWS_KEY = "AKIAIOSFODNN7EXAMPLE" # deploy key\n', encoding="utf-8" + 'AWS_KEY = "glpat-IOSFODNN7EXAMPLE" # deploy key\n', encoding="utf-8" ) payload = await _grep(root, "deploy key") preview = payload["results"][0]["preview"] - assert "AKIAIOSFODNN7EXAMPLE" not in preview + assert "glpat-IOSFODNN7EXAMPLE" not in preview assert "deploy key" in preview # the match itself still reads @pytest.mark.asyncio @@ -797,19 +797,19 @@ async def test_a_credential_inside_a_document_is_redacted_too(self, tmp_path): root.mkdir() _write_docx( root / "runbook.docx", - ["the WIDGET rotation", "token AKIAIOSFODNN7EXAMPLE is the WIDGET key"], + ["the WIDGET rotation", "token glpat-IOSFODNN7EXAMPLE is the WIDGET key"], ) payload = await _grep(root, "WIDGET key") preview = payload["results"][0]["preview"] - assert "AKIAIOSFODNN7EXAMPLE" not in preview + assert "glpat-IOSFODNN7EXAMPLE" not in preview def test_a_credential_in_the_PATH_is_redacted(self): """A path segment can itself be credential-shaped -- a directory or filename holding a token -- and this row is an egress boundary for a file the user never asked for by name. The listings in this module already redact the paths they return; a search result is no different.""" - hit = f._grep_hit("/repo/AKIAIOSFODNN7EXAMPLE/notes.txt", 3, "nothing secret here") - assert "AKIA" not in hit["file"] + hit = f._grep_hit("/repo/glpat-IOSFODNN7EXAMPLE/notes.txt", 3, "nothing secret here") + assert "glpat-" not in hit["file"] # The clean segments survive, so the row still says where it is. assert "notes.txt" in hit["file"] @@ -825,7 +825,7 @@ def test_every_string_a_row_carries_is_redacted(self): flagged one per round -- preview, then label, then path -- because each fix covered the field that was named. This asserts over the row's strings, so a field added later without redaction fails here rather than in a review.""" - planted = "AKIAIOSFODNN7EXAMPLE" + planted = "glpat-IOSFODNN7EXAMPLE" hit = f._grep_hit( f"/repo/{planted}/notes.txt", 0, @@ -839,8 +839,8 @@ def test_a_credential_in_a_sheet_title_is_redacted_like_a_preview(self): """A label is document CONTENT, not a shape this endpoint chose -- a workbook's is its sheet title, which an author picks. It reaches the response and the audit resource string, so leaving it raw published whatever the title said.""" - hit = f._grep_hit("/r/budget.xlsx", 0, "totals", label="AKIAIOSFODNN7EXAMPLE row 12") - assert "AKIA" not in hit["label"] + hit = f._grep_hit("/r/budget.xlsx", 0, "totals", label="glpat-IOSFODNN7EXAMPLE row 12") + assert "glpat-" not in hit["label"] def test_a_long_sheet_title_is_cut_like_a_preview(self): """Author-controlled text of any length, bounded like every other string this @@ -892,9 +892,9 @@ def test_redaction_runs_before_truncation(self, monkeypatch): """A secret straddling the preview cap would be CUT IN HALF first, and half a token matches no pattern -- so the cut has to come second.""" monkeypatch.setattr(f, "_GREP_PREVIEW_CHARS", 40) - line = "x" * 30 + "AKIAIOSFODNN7EXAMPLE" + " tail" + line = "x" * 30 + "glpat-IOSFODNN7EXAMPLE" + " tail" hit = f._grep_hit("/r/a.py", 1, line) - assert "AKIA" not in hit["preview"] + assert "glpat-" not in hit["preview"] assert len(hit["preview"]) <= 40 @@ -1141,9 +1141,9 @@ def test_the_query_still_reaches_the_child_over_that_channel(self, monkeypatch): _rg_spawn(monkeypatch, lines=(), made=made) # A future deadline: `_grep_rg` returns before spawning anything when the # budget is already spent, and then this would assert on an empty list. - f._grep_rg("/r", "AKIAIOSFODNN7EXAMPLE", f.time.monotonic() + 5) + f._grep_rg("/r", "glpat-IOSFODNN7EXAMPLE", f.time.monotonic() + 5) assert made, "no child was spawned" - assert made[0].stdin.written == "AKIAIOSFODNN7EXAMPLE\n" + assert made[0].stdin.written == "glpat-IOSFODNN7EXAMPLE\n" # Closed too, or rg would wait for EOF that never comes. assert made[0].stdin.closed is True @@ -1487,9 +1487,9 @@ async def test_a_secret_typed_as_the_query_never_reaches_the_audit_log( """Previews are redacted for the pasted-secret case; a user grepping for a token VALUE types the token, which is the same class of text.""" monkeypatch.setattr(f, "_grep_rg_executable", lambda: None) - await _grep(tree, "AKIAIOSFODNN7EXAMPLE") + await _grep(tree, "glpat-IOSFODNN7EXAMPLE") for call in mock_sel.log_api_access.call_args_list: - assert "AKIAIOSFODNN7EXAMPLE" not in str(call.kwargs.get("resources", "")) + assert "glpat-IOSFODNN7EXAMPLE" not in str(call.kwargs.get("resources", "")) class TestWorkbookExpansion: diff --git a/test/test_file_office_preview.py b/test/test_file_office_preview.py index 69de2f8b7cb..a8affaa525c 100644 --- a/test/test_file_office_preview.py +++ b/test/test_file_office_preview.py @@ -166,7 +166,7 @@ async def test_pptx_slides_are_redacted_before_the_cap(tmp_path, mock_sel): # Same rule as the flat text (test_redaction_runs_before_truncation): a # credential straddling the per-slide cut must not leak as a prefix. f = tmp_path / "creds.pptx" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" _write_pptx(str(f), [["x" * (_OFFICE_PREVIEW_CAP - 10) + secret], ["next"]]) with patch("kiro_crew.dashboard.handlers._validate_dashboard_path", return_value=str(f)): async with TestClient(TestServer(_make_app())) as client: @@ -416,8 +416,8 @@ async def test_redaction_runs_before_truncation(tmp_path, mock_sel): """ f = tmp_path / "creds.docx" # One paragraph: filler that ends 10 chars before the cap, then a fake - # AKIA credential ID that straddles the boundary. - secret = "AKIAIOSFODNN7EXAMPLE" + # glpat- credential ID that straddles the boundary. + secret = "glpat-IOSFODNN7EXAMPLE" filler = "x" * (_OFFICE_PREVIEW_CAP - 10) _write_docx(str(f), [filler + secret]) with patch("kiro_crew.dashboard.handlers._validate_dashboard_path", return_value=str(f)): @@ -480,28 +480,28 @@ async def test_docx_credential_straddling_the_cap_near_either_edge_is_masked( """The token is never cut at the cap, however little or much of it sits before it. test_redaction_runs_before_truncation covers the middle. A character-granular - budget would serve the ``AKIA`` prefix at both of these offsets; 4 is the + budget would serve the ``glpat-`` prefix at both of these offsets; 4 is the shortest prefix that still names the key family, 16 leaves only the last four characters past the cap. """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f = tmp_path / "edge.docx" _write_docx(str(f), ["x" * (_OFFICE_PREVIEW_CAP - before_cap) + secret + " tail", "next"]) body = await _preview(f) assert body["truncated"] is True - assert "AKIA" not in body["text"] + assert "glpat-" not in body["text"] assert len(body["text"]) <= _OFFICE_PREVIEW_CAP @pytest.mark.asyncio async def test_docx_credential_in_the_paragraph_that_meets_the_budget_is_masked(tmp_path, mock_sel): """The paragraph the budget stops at is extracted whole, so its secret is seen whole.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f = tmp_path / "own-paragraph.docx" _write_docx(str(f), ["x" * (_OFFICE_PREVIEW_CAP - 10), secret, "next"]) body = await _preview(f) assert body["truncated"] is True - assert "AKIA" not in body["text"] + assert "glpat-" not in body["text"] assert len(body["text"]) <= _OFFICE_PREVIEW_CAP @@ -519,13 +519,13 @@ async def test_docx_redaction_shrink_above_the_cap_pulls_no_unmasked_text_under_ head = [jwt] * 4 used = sum(len(p) + 1 for p in head) margin = files_mod._STREAM_HOLDBACK_JWT_MAX - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f = tmp_path / "shrink.docx" _write_docx(str(f), [*head, "a" * (_OFFICE_PREVIEW_CAP + margin - 6 - used) + secret, "keep"]) body = await _preview(f) assert body["truncated"] is True assert jwt not in body["text"] - assert "AKIA" not in body["text"] + assert "glpat-" not in body["text"] assert len(body["text"]) <= _OFFICE_PREVIEW_CAP @@ -581,13 +581,13 @@ async def test_pptx_credential_straddling_the_cap_is_masked_in_slides_and_text( test_pptx_slides_are_redacted_before_the_cap covers the middle; these offsets are the ones a character-granular budget would leak (see the .docx twin). """ - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" f = tmp_path / "edge.pptx" _write_pptx(str(f), [["x" * (_OFFICE_PREVIEW_CAP - before_cap) + secret + " tail"], ["next"]]) body = await _preview(f) assert body["truncated"] is True - assert "AKIA" not in _slides_text(body) - assert "AKIA" not in body["text"] + assert "glpat-" not in _slides_text(body) + assert "glpat-" not in body["text"] assert sum(len(s["text"]) for s in body["slides"]) <= _OFFICE_PREVIEW_CAP assert len(body["text"]) <= _OFFICE_PREVIEW_CAP @@ -603,15 +603,15 @@ async def test_pptx_redaction_shrink_in_one_slide_frees_no_unmasked_text_in_the_ carries a raw secret. """ jwt = _jwt(3000) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" filler = "a" * (_OFFICE_PREVIEW_CAP - 6 - 4 * (len(jwt) + 1)) f = tmp_path / "shrink.pptx" _write_pptx(str(f), [[jwt] * 4, [filler], [secret + " more"], ["keep"]]) body = await _preview(f) assert body["truncated"] is True assert jwt not in _slides_text(body) - assert "AKIA" not in _slides_text(body) - assert "AKIA" not in body["text"] + assert "glpat-" not in _slides_text(body) + assert "glpat-" not in body["text"] @pytest.mark.asyncio @@ -684,7 +684,7 @@ async def test_blocks_text_is_credential_redacted(tmp_path, mock_sel): """The blocks payload carries the same document text the text mode does, so it goes through the same redaction — per string, so structure survives.""" f = tmp_path / "leaky.docx" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" write_docx( str(f), docx_para(f"key {secret} here", style="Heading1") + docx_table([[f"cell {secret}"]]), @@ -706,7 +706,7 @@ async def test_a_credential_split_across_two_runs_is_still_redacted(tmp_path, mo place while the text mode -- which redacts the whole joined extraction -- masks it, so the blocks payload would be the weaker of the two surfaces.""" f = tmp_path / "split.docx" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" head, tail = secret[:8], secret[8:] write_docx( str(f), @@ -748,7 +748,7 @@ def test_an_unknown_string_field_is_redacted_by_default(): """The point of the inversion. Enumerating the keys that hold text means a block shape added later carries its text out unredacted until someone extends the list, and nothing fails while they have not.""" - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" out = files_mod._redact_block({"type": "caption", "some_future_field": secret}) assert isinstance(out, dict) assert secret not in str(out["some_future_field"]) diff --git a/test/test_file_office_slides.py b/test/test_file_office_slides.py index 3b61c78ed95..f905479f607 100644 --- a/test/test_file_office_slides.py +++ b/test/test_file_office_slides.py @@ -461,7 +461,7 @@ async def test_a_slide_file_that_is_a_symlink_or_altered_is_refused_and_audited( digest = _write_pptx(f) _seed_cache(cache, digest, 2) secret = tmp_path / "credentials" - secret.write_bytes(b"AKIA-not-for-you") + secret.write_bytes(b"glpat--not-for-you") (cache / digest / "slide-1.png").unlink() (cache / digest / "slide-1.png").symlink_to(secret) (cache / digest / "slide-2.png").write_bytes(b"\x89PNG-replaced") @@ -471,7 +471,7 @@ async def test_a_slide_file_that_is_a_symlink_or_altered_is_refused_and_audited( linked_body = await linked.read() altered = await client.get(f"/api/file-office-slide?path={f}&n=2") assert linked.status == 404 and altered.status == 404 - assert b"AKIA" not in linked_body + assert b"glpat-" not in linked_body integrity = [ c for c in mock_sel.log_tool_invocation.call_args_list @@ -544,7 +544,7 @@ async def test_a_deck_whose_slides_show_a_credential_is_not_rendered(tmp_path, m _validated(f), patch(f"{_MOD}.soffice_path", return_value="/usr/bin/soffice"), patch(f"{_MOD}._run_soffice", soffice), - patch(f"{_MOD}._deck_text", return_value=("rotate me: AKIAIOSFODNN7EXAMPLE", False)), + patch(f"{_MOD}._deck_text", return_value=("rotate me: glpat-IOSFODNN7EXAMPLE", False)), ): async with TestClient(TestServer(_make_app())) as client: resp = await client.get(f"/api/file-office-slides?path={f}") diff --git a/test/test_file_send_channel.py b/test/test_file_send_channel.py index b333979a8df..d4d921f41a3 100644 --- a/test/test_file_send_channel.py +++ b/test/test_file_send_channel.py @@ -735,7 +735,7 @@ async def test_a_credential_bearing_filename_is_rejected_for_both_legs(self, tmp transport = MagicMock(spec_set=["send_document"]) transport.send_document = AsyncMock(return_value="123") app = self._app() - leaky_name = "AKIA" + "IOSFODNN7EXAMPLE" + ".txt" + leaky_name = "glpat-" + "IOSFODNN7EXAMPLE" + ".txt" with patch( "kiro_crew.dashboard.chat_runner._resolve_mirror_target", return_value=(self._link("telegram", "42"), transport), @@ -754,13 +754,13 @@ async def test_a_credential_bearing_filename_is_rejected_for_both_legs(self, tmp @pytest.mark.asyncio async def test_outbound_text_is_redacted_in_display_form(self, tmp_path, outbox_file): # redact() scans literal bytes; a channel renderer strips markdown - # delimiters at display, so AKIA**…** passes a literal scan and + # delimiters at display, so glpat-**…** passes a literal scan and # displays as an intact key. The caption must go through # redact_for_display before delivery — same boundary rule as every # renderer sink. from unittest.mock import AsyncMock - key = "AKIA" + "IOSFODNN7EXAMPLE" + key = "glpat-" + "IOSFODNN7EXAMPLE" transport = MagicMock(spec_set=["send_document"]) transport.send_document = AsyncMock(return_value="900") app = self._app() @@ -778,7 +778,7 @@ async def test_outbound_text_is_redacted_in_display_form(self, tmp_path, outbox_ json={ "file_path": str(outbox_file), "filename": "report.txt", - "description": f"{key[:4]}**{key[4:]}**", + "description": f"{key[:6]}**{key[6:]}**", }, headers={"X-Session-Key": "telegram:1"}, ) @@ -945,10 +945,10 @@ async def test_discord_destination_gets_send_document(self, tmp_path, outbox_pdf @pytest.mark.asyncio async def test_discord_outbound_text_is_redacted_in_display_form(self, tmp_path, outbox_file): # Same boundary rule as the Telegram leg: redact() scans literal bytes, - # and Discord renders markdown, so AKIA**…** displays as an intact key. + # and Discord renders markdown, so glpat-**…** displays as an intact key. from unittest.mock import AsyncMock - key = "AKIA" + "IOSFODNN7EXAMPLE" + key = "glpat-" + "IOSFODNN7EXAMPLE" transport = MagicMock(spec_set=["send_document"]) transport.send_document = AsyncMock(return_value="900") app = self._app() @@ -966,7 +966,7 @@ async def test_discord_outbound_text_is_redacted_in_display_form(self, tmp_path, json={ "file_path": str(outbox_file), "filename": "report.pdf", - "description": f"{key[:4]}**{key[4:]}**", + "description": f"{key[:6]}**{key[6:]}**", }, headers={"X-Session-Key": "discord:1"}, ) diff --git a/test/test_file_sheet.py b/test/test_file_sheet.py index fff899434fe..fbf7cf05f1a 100644 --- a/test/test_file_sheet.py +++ b/test/test_file_sheet.py @@ -196,7 +196,7 @@ def test_cell_text_is_credential_redacted(): # class as api_file_read, so the same redaction pass must apply. from kiro_crew.platform import redact_via_context - sample = "aws key AKIA" + "IOSFODNN7EXAMPLE" + sample = "aws key glpat-" + "IOSFODNN7EXAMPLE" assert redact_via_context(sample) != sample # fixture must be redactable def populate(wb): diff --git a/test/test_file_stream.py b/test/test_file_stream.py index bd05a4c9dcd..5a01dbf4e50 100644 --- a/test/test_file_stream.py +++ b/test/test_file_stream.py @@ -257,7 +257,7 @@ async def test_text_credentials_behind_forged_magic_refused(tmp_path, mock_sel): """file-download refuses redact()-flagged text; the same file with a forged media prefix must not become retrievable through file-stream.""" f = tmp_path / "secrets.mp3" - f.write_bytes(b"ID3" + b"AKIA_FAKE_CREDENTIAL_TEXT\n" * 10) + f.write_bytes(b"ID3" + b"glpat-_FAKE_CREDENTIAL_TEXT\n" * 10) with patch("kiro_crew.dashboard.handlers._validate_dashboard_path", return_value=str(f)), \ patch("kiro_crew.dashboard.handlers.files.redact", side_effect=lambda t: "[REDACTED]"): async with TestClient(TestServer(_make_app())) as client: @@ -272,7 +272,7 @@ async def test_invalid_utf8_magic_cannot_skip_the_scan(tmp_path, mock_sel): The probe then takes the shared binary scan, so the credential scan still runs and the file is refused -- a prepended byte is not a bypass.""" f = tmp_path / "secrets2.mp3" - key_id = "AKIA" + "IOSFODNN7" + "EXAMPLE" # built so no literal key sits here + key_id = "glpat-" + "IOSFODNN7" + "EXAMPLE" # built so no literal key sits here f.write_bytes(b"\xff\xfb" + f"key {key_id}\n".encode() * 10) with patch("kiro_crew.dashboard.handlers._validate_dashboard_path", return_value=str(f)): diff --git a/test/test_followup_suggest.py b/test/test_followup_suggest.py index 789f8c6b6f3..4050d52af62 100644 --- a/test/test_followup_suggest.py +++ b/test/test_followup_suggest.py @@ -371,7 +371,7 @@ async def test_endpoint_revalidates_schema(self): async def test_credentials_are_redacted_before_broadcast(self): slot = _ChatSlot("test") state = _mock_state(slot) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" async with TestClient(TestServer(_make_app(state))) as client: resp = await client.post( "/api/chat/slots/test/followup", @@ -394,7 +394,7 @@ async def test_credential_shaped_branch_is_dropped_not_broadcast(self): async with TestClient(TestServer(_make_app(state))) as client: resp = await client.post( "/api/chat/slots/test/followup", - json={"items": [_item(branch="AKIAIOSFODNN7EXAMPLE")]}, + json={"items": [_item(branch="glpat-IOSFODNN7EXAMPLE")]}, ) assert resp.status == 200 payload = state.deliver_ws_owners.call_args[0][1] diff --git a/test/test_gateway_appkit_endpoints_install.py b/test/test_gateway_appkit_endpoints_install.py index 625147ea179..219f5063c79 100644 --- a/test/test_gateway_appkit_endpoints_install.py +++ b/test/test_gateway_appkit_endpoints_install.py @@ -592,7 +592,7 @@ async def test_log_redaction_applied_per_line( async def _fake_install(name: str, log_lines: list[str] | None = None) -> dict[str, Any]: if log_lines is not None: # AWS access key ID pattern — caught by redact_credentials - log_lines.append("Found key AKIAIOSFODNN7EXAMPLE in config") + log_lines.append("Found key glpat-IOSFODNN7EXAMPLE in config") return {"ok": True, "name": name, "message": "ok", "log": "\n".join(log_lines or [])} monkeypatch.setattr( @@ -611,6 +611,6 @@ async def _fake_install(name: str, log_lines: list[str] | None = None) -> dict[s ) body = await resp.text() # The raw AWS key should NOT appear in the streamed output - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body # But the redaction marker should be present assert "REDACTED" in body diff --git a/test/test_gateway_appkit_endpoints_note.py b/test/test_gateway_appkit_endpoints_note.py index a7564637d6b..f17bf0adf73 100644 --- a/test/test_gateway_appkit_endpoints_note.py +++ b/test/test_gateway_appkit_endpoints_note.py @@ -752,8 +752,8 @@ async def test_note_visible_content_is_redacted(self, tmp_path: Path): state._slots["s1"] = slot raw = ( - "board updated AKIAIOSFODNN7EXAMPLE see " - "http://evil.example.com/x?d=AKIAIOSFODNN7EXAMPLE" + "board updated glpat-IOSFODNN7EXAMPLE see " + "http://evil.example.com/x?d=glpat-IOSFODNN7EXAMPLE" ) plain_note = "board updated, see https://example.com/board/42?view=week" async with self._make_client(state) as client: @@ -773,7 +773,7 @@ async def test_note_visible_content_is_redacted(self, tmp_path: Path): # marker embeds the domain by design, so assert the secret and URL path # are scrubbed rather than that the domain substring is absent. visible = slot.messages[0]["content"] - assert "AKIAIOSFODNN7EXAMPLE" not in visible + assert "glpat-IOSFODNN7EXAMPLE" not in visible assert "[REDACTED: credential]" in visible assert "[REDACTED: suspicious URL to evil.example.com]" in visible # Context half: the credential-shaped note seated none; the other note's diff --git a/test/test_git_repo_touches.py b/test/test_git_repo_touches.py index 68fa4f0312d..2379605e80c 100644 --- a/test/test_git_repo_touches.py +++ b/test/test_git_repo_touches.py @@ -959,7 +959,7 @@ async def test_a_path_the_redactor_masks_is_refused_and_announced( would only ever show an error. It is left out, out of ``listed``, and the listing says it is incomplete.""" # Shaped like an access key id, so the credential redactor masks it. - credential_shaped = "AKIA" + "IOSFODNN7" + "EXAMPLE" + credential_shaped = "glpat-" + "IOSFODNN7" + "EXAMPLE" plain = _init_repo(tmp_path / "plain") secretish = _init_repo(tmp_path / credential_shaped) if masked == "agent": diff --git a/test/test_goal_setup.py b/test/test_goal_setup.py index 6d8b9960421..2e7de164fba 100644 --- a/test/test_goal_setup.py +++ b/test/test_goal_setup.py @@ -187,7 +187,7 @@ def test_the_removed_nudge_names_the_goal_and_its_orphaned_milestones() -> None: def test_every_goal_nudge_quotes_goals_and_milestones_scrubbed() -> None: - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" goal = {"id": "g00000001", "text": f"Rotate {secret} weekly"} other = {"id": "g00000002", "text": f"Audit {secret} usage"} gone = {"id": "g00000003", "text": f"Drop {secret} keys"} diff --git a/test/test_governance_distribution.py b/test/test_governance_distribution.py index bcae41758d0..b10890077da 100644 --- a/test/test_governance_distribution.py +++ b/test/test_governance_distribution.py @@ -1299,7 +1299,7 @@ def test_a_transport_error_carrying_a_credential_is_redacted_not_just_the_source """The exception text is the ENDPOINT's, not ours: an error page, or a proxy echoing the request back, can carry the credential. ``_redact_source`` only knows the configured source, so the reason has to go through the full sanitiser.""" - leaked = "AKIAIOSFODNN7EXAMPLE" + leaked = "glpat-IOSFODNN7EXAMPLE" source = transport( _failing_fetcher(TimeoutError(f"upstream said: aws_access_key_id={leaked}")) ) diff --git a/test/test_governance_distribution_redaction.py b/test/test_governance_distribution_redaction.py index e5e654448b1..eefc21203a2 100644 --- a/test/test_governance_distribution_redaction.py +++ b/test/test_governance_distribution_redaction.py @@ -111,21 +111,21 @@ class TestEndpointAuthoredTextIsSanitised: def test_a_credential_echoed_by_the_endpoint_does_not_reach_the_detail( self, transport, install_ceiling ): - leaky = b'{"Authorization": "Bearer AKIAIOSFODNN7EXAMPLE" oops' + leaky = b'{"Authorization": "Bearer glpat-IOSFODNN7EXAMPLE" oops' source = transport(_static_fetcher(pd.FetchedPolicy(body=leaky))) install_ceiling(governance.parse_policy(_doc("running", distribution={"source": source}))) outcome = pd.refresh_now() assert outcome.status == pd.REFRESH_REJECTED - assert "AKIAIOSFODNN7EXAMPLE" not in outcome.detail + assert "glpat-IOSFODNN7EXAMPLE" not in outcome.detail def test_the_sanitiser_runs_both_passes(self): """The source elision AND the shared credential chain, not one or the other.""" source = "https://config.corp.example/p.json" - text = f"fetching {source} returned AKIAIOSFODNN7EXAMPLE" + text = f"fetching {source} returned glpat-IOSFODNN7EXAMPLE" clean = pd._sanitize_detail(text, source) assert source not in clean assert "config.corp.example" not in clean - assert "AKIAIOSFODNN7EXAMPLE" not in clean + assert "glpat-IOSFODNN7EXAMPLE" not in clean class TestTheSignatureAuditLabelIsRedacted: diff --git a/test/test_handler_cron_list.py b/test/test_handler_cron_list.py index f4ad511db28..5238f8f03b3 100644 --- a/test/test_handler_cron_list.py +++ b/test/test_handler_cron_list.py @@ -83,7 +83,7 @@ def test_next_run_past_due(self, cron_service: CronService) -> None: def test_message_is_redacted(self, cron_service: CronService) -> None: job = _make_job() - job.message = "token=AKIAIOSFODNN7EXAMPLE" + job.message = "token=glpat-IOSFODNN7EXAMPLE" cron_service._jobs = [job] # `security.redact` is the one pass now (it runs the exfiltration and # credential scanners internally and returns a plain str), so the assertion @@ -96,7 +96,7 @@ def test_message_is_redacted(self, cron_service: CronService) -> None: mock_redact.assert_any_call(job.message) assert result is not None assert "[REDACTED]" in result - assert "AKIAIOSFODNN7EXAMPLE" not in result + assert "glpat-IOSFODNN7EXAMPLE" not in result def test_a_real_credential_in_a_message_does_not_survive_the_listing( self, cron_service: CronService @@ -104,11 +104,11 @@ def test_a_real_credential_in_a_message_does_not_survive_the_listing( # Unmocked, so it exercises the real scanner rather than a stub that # returns whatever the test wanted. job = _make_job() - job.message = "token=AKIA" + "IOSFODNN7EXAMPLE" + job.message = "token=glpat-" + "IOSFODNN7EXAMPLE" cron_service._jobs = [job] result = asyncio.run(_handle_cron_command("cron list", cron_service, "C123", "t123")) assert result is not None - assert "AKIA" + "IOSFODNN7EXAMPLE" not in result + assert "glpat-" + "IOSFODNN7EXAMPLE" not in result assert "REDACTED" in result def test_remove_all_redacts_name(self, cron_service: CronService) -> None: @@ -116,7 +116,7 @@ def test_remove_all_redacts_name(self, cron_service: CronService) -> None: # persisted conversation log); j.name is free-form user/LLM-supplied, # so it must be redacted like j.message is in the `cron list` branch. job = _make_job() - job.name = "token=AKIAIOSFODNN7EXAMPLE" + job.name = "token=glpat-IOSFODNN7EXAMPLE" cron_service._jobs = [job] with patch("kiro_crew.messaging.commands.redact", return_value="[REDACTED]") as mock_redact: @@ -124,5 +124,5 @@ def test_remove_all_redacts_name(self, cron_service: CronService) -> None: mock_redact.assert_any_call(job.name) assert result is not None assert "[REDACTED]" in result - assert "AKIAIOSFODNN7EXAMPLE" not in result + assert "glpat-IOSFODNN7EXAMPLE" not in result assert not cron_service.list_jobs(include_disabled=True) # jobs still removed diff --git a/test/test_handler_turn.py b/test/test_handler_turn.py index c8bf1f98cca..59ca54caa8c 100644 --- a/test/test_handler_turn.py +++ b/test/test_handler_turn.py @@ -880,7 +880,7 @@ def test_the_slack_messages_sink_redacts_what_its_render_let_through( from conftest import MockSlackClient from kiro_crew.providers.base import LLMEvent - key = "AKIAIOSFODNN7EXAMPLE" + key = "glpat-IOSFODNN7EXAMPLE" monkeypatch.setattr( handler, "render_one_for_slack", diff --git a/test/test_handlers_artifacts_coverage.py b/test/test_handlers_artifacts_coverage.py index be16be2fc87..02f41338705 100644 --- a/test/test_handlers_artifacts_coverage.py +++ b/test/test_handlers_artifacts_coverage.py @@ -1561,7 +1561,7 @@ class TestIdEmbedsHardCredential: # (``_B64_CHUNK_RE``), so every encoded fixture below is padded past that # floor — a shorter encoding is not a chunk at all and never decoded. def test_literal_credential_is_detected(self) -> None: - assert _id_embeds_hard_credential("id-AKIAIOSFODNN7EXAMPLE") is True + assert _id_embeds_hard_credential("id-xoxb-IOSFODNN7EXAMPLE") is True def test_benign_id_is_not_flagged(self) -> None: assert _id_embeds_hard_credential("3f9a2b71-0c4d-4e8a-9b11-77d0c2e5a1f4") is False @@ -1573,7 +1573,7 @@ def test_undecodable_chunk_is_skipped_without_raising(self) -> None: assert _id_embeds_hard_credential("A" * 41) is False def test_base64_encoded_credential_is_detected(self) -> None: - encoded = base64.b64encode(b"AKIAIOSFODNN7EXAMPLE-with-trailing-filler").decode() + encoded = base64.b64encode(b"xoxb-IOSFODNN7EXAMPLE-with-trailing-filler").decode() assert len(encoded) >= 40 assert _id_embeds_hard_credential(encoded) is True @@ -1611,8 +1611,8 @@ def test_list_past_the_cap_is_emptied(self) -> None: assert self._leaf_of(out) == [] def test_string_past_the_cap_is_still_redacted(self) -> None: - out = _redact_remote_response(self._at_boundary("AKIAIOSFODNN7EXAMPLE")) - assert self._leaf_of(out) != "AKIAIOSFODNN7EXAMPLE" + out = _redact_remote_response(self._at_boundary("glpat-IOSFODNN7EXAMPLE")) + assert self._leaf_of(out) != "glpat-IOSFODNN7EXAMPLE" def test_non_string_scalar_past_the_cap_survives(self) -> None: out = _redact_remote_response(self._at_boundary(7)) @@ -1623,15 +1623,15 @@ def test_empty_string_past_the_cap_survives(self) -> None: assert self._leaf_of(out) == "" def test_already_redacted_top_level_key_is_not_rescanned(self) -> None: - payload = {"content": "AKIAIOSFODNN7EXAMPLE", "title": "AKIAIOSFODNN7EXAMPLE"} + payload = {"content": "glpat-IOSFODNN7EXAMPLE", "title": "glpat-IOSFODNN7EXAMPLE"} out = _redact_remote_response(payload, already_redacted=frozenset({"content"})) - assert out["content"] == "AKIAIOSFODNN7EXAMPLE" - assert out["title"] != "AKIAIOSFODNN7EXAMPLE" + assert out["content"] == "glpat-IOSFODNN7EXAMPLE" + assert out["title"] != "glpat-IOSFODNN7EXAMPLE" def test_external_id_keeps_benign_high_entropy_value(self) -> None: out = _redact_remote_response({"external_id": "9f8e7d6c5b4a39281706"}) assert out["external_id"] == "9f8e7d6c5b4a39281706" def test_external_id_with_hard_credential_is_replaced(self) -> None: - out = _redact_remote_response({"external_id": "AKIAIOSFODNN7EXAMPLE"}) + out = _redact_remote_response({"external_id": "glpat-IOSFODNN7EXAMPLE"}) assert out["external_id"] == art_handlers._REMOTE_ID_CRED_TAG diff --git a/test/test_handlers_memory_coverage.py b/test/test_handlers_memory_coverage.py index 99150c850f8..8b5b6135098 100644 --- a/test/test_handlers_memory_coverage.py +++ b/test/test_handlers_memory_coverage.py @@ -33,7 +33,7 @@ _MOD = "kiro_crew.dashboard.handlers.memory" -_CRED = "AKIAIOSFODNN7EXAMPLE" +_CRED = "glpat-IOSFODNN7EXAMPLE" class _BadJSON: diff --git a/test/test_heartbeat_prompt_deliver.py b/test/test_heartbeat_prompt_deliver.py index 7a98720e95e..4c6ea6aef6b 100644 --- a/test/test_heartbeat_prompt_deliver.py +++ b/test/test_heartbeat_prompt_deliver.py @@ -322,8 +322,8 @@ async def test_traceback_is_redacted(self, caplog): caplog.set_level(logging.ERROR) async def leaky(): - # AKIA-prefixed key is a recognized credential pattern - raise RuntimeError("creds leaked: AKIAIOSFODNN7EXAMPLE") + # glpat--prefixed key is a recognized credential pattern + raise RuntimeError("creds leaked: glpat-IOSFODNN7EXAMPLE") task = asyncio.create_task(leaky()) try: @@ -335,7 +335,7 @@ async def leaky(): assert "Background task failed" in log_output # Recognized credential pattern must not appear anywhere in the log output # (including in the traceback frames, not just the exception message). - assert "AKIAIOSFODNN7EXAMPLE" not in log_output + assert "glpat-IOSFODNN7EXAMPLE" not in log_output assert "[REDACTED: credential]" in log_output @pytest.mark.asyncio() diff --git a/test/test_heartbeat_safe_tools.py b/test/test_heartbeat_safe_tools.py index dc13cef4a95..a0d278a4de1 100644 --- a/test/test_heartbeat_safe_tools.py +++ b/test/test_heartbeat_safe_tools.py @@ -587,7 +587,7 @@ async def test_dashboard_log_warning_redacts_llm_title( monkeypatch.setattr("kiro_crew.slack.gateway.sel", lambda: sel_mock) # Title carries an AWS access key (a polled CR comment or ticket # body could mention one, and the tool-name path is LLM-controlled). - bad_title = "tool_with_secret AKIAIOSFODNN7EXAMPLE inside" + bad_title = "tool_with_secret glpat-IOSFODNN7EXAMPLE inside" event = _make_event(bad_title) with caplog.at_level(logging.WARNING, logger="kiro_crew.slack.gateway"): await orchestrator._heartbeat_approval(event) @@ -595,7 +595,7 @@ async def test_dashboard_log_warning_redacts_llm_title( # by this callback — redact_credentials should have replaced it. for record in caplog.records: assert ( - "AKIAIOSFODNN7EXAMPLE" not in record.getMessage() + "glpat-IOSFODNN7EXAMPLE" not in record.getMessage() ), f"Unredacted credential leaked into log: {record.getMessage()}" @pytest.mark.asyncio diff --git a/test/test_history_auto_skills.py b/test/test_history_auto_skills.py index df062f3eebe..04497c2127c 100644 --- a/test/test_history_auto_skills.py +++ b/test/test_history_auto_skills.py @@ -297,7 +297,7 @@ async def fake_llm(_prompt, *, memory_store: str = "", session_key: str = ""): "triggers": "thing, procedure", "procedure_md": ( "## Steps\n" - "1. Use AKIAIOSFODNN7EXAMPLE as the key\n" + "1. Use glpat-IOSFODNN7EXAMPLE as the key\n" "2. Run `aws sts get-caller-identity`\n" ), }, @@ -309,8 +309,8 @@ async def fake_llm(_prompt, *, memory_store: str = "", session_key: str = ""): skill_file = tmp_path / "skills" / "auto" / "poison-skill" / "SKILL.md" assert skill_file.exists() content = skill_file.read_text(encoding="utf-8") - # AKIA prefix must NOT survive to disk - assert "AKIAIOSFODNN7EXAMPLE" not in content + # glpat- prefix must NOT survive to disk + assert "glpat-IOSFODNN7EXAMPLE" not in content @pytest.mark.asyncio async def test_similarity_dedup_skips_near_duplicate(self, tmp_path): diff --git a/test/test_history_retention.py b/test/test_history_retention.py index 85161c88d3a..e2661f0bf61 100644 --- a/test/test_history_retention.py +++ b/test/test_history_retention.py @@ -399,7 +399,7 @@ async def test_read_redacts_credentials_and_urls(self, archive_dir): leaky = archive_dir / "leak__20260104-000000.jsonl" leaky.write_text( '{"_type":"archive","reason":"rotate","count":1}\n' - '{"role":"user","content":"here is AKIAIOSFODNN7EXAMPLE my key"}\n' + '{"role":"user","content":"here is glpat-IOSFODNN7EXAMPLE my key"}\n' ) app = self._make_app() async with TestClient(TestServer(app)) as client: @@ -407,7 +407,7 @@ async def test_read_redacts_credentials_and_urls(self, archive_dir): assert resp.status == 200 body = await resp.text() # Raw credential must not appear in the response - assert "AKIAIOSFODNN7EXAMPLE" not in body + assert "glpat-IOSFODNN7EXAMPLE" not in body class TestArchiveOnlyDropped: diff --git a/test/test_image_artifacts.py b/test/test_image_artifacts.py index e5cbb63b392..cb6622445cc 100644 --- a/test/test_image_artifacts.py +++ b/test/test_image_artifacts.py @@ -199,7 +199,7 @@ def test_serialize_redacts_llm_derived_image_metadata( """ from kiro_crew.dashboard.handlers.artifacts import _serialize - leak = "AKIAIOSFODNN7EXAMPLE" + leak = "glpat-IOSFODNN7EXAMPLE" art = store.create_image( name=f"pic {leak}", image_bytes=_png_bytes(4, 4), diff --git a/test/test_imessage_renderer.py b/test/test_imessage_renderer.py index 21adf7f7ab8..9bed6e80bbb 100644 --- a/test/test_imessage_renderer.py +++ b/test/test_imessage_renderer.py @@ -355,21 +355,21 @@ class TestFlattenedCredentialIsRedacted: async def test_emphasis_split_key_does_not_survive_flattening(self) -> None: client = FakeClient() renderer = _renderer(client) - await renderer.on_text_chunk("key **AKIA**IOSFODNN7EXAMPLE ok") + await renderer.on_text_chunk("key **glpat-**IOSFODNN7EXAMPLE ok") # The raw markdown is what the driver's byte scan saw: still split, so # the literal pattern could not match it. - assert "**AKIA**IOSFODNN7EXAMPLE" in renderer.text() + assert "**glpat-**IOSFODNN7EXAMPLE" in renderer.text() # The form that actually ships must not contain the reassembled key. delivered = renderer.delivery_text() - assert "AKIAIOSFODNN7EXAMPLE" not in delivered + assert "glpat-IOSFODNN7EXAMPLE" not in delivered @pytest.mark.asyncio async def test_code_span_split_key_does_not_survive_flattening(self) -> None: client = FakeClient() renderer = _renderer(client) - await renderer.on_text_chunk("`AKIA`IOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in renderer.delivery_text() + await renderer.on_text_chunk("`glpat-`IOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in renderer.delivery_text() @pytest.mark.asyncio async def test_credential_reassembled_through_link_grammar_is_caught(self) -> None: @@ -377,8 +377,8 @@ async def test_credential_reassembled_through_link_grammar_is_caught(self) -> No # across the label/target boundary, so the byte scan sees no key at all. client = FakeClient() renderer = _renderer(client) - await renderer.on_text_chunk("[AKIA](https://x.example)IOSFODNN7EXAMPLE") - assert "AKIAIOSFODNN7EXAMPLE" not in renderer.delivery_text() + await renderer.on_text_chunk("[glpat-](https://x.example)IOSFODNN7EXAMPLE") + assert "glpat-IOSFODNN7EXAMPLE" not in renderer.delivery_text() @pytest.mark.asyncio async def test_ordinary_prose_is_delivered_unchanged(self) -> None: diff --git a/test/test_inbound_unbind_notice.py b/test/test_inbound_unbind_notice.py index 9b8ecdb4955..804e999ef92 100644 --- a/test/test_inbound_unbind_notice.py +++ b/test/test_inbound_unbind_notice.py @@ -297,7 +297,7 @@ class TestNoticeIsSafeAndHuman: # test_security.py. A well-formed S3 presigned URL is deliberately exempt # (``_is_safe_presigned``), so the URL below carries a fixed credential in its # query instead — the shape ``_exfil_url_warning`` classifies unconditionally. - AWS_KEY_ID = "AKIA" "IOSFODNN7EXAMPLE" + AWS_KEY_ID = "glpat-" "IOSFODNN7EXAMPLE" EXFIL_URL = ( "https://evil.example.com/collect?t=" + "ghp_" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef12" ) diff --git a/test/test_instances_proxy_handler.py b/test/test_instances_proxy_handler.py index 13ad980b38e..91d7cbefc74 100644 --- a/test/test_instances_proxy_handler.py +++ b/test/test_instances_proxy_handler.py @@ -360,7 +360,7 @@ class TestProxyRedactsPeerReplies: the read-path redaction point: a credential the peer emits never reaches the browser, in a JSON body or in an SSE frame.""" - SECRET = "AKIAIOSFODNN7EXAMPLE" + SECRET = "glpat-IOSFODNN7EXAMPLE" def _req(self, tmp_path, monkeypatch, *, path, chunks, content_type): _enable(tmp_path, monkeypatch) @@ -420,7 +420,7 @@ async def test_json_body_strings_are_redacted(self, tmp_path, monkeypatch): async def test_json_escape_cannot_hide_a_secret(self, tmp_path, monkeypatch): from kiro_crew.dashboard.handlers_instances import api_instances_proxy - hidden = '{"content": "\\u0041' + self.SECRET[1:] + '"}' + hidden = '{"content": "' + ("\\u%04x" % ord(self.SECRET[0])) + self.SECRET[1:] + '"}' req = self._req( tmp_path, monkeypatch, @@ -451,7 +451,7 @@ async def test_too_deeply_nested_json_is_refused_not_forwarded(self, tmp_path, m async def test_a_leading_bom_cannot_hide_an_escaped_secret(self, tmp_path, monkeypatch): from kiro_crew.dashboard.handlers_instances import api_instances_proxy - body = '\ufeff{"content": "\\u0041' + self.SECRET[1:] + '"}' + body = '\ufeff{"content": "' + ("\\u%04x" % ord(self.SECRET[0])) + self.SECRET[1:] + '"}' req = self._req( tmp_path, monkeypatch, @@ -466,7 +466,14 @@ async def test_a_leading_bom_cannot_hide_an_escaped_secret(self, tmp_path, monke async def test_json_python_cannot_decode_is_refused_not_forwarded(self, tmp_path, monkeypatch): from kiro_crew.dashboard.handlers_instances import api_instances_proxy - body = '{"n": ' + "9" * 5000 + ', "content": "\\u0041' + self.SECRET[1:] + '"}' + body = ( + '{"n": ' + + "9" * 5000 + + ', "content": "' + + ("\\u%04x" % ord(self.SECRET[0])) + + self.SECRET[1:] + + '"}' + ) req = self._req( tmp_path, monkeypatch, @@ -537,13 +544,14 @@ class TestRedactSseEvent: """The browser joins an event's data lines before parsing, so redaction must see the joined payload, whatever the line ending.""" - SECRET = "AKIA" + "IOSFODNN7EXAMPLE" + SECRET = "glpat-" + "IOSFODNN7EXAMPLE" def test_secret_split_over_data_lines_behind_an_escape_is_redacted(self): from kiro_crew.dashboard.handlers_instances import _redact_sse_event event = ( - 'event: chat_message\ndata: {"slot": "s1",\ndata: "content": "\\u0041' + 'event: chat_message\ndata: {"slot": "s1",\ndata: "content": "' + + ("\\u%04x" % ord(self.SECRET[0])) + self.SECRET[1:] + '"}' ).encode() @@ -573,7 +581,9 @@ async def write(self, chunk): async def write_eof(self): return None - payload = ('data: {"c": "\\u0041' + self.SECRET[1:] + '"}\n\n').encode() + payload = ( + 'data: {"c": "' + ("\\u%04x" % ord(self.SECRET[0])) + self.SECRET[1:] + '"}\n\n' + ).encode() stream = b"\xef\xbb\xbf" + payload req = TestProxyRedactsPeerReplies()._req( tmp_path, @@ -607,7 +617,9 @@ async def write(self, chunk): async def write_eof(self): return None - stream = ('data: {"a":\rdata: "\\u0041' + self.SECRET[1:] + '"}\r\r').encode() + stream = ( + 'data: {"a":\rdata: "' + ("\\u%04x" % ord(self.SECRET[0])) + self.SECRET[1:] + '"}\r\r' + ).encode() req = TestProxyRedactsPeerReplies()._req( tmp_path, monkeypatch, diff --git a/test/test_instances_remote_update.py b/test/test_instances_remote_update.py index f00b7632e43..deb5a27d527 100644 --- a/test/test_instances_remote_update.py +++ b/test/test_instances_remote_update.py @@ -679,7 +679,7 @@ class TestRunnerStdoutTail: def test_the_ssh_runner_appends_a_redacted_stdout_tail_only_when_asked(self, monkeypatch): from kiro_crew.instances import token_mint as tm - secret = "AKIA" + "ABCDEFGHIJKLMNOP" + secret = "glpat-" + "ABCDEFGHIJKLMNOP" class _Proc: returncode = 1 @@ -706,7 +706,7 @@ def test_the_ssm_runner_appends_a_redacted_stdout_tail_only_when_asked(self, mon from kiro_crew.cloud.ssm import CommandResult from kiro_crew.instances import ssm_token_mint as sm - secret = "AKIA" + "ABCDEFGHIJKLMNOP" + secret = "glpat-" + "ABCDEFGHIJKLMNOP" async def _send(*_a, **_k): return CommandResult( diff --git a/test/test_instances_search_federation.py b/test/test_instances_search_federation.py index 81446ebdf23..d16ffd476a1 100644 --- a/test/test_instances_search_federation.py +++ b/test/test_instances_search_federation.py @@ -322,7 +322,7 @@ async def test_redacts_credentials_in_peer_titles_and_snippets(self, monkeypatch """Defense in depth: a peer's rows are re-redacted locally even though a well-behaved peer already redacted them.""" _enable_instances(monkeypatch) - secret = "AKIAIOSFODNN7EXAMPLE" + secret = "glpat-IOSFODNN7EXAMPLE" mgr = _Mgr({"a": (True, {"sessions": [{"key": "r", "title": f"creds {secret}"}]})}) state = _state([], mgr) diff --git a/test/test_instances_token_mint.py b/test/test_instances_token_mint.py index 41404db46e6..70dcac32f43 100644 --- a/test/test_instances_token_mint.py +++ b/test/test_instances_token_mint.py @@ -529,7 +529,7 @@ class FakeProc: returncode = 255 async def communicate(self): - return b"", b"WSSH error AKIAIOSFODNN7EXAMPLE banner" + return b"", b"WSSH error glpat-IOSFODNN7EXAMPLE banner" async def fake_exec(*a, **k): return FakeProc() @@ -537,7 +537,7 @@ async def fake_exec(*a, **k): monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_exec) rc, err = asyncio.run(tm.run_remote_kirocrew("cd-1", "restart")) assert rc == 255 - assert "AKIAIOSFODNN7EXAMPLE" not in err + assert "glpat-IOSFODNN7EXAMPLE" not in err assert "[REDACTED: credential]" in err def test_run_remote_kirocrew_redacts_urls_before_credentials(self, monkeypatch): @@ -557,7 +557,7 @@ class FakeProc: returncode = 255 async def communicate(self): - return b"", b"banner https://evil.example.com/x?token=AKIAIOSFODNN7EXAMPLE end" + return b"", b"banner https://evil.example.com/x?token=glpat-IOSFODNN7EXAMPLE end" async def fake_exec(*a, **k): return FakeProc() @@ -570,7 +570,7 @@ async def fake_exec(*a, **k): # order the URL survives as https://evil.example.com/x?token=[...]. assert "https://evil.example.com" not in err assert "[REDACTED: suspicious URL" in err - assert "AKIAIOSFODNN7EXAMPLE" not in err + assert "glpat-IOSFODNN7EXAMPLE" not in err def test_stdout_tail_url_pass_not_disarmed_by_token_prescrub(self, monkeypatch): """The stdout-tail site has a second disarm path — its own @@ -582,7 +582,7 @@ def test_stdout_tail_url_pass_not_disarmed_by_token_prescrub(self, monkeypatch): """ from kiro_crew.instances import token_mint as tm - stdout = b"fail: see https://evil.example.com/x?token=AKIAIOSFODNN7EXAMPLE now" + stdout = b"fail: see https://evil.example.com/x?token=glpat-IOSFODNN7EXAMPLE now" class FakeProc: returncode = 1 @@ -599,7 +599,7 @@ async def fake_exec(*a, **k): msg = str(excinfo.value) assert "https://evil.example.com" not in msg assert "[REDACTED: suspicious URL" in msg - assert "AKIAIOSFODNN7EXAMPLE" not in msg + assert "glpat-IOSFODNN7EXAMPLE" not in msg class _HangProc: """First ``communicate`` times out; the reap (a SECOND communicate) diff --git a/test/test_issue_radar_crew_mcp_tools.py b/test/test_issue_radar_crew_mcp_tools.py index 83d316babc0..90a0f0e7331 100644 --- a/test/test_issue_radar_crew_mcp_tools.py +++ b/test/test_issue_radar_crew_mcp_tools.py @@ -838,10 +838,10 @@ class TestPublicStringsAreSanitizedOnTheWayIn(unittest.TestCase): def test_a_credential_quoted_into_a_progress_line_is_not_published(self): captured, _ = _record( - event="log had AKIAIOSFODNN7EXAMPLE in it", + event="log had glpat-IOSFODNN7EXAMPLE in it", event_kind="investigate", ) - assert "AKIAIOSFODNN7EXAMPLE" not in captured["body"]["event"] + assert "glpat-IOSFODNN7EXAMPLE" not in captured["body"]["event"] def test_a_credential_in_the_pass_reason_is_not_stored(self): """``why`` is what the shared skip index keeps as the reason. @@ -855,11 +855,11 @@ def test_a_credential_in_the_pass_reason_is_not_stored(self): captured, _ = _record( phase="skipped", skip_scope="needs-decision", - why="the failing config had AKIAIOSFODNN7EXAMPLE hardcoded", + why="the failing config had glpat-IOSFODNN7EXAMPLE hardcoded", event="passed: needs a decision on the credential", event_kind="skip", ) - assert "AKIAIOSFODNN7EXAMPLE" not in captured["body"]["why"] + assert "glpat-IOSFODNN7EXAMPLE" not in captured["body"]["why"] def test_the_home_directory_is_scrubbed_from_a_progress_line(self): # Redaction alone covers credentials and exfil URLs, NOT paths — and a @@ -922,8 +922,8 @@ def test_the_local_worktree_path_is_not_scrubbed(self): assert captured["body"]["worktree"] == worktree def test_a_label_carrying_a_credential_is_not_persisted(self): - captured, _ = _record(labels_applied=["crew: in progress", "AKIAIOSFODNN7EXAMPLE"]) - assert "AKIAIOSFODNN7EXAMPLE" not in captured["body"]["labels_applied"][1] + captured, _ = _record(labels_applied=["crew: in progress", "glpat-IOSFODNN7EXAMPLE"]) + assert "glpat-IOSFODNN7EXAMPLE" not in captured["body"]["labels_applied"][1] def test_removing_the_last_label_is_forwarded_as_an_empty_list(self): """`labels_applied: []` means "I now hold none", not "I did not say". diff --git a/test/test_lesson_contradiction.py b/test/test_lesson_contradiction.py index e49d4b0b409..e80c6510794 100644 --- a/test/test_lesson_contradiction.py +++ b/test/test_lesson_contradiction.py @@ -1355,7 +1355,7 @@ async def test_credential_bearing_rule_is_redacted(self): "key": "lesson.y", "value_json": json.dumps( { - "rule": "use key AKIAIOSFODNN7EXAMPLE for the bucket", + "rule": "use key glpat-IOSFODNN7EXAMPLE for the bucket", "category": "tool", "negative": None, } @@ -1364,7 +1364,7 @@ async def test_credential_bearing_rule_is_redacted(self): } ] lessons = await self._get(rows) - assert "AKIAIOSFODNN7EXAMPLE" not in lessons[0]["rule"] + assert "glpat-IOSFODNN7EXAMPLE" not in lessons[0]["rule"] assert lessons[0]["category"] == "tool" async def test_credential_bearing_category_is_redacted(self): @@ -1376,7 +1376,7 @@ async def test_credential_bearing_category_is_redacted(self): "value_json": json.dumps( { "rule": "a rule", - "category": "token AKIAIOSFODNN7EXAMPLE", + "category": "token glpat-IOSFODNN7EXAMPLE", "negative": None, } ), @@ -1384,7 +1384,7 @@ async def test_credential_bearing_category_is_redacted(self): } ] lessons = await self._get(rows) - assert "AKIAIOSFODNN7EXAMPLE" not in lessons[0]["category"] + assert "glpat-IOSFODNN7EXAMPLE" not in lessons[0]["category"] async def test_non_string_jsonl_rule_does_not_crash(self): """The JSONL fallback branch: ``load_all`` builds Lesson rows without diff --git a/test/test_markdown_link_parentheses.py b/test/test_markdown_link_parentheses.py index ca9c227431e..a0cb1998252 100644 --- a/test/test_markdown_link_parentheses.py +++ b/test/test_markdown_link_parentheses.py @@ -94,14 +94,14 @@ def _label_class(link_pattern: re.Pattern[str]) -> str: class TestRendererLabelsAreNoWiderThanTheScreens: """The screen's label admits no ``[``, ``]`` or line break. A renderer whose - label class admitted them linked ``AKIA[IOSF...[z](u)`` from the first ``[`` - and showed ``AKIAIOSF...`` joined, while the screen saw only the inner link + label class admitted them linked ``glpat-[IOSF...[z](u)`` from the first ``[`` + and showed ``glpat-IOSF...`` joined, while the screen saw only the inner link ``[z](u)`` collapse and scanned the key as split. Telegram's fallback did the same across a newline in the label. """ - _OPUS_SLACK_SHAPE = f"AKIA[{_KEY[4:]}[z](https://u)" - _TELEGRAM_NEWLINE_SHAPE = f"AKIA[{_KEY[4:]}\nfoo](https://u)" + _OPUS_SLACK_SHAPE = f"glpat-[{_KEY[6:]}[z](https://u)" + _TELEGRAM_NEWLINE_SHAPE = f"glpat-[{_KEY[6:]}\nfoo](https://u)" @pytest.mark.parametrize("renderer", sorted(_RENDERER_LINK_PATTERNS)) def test_the_label_class_is_the_screens(self, renderer): @@ -112,7 +112,7 @@ def test_slack_never_joins_a_key_around_a_bracket_in_the_label(self): assert _KEY not in canonicalize_display(payload) assert redact_for_display(payload, _default_redactor) == (payload, False) rendered = _slack(payload) - assert rendered == f"AKIA[{_KEY[4:]}" + assert rendered == f"glpat-[{_KEY[6:]}" assert _KEY not in canonicalize_display(rendered) def test_telegram_never_joins_a_key_around_a_newline_in_the_label(self): @@ -123,11 +123,11 @@ def test_telegram_never_joins_a_key_around_a_newline_in_the_label(self): def test_whatsapp_never_joins_a_key_around_a_bracket_in_the_label(self): payload = self._OPUS_SLACK_SHAPE - assert to_whatsapp_text(payload) == f"AKIA[{_KEY[4:]}z (https://u)" + assert to_whatsapp_text(payload) == f"glpat-[{_KEY[6:]}z (https://u)" def test_imessage_never_joins_a_key_around_a_bracket_in_the_label(self): payload = self._OPUS_SLACK_SHAPE - assert to_plaintext(payload) == f"AKIA[{_KEY[4:]}z (https://u)" + assert to_plaintext(payload) == f"glpat-[{_KEY[6:]}z (https://u)" def test_a_bracket_before_the_label_stays_text(self): """``[x[y](u)`` is ``[x`` followed by a link labelled ``y``.""" @@ -217,7 +217,7 @@ class TestTheFallbackKeepsRedactionTagsWhole: """ _OPAQUE_TOKEN_URL = "https://example.com/cb?token=q7Zt3mVx9pLw2Kd8" - _PAST_THE_BOUND = f"{_URL_SPLIT_TRIGGER} {_nested_link(DISPLAY_SETTLING_PASSES + 2)}{_KEY[4:]}" + _PAST_THE_BOUND = f"{_URL_SPLIT_TRIGGER} {_nested_link(DISPLAY_SETTLING_PASSES + 2)}{_KEY[6:]}" def test_the_tag_pattern_matches_every_tag_the_redactor_writes(self): for tag in ( @@ -254,13 +254,13 @@ def test_a_suspicious_url_tag_keeps_its_brackets_past_the_bound(self): @pytest.mark.parametrize("depth", [6, 9]) def test_the_existing_deep_nesting_cases_redact_to_themselves(self, depth): - payload = f"{_URL_SPLIT_TRIGGER} {_nested_link(depth)}{_KEY[4:]}" + payload = f"{_URL_SPLIT_TRIGGER} {_nested_link(depth)}{_KEY[6:]}" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True assert _default_redactor(safe) == safe def test_a_key_split_by_markup_on_the_fallback_path_is_still_redacted(self): - payload = f"{self._PAST_THE_BOUND} AKIA**{_KEY[4:]}**" + payload = f"{self._PAST_THE_BOUND} glpat-**{_KEY[6:]}**" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True assert _KEY not in safe @@ -295,7 +295,7 @@ class TestTheWholeTextFallbackKeepsRemovedRedactionTags: _URL = "https://evil.example/c?d=QUtJQUlPU0ZPRE5ON0VYQU1QTEVfc2VjcmV0X2RhdGFfaGVyZQ" def test_the_display_screen_keeps_a_suspicious_url_tag_hidden_by_a_link(self): - payload = f"AKIA[]({self._URL}){_KEY[4:]}" + payload = f"glpat-[]({self._URL}){_KEY[6:]}" suspicious_url_tag = _default_redactor(self._URL) safe, redacted = redact_for_display(payload, _default_redactor) @@ -307,7 +307,7 @@ def test_the_display_screen_keeps_a_suspicious_url_tag_hidden_by_a_link(self): assert not any(_KEY in reading for reading in _screen_readings(safe)) def test_discord_keeps_a_suspicious_url_tag_hidden_by_a_link(self): - payload = f"AKIA[]({self._URL}){_KEY[4:]}" + payload = f"glpat-[]({self._URL}){_KEY[6:]}" suspicious_url_tag = _default_redactor(self._URL) delivered = discord_redact_transformed(payload) @@ -318,7 +318,7 @@ def test_discord_keeps_a_suspicious_url_tag_hidden_by_a_link(self): assert not any(_KEY in reading for reading in _screen_readings(delivered)) def test_an_existing_credential_tag_hidden_by_a_link_is_delivered(self): - payload = f"AKIA[]({_TAG}){_KEY[4:]}" + payload = f"glpat-[]({_TAG}){_KEY[6:]}" safe, redacted = redact_for_display(payload, _default_redactor) @@ -344,7 +344,7 @@ class TestATagFollowedByAParenthesisIsNotALink: @pytest.mark.parametrize("remark", _REMARKS) @pytest.mark.parametrize("pair", ["||", "**"]) def test_the_discord_path_keeps_the_tag_and_the_remark(self, pair, remark): - payload = f"AKIA{pair}{_KEY[4:]}{pair}{remark}" + payload = f"glpat-{pair}{_KEY[6:]}{pair}{remark}" delivered = discord_redact_transformed(payload) assert delivered == f"{_TAG}{remark}" _tag_kept_whole(delivered, 1, remark) @@ -352,23 +352,23 @@ def test_the_discord_path_keeps_the_tag_and_the_remark(self, pair, remark): @pytest.mark.parametrize("remark", _REMARKS) @pytest.mark.parametrize("pair", ["||", "**"]) def test_the_display_screen_keeps_the_tag_and_the_remark(self, pair, remark): - payload = f"AKIA{pair}{_KEY[4:]}{pair}{remark}" + payload = f"glpat-{pair}{_KEY[6:]}{pair}{remark}" safe, redacted = redact_for_display(payload, _credentials_only) assert redacted is True assert safe == f"{_TAG}{remark}" _tag_kept_whole(safe, 1, remark) def test_a_tag_the_literal_scan_wrote_survives_the_canonical_branch(self): - payload = f"{_KEY}(x) AKIA**{_KEY[4:]}**" + payload = f"{_KEY}(x) glpat-**{_KEY[6:]}**" safe, redacted = redact_for_display(payload, _credentials_only) assert redacted is True assert safe == f"{_TAG}(x) {_TAG}" _tag_kept_whole(safe, 2, "(x)") def test_a_tag_the_literal_scan_wrote_survives_a_further_reading(self): - """Only the plain fallback joins ``AKIA[rest]**(https://u)**``; the tag + """Only the plain fallback joins ``glpat-[rest]**(https://u)**``; the tag written before it must not go with the answer to that reading.""" - payload = f"{_KEY}(https://x) AKIA[{_KEY[4:]}]**(https://u)**" + payload = f"{_KEY}(https://x) glpat-[{_KEY[6:]}]**(https://u)**" assert _KEY not in canonicalize_display(_credentials_only(payload)) safe, redacted = redact_for_display(payload, _credentials_only) assert redacted is True @@ -412,19 +412,19 @@ def test_a_delimiter_pass_cannot_hand_the_link_pass_a_tag(self, wrap): @pytest.mark.parametrize("wrap", _REMARK_WRAPS) def test_a_key_beside_a_wrapped_remark_keeps_its_tag_on_discord(self, wrap): - payload = f"AKIA||{_KEY[4:]}||{wrap.format('(x)')}" + payload = f"glpat-||{_KEY[6:]}||{wrap.format('(x)')}" delivered = discord_redact_transformed(payload) assert delivered.startswith(_TAG), delivered _tag_kept_whole(delivered, 1, "(x)") def test_a_key_joined_only_across_a_tag_is_still_redacted(self): - """``AKIA[]([REDACTED: credential])REST`` shows the key on a reader that + """``glpat-[]([REDACTED: credential])REST`` shows the key on a reader that collapses the empty-labelled link, and the tag sat inside that link. The reading's redacted form is emitted, so the key is hidden and both input keys are counted.""" - payload = f"AKIA[]({_KEY}){_KEY[4:]}" + payload = f"glpat-[]({_KEY}){_KEY[6:]}" literal = _credentials_only(payload) - assert literal == f"AKIA[]({_TAG}){_KEY[4:]}" + assert literal == f"glpat-[]({_TAG}){_KEY[6:]}" assert canonicalize_display(literal) == _KEY safe, redacted = redact_for_display(payload, _credentials_only) assert redacted is True @@ -436,7 +436,7 @@ def test_a_key_joined_only_across_a_tag_is_still_redacted(self): class TestAnEscapedBackslashClosesWhereTheWalkerCloses: """``\\\\`` before ``)`` is an escaped backslash, not an escaped parenthesis. - ``[AKIA](https://x/a\\\\)REST`` is a link to a CommonMark reader, to the + ``[glpat-](https://x/a\\\\)REST`` is a link to a CommonMark reader, to the extraction walker and to Slack: the pair is one escape and the ``)`` after it closes the destination. A unit that refused every backslash before a parenthesis left it raw, so the screen collapsed nothing and the joined key @@ -447,9 +447,9 @@ class TestAnEscapedBackslashClosesWhereTheWalkerCloses: @pytest.mark.parametrize( "payload", [ - f"[AKIA](https://x/a\\\\){_KEY[4:]}", - f"[AKIA](https://x/a\\\\\\\\){_KEY[4:]}", - f"[AKIA](https://x/a\\\\(b)){_KEY[4:]}", + f"[glpat-](https://x/a\\\\){_KEY[6:]}", + f"[glpat-](https://x/a\\\\\\\\){_KEY[6:]}", + f"[glpat-](https://x/a\\\\(b)){_KEY[6:]}", ], ) def test_a_key_split_around_an_escaped_backslash_is_redacted(self, payload): @@ -484,19 +484,19 @@ def test_an_escaped_parenthesis_still_stays_as_written(self, source): class TestAnEscapedBracketIsNotANestedOpener: - """``[AKIA](https://x/\\[b](c))REST`` is one link wherever a reader honours the + """``[glpat-](https://x/\\[b](c))REST`` is one link wherever a reader honours the escape: ``\\[`` is an escaped bracket, so no ``[label](`` opens inside the url, and the balanced ``(c)`` sits inside it. A unit that consumed the backslash on its own re-read the ``[`` after it as a nested opener and refused the url, so the outer link stayed raw, the inner ``[b](c)`` collapsed instead, and the screen - scanned a text that held no key while Discord showed ``AKIAREST`` joined. The + scanned a text that held no key while Discord showed ``glpat-REST`` joined. The escape and its escapee are one token, so the unit closes where the walker closes and the outer link collapses to its label. """ @pytest.mark.parametrize("destination", _ESCAPED_BRACKET_DESTINATIONS) def test_a_key_split_around_an_escaped_bracket_is_redacted(self, destination): - payload = f"[AKIA]({destination}){_KEY[4:]}" + payload = f"[glpat-]({destination}){_KEY[6:]}" assert canonicalize_display(payload) == _KEY safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True @@ -507,7 +507,7 @@ def test_a_key_split_around_an_escaped_bracket_is_redacted(self, destination): def test_the_discord_send_path_redacts_it(self, destination): """The literal text never holds the key; what Discord shows does, so the sent text is judged by its rendered form.""" - payload = f"[AKIA]({destination}){_KEY[4:]}" + payload = f"[glpat-]({destination}){_KEY[6:]}" sent = discord_redact_transformed(payload) assert sent != payload assert all(_KEY not in reading for reading in _every_reading(sent)) @@ -538,8 +538,8 @@ def test_the_unit_closes_where_the_walker_closes(self, destination): @pytest.mark.parametrize( "payload", [ - f"[AKIA](https://x/a\\)b){_KEY[4:]}", - f"[AKIA](https://x/\\(a){_KEY[4:]}", + f"[glpat-](https://x/a\\)b){_KEY[6:]}", + f"[glpat-](https://x/\\(a){_KEY[6:]}", ], ) def test_an_escaped_parenthesis_is_still_refused(self, payload): @@ -550,7 +550,7 @@ def test_an_escaped_parenthesis_is_still_refused(self, payload): def test_an_unescaped_nested_opener_is_still_refused(self): """The refusal ``\\[`` bypasses still holds for a bare ``[label](``.""" - payload = f"[x](a[AKIA](u){_KEY[4:]})" + payload = f"[x](a[glpat-](u){_KEY[6:]})" assert _KEY in canonicalize_display(payload) assert redact_for_display(payload, _default_redactor)[1] is True @@ -593,9 +593,9 @@ def _refused_link_shapes(heads: tuple[str, ...], tail_for) -> list[tuple[str, st _KEYED_REFUSED_LINK_SHAPES = _refused_link_shapes( - (_KEY[:4], _KEY[:8], _KEY[:13]), lambda head: _KEY[len(head) :] + (_KEY[:6], _KEY[:8], _KEY[:13]), lambda head: _KEY[len(head) :] ) -_KEYLESS_REFUSED_LINK_SHAPES = _refused_link_shapes((_KEY[:4],), lambda head: "rest") +_KEYLESS_REFUSED_LINK_SHAPES = _refused_link_shapes((_KEY[:6],), lambda head: "rest") def _every_reading(text: str) -> list[str]: @@ -617,8 +617,8 @@ def _every_reading(text: str) -> list[str]: class TestAnAngleBracketedDestinationCollapsesToItsLabel: - """``[AKIA]()IOSF...``: Discord reads ``<...>`` as the whole - destination, so the link shows ``AKIA`` and the reader sees the key joined + """``[glpat-]()IOSF...``: Discord reads ``<...>`` as the whole + destination, so the link shows ``glpat-`` and the reader sees the key joined to what follows. The parenthesis grammar refuses the unbalanced ``(`` inside the brackets and left the link raw, so the screen scanned the text as written and saw no key. The screen's link grammar has an angle-bracket @@ -628,11 +628,11 @@ class TestAnAngleBracketedDestinationCollapsesToItsLabel: @pytest.mark.parametrize("destination", _UNBALANCED_ANGLE_DESTINATIONS) def test_the_screen_links_it(self, destination): assert _MD_LINK.fullmatch(f"[l]({destination})") is None - assert display_safety._balanced_link_reading(f"[AKIA]({destination}){_KEY[4:]}") == _KEY + assert display_safety._balanced_link_reading(f"[glpat-]({destination}){_KEY[6:]}") == _KEY @pytest.mark.parametrize("destination", _UNBALANCED_ANGLE_DESTINATIONS) def test_a_key_split_around_it_is_redacted(self, destination): - payload = f"[AKIA]({destination}){_KEY[4:]}" + payload = f"[glpat-]({destination}){_KEY[6:]}" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True assert _KEY not in safe @@ -640,14 +640,14 @@ def test_a_key_split_around_it_is_redacted(self, destination): @pytest.mark.parametrize("destination", _UNBALANCED_ANGLE_DESTINATIONS) def test_the_discord_send_path_redacts_it(self, destination): - payload = f"[AKIA]({destination}){_KEY[4:]}" + payload = f"[glpat-]({destination}){_KEY[6:]}" sent = discord_redact_transformed(payload) assert sent != payload assert _KEY not in sent assert all(_KEY not in reading for reading in _every_reading(sent)) def test_the_finding_shape_verbatim(self): - payload = "[AKIA]()IOSFODNN7EXAMPLE" + payload = "[glpat-]()IOSFODNN7EXAMPLE" assert discord_redact_transformed(payload) == CREDENTIAL_REDACTION_TAGS[0] @pytest.mark.parametrize("destination", _UNBALANCED_ANGLE_DESTINATIONS) @@ -656,7 +656,7 @@ def test_a_key_split_by_a_pair_inside_it_is_still_scanned(self, destination): links stays text under the no-parenthesis-group reading, where the emphasis pass joins a key a ``~~`` pair split inside it, as it did before the branch.""" inner = destination[1:-1] - payload = f"[l](<{inner}/AKIA~~{_KEY[4:]}~~>)" + payload = f"[l](<{inner}/glpat-~~{_KEY[6:]}~~>)" assert _KEY in display_safety._link_free_reading(payload) safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True @@ -664,10 +664,10 @@ def test_a_key_split_by_a_pair_inside_it_is_still_scanned(self, destination): assert all(_KEY not in reading for reading in _every_reading(safe)) def test_the_parenthesis_grammar_still_closes_first(self): - """``[AKIA]()`` is a link to ``)`` is a link to ``)" + payload = f"[glpat-]()" assert canonicalize_display(payload) == f"{_KEY}>)" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True @@ -679,7 +679,7 @@ def test_no_renderer_shows_a_key_it_leaves_raw(self, destination): destination: each leaves the text as written, or shows the url beside the label, so no reader of theirs sees the key joined and the renderers keep the shared destination unit as it is.""" - payload = f"[AKIA]({destination}){_KEY[4:]}" + payload = f"[glpat-]({destination}){_KEY[6:]}" assert _KEY not in _slack_reader_sees(_slack(payload)) assert _KEY not in html.unescape(_md_to_telegram_html(payload)) assert _KEY not in _strip_md(payload) @@ -714,17 +714,17 @@ def reject(text: str) -> None: class TestAKeyJoinedByALinkTheCanonicalGrammarRefuses: - """``AKIA[IOSF...](https://ex.com/p\\)q)`` is no link to the canonical grammar, + """``glpat-[IOSF...](https://ex.com/p\\)q)`` is no link to the canonical grammar, which refuses an unescaped backslash before ``)``, so the canonical form is the text as written and scans as split. The grammar admitting no parenthesis group closes at that ``)`` and joins the key, as a CommonMark reader does when it - shows ``AKIA`` beside the label. A reading that reveals a key has to be scanned + shows ``glpat-`` beside the label. A reading that reveals a key has to be scanned whether or not the canonical form differs from the text, and the answer has to carry no key: the canonical redacted form is the text itself here, so the redacted reading is emitted instead. """ - _REPORTED = f"AKIA[{_KEY[4:]}](https://ex.com/p\\)q)" + _REPORTED = f"glpat-[{_KEY[6:]}](https://ex.com/p\\)q)" def test_the_reported_input_is_redacted_under_the_balanced_reading(self): assert redact_for_display(self._REPORTED, _default_redactor) == ( @@ -741,7 +741,7 @@ def test_unrelated_emphasis_does_not_hand_back_the_raw_link(self): assert all(_KEY not in reading for reading in _every_reading(safe)) def test_a_url_the_canonical_grammar_links_still_answers_with_the_canonical_form(self): - payload = f"[l](https://x/(a)/AKIA~~{_KEY[4:]}~~)" + payload = f"[l](https://x/(a)/glpat-~~{_KEY[6:]}~~)" assert redact_for_display(payload, _default_redactor) == ("l", True) def test_every_generated_key_shape_is_covered_by_a_reading(self): @@ -778,7 +778,7 @@ def test_the_same_shape_without_a_key_passes_through_byte_identical(self, case_n #: A second key, distinct from ``_KEY``, so one text can carry a key one reading #: joins beside a key another reading joins. -_SECOND_KEY = "ASIA" + _KEY[4:] +_SECOND_KEY = "sk-ant-" + _KEY[6:] def _shows_a_key(text: str) -> bool: @@ -786,26 +786,26 @@ def _shows_a_key(text: str) -> bool: def _keyed(text: str) -> str: - return text.replace(_KEY[:4], _SECOND_KEY[:4]) + return text.replace(_KEY[:6], _SECOND_KEY[:7]) #: One shape per way a single reading joins a key: a native link inside a raw #: Markdown url or label, a link the canonical grammar refuses, an emphasis pair #: closing a link, an emphasis pair on its own, and a pair inside a linked url. _SHAPES_ONE_READING_JOINS = [ - ("native-link-in-a-raw-url", f"[l](https://x/{_KEY[4:]}|)"), - ("native-link-in-a-label", f"[AK{_KEY[4:]}](https://x/a|b)"), - ("slack-emphasis-in-a-raw-url", f"[l](https://x/AKIA_{_KEY[4:]}_|)"), - ("refused-link-label-holds-the-head", f"[AKIA](https://x/\\){_KEY[4:]}"), - ("emphasis-closes-a-link", f"AKIA[{_KEY[4:]}]**(https://x)**"), - ("emphasis-pair", f"AKIA**{_KEY[4:]}**"), - ("pair-inside-a-linked-url", f"[l](https://x/AKIA**{_KEY[4:]}**)"), - ("pair-inside-a-parenthesised-url", f"[l](https://x/(a)/AKIA~~{_KEY[4:]}~~)"), + ("native-link-in-a-raw-url", f"[l](https://x/{_KEY[6:]}|)"), + ("native-link-in-a-label", f"[gl{_KEY[6:]}](https://x/a|b)"), + ("slack-emphasis-in-a-raw-url", f"[l](https://x/glpat-_{_KEY[6:]}_|)"), + ("refused-link-label-holds-the-head", f"[glpat-](https://x/\\){_KEY[6:]}"), + ("emphasis-closes-a-link", f"glpat-[{_KEY[6:]}]**(https://x)**"), + ("emphasis-pair", f"glpat-**{_KEY[6:]}**"), + ("pair-inside-a-linked-url", f"[l](https://x/glpat-**{_KEY[6:]}**)"), + ("pair-inside-a-parenthesised-url", f"[l](https://x/(a)/glpat-~~{_KEY[6:]}~~)"), ] + [ (case_name, payload) for case_name, payload in _KEYED_REFUSED_LINK_SHAPES if case_name.startswith("label-holds-the-tail-") - and case_name.endswith(f"-{_KEY[:4]}") + and case_name.endswith(f"-{_KEY[:6]}") and any(_KEY in reading for reading in _every_reading(payload)) ] @@ -820,8 +820,8 @@ def _keyed(text: str) -> str: class TestAKeySplitBySlackMarkupInsideARawMarkdownLink: @staticmethod - def _payload(delimiter: str, tail: str = _KEY[4:]) -> str: - return f"[l](https://x/AKIA{delimiter}{tail}{delimiter}|)" + def _payload(delimiter: str, tail: str = _KEY[6:]) -> str: + return f"[l](https://x/glpat-{delimiter}{tail}{delimiter}|)" @pytest.mark.parametrize( ("case_name", "delimiter"), @@ -852,7 +852,7 @@ def test_the_same_shapes_without_a_key_pass_through_byte_identical(self, case_na ids=[case[0] for case in _SLACK_RENDERED_DELIMITERS], ) def test_an_unmatched_delimiter_does_not_invent_a_key(self, case_name, delimiter): - payload = f"[l](https://x/AKIA{delimiter}rest|)" + payload = f"[l](https://x/glpat-{delimiter}rest|)" reading = display_safety._link_free_reading(payload) assert _default_redactor(reading) == reading, case_name assert redact_for_display(payload, _default_redactor) == (payload, False), case_name @@ -868,25 +868,23 @@ def test_an_unmatched_delimiter_does_not_invent_a_key(self, case_name, delimiter class TestEveryKeyAnyReadingJoinsIsRedactedTogether: """A text can carry a key one reading joins beside a key another reading joins: - ``[l](https://x/IOSF...|)`` shows its key to a Slack reader, and - ``ASIA[IOSF...](https://ex.com/p\\)q)`` beside it shows the second key to a + ``[l](https://x/IOSF...|)`` shows its key to a Slack reader, and + ``sk-ant-[IOSF...](https://ex.com/p\\)q)`` beside it shows the second key to a CommonMark reader. An answer scanned only under the reading that fired removes the first key and hands the reader the second. The same hole sits on the - canonical route: ``AKIA**IOSF...**`` beside the refused link is answered by the + canonical route: ``glpat-**IOSF...**`` beside the refused link is answered by the canonical redacted form, which still carries the link the narrow grammar joins. The emitted text has to show a key under no reading, and Discord's outbound path, which sends what the screen returns, is checked as well. """ - _TWO_VECTORS = ( - f"[l](https://x/{_KEY[4:]}|) {_keyed(f'AKIA[{_KEY[4:]}](https://ex.com/p\\)q)')}" - ) - _REFUSED_LINK = f"AKIA[{_KEY[4:]}](https://ex.com/p\\)q)" + _TWO_VECTORS = f"[l](https://x/{_KEY[6:]}|) {_keyed(f'glpat-[{_KEY[6:]}](https://ex.com/p\\)q)')}" + _REFUSED_LINK = f"glpat-[{_KEY[6:]}](https://ex.com/p\\)q)" _BESIDE_THE_REFUSED_LINK = [ - ("emphasis-pair-beside-the-refused-link", f"AKIA**{_KEY[4:]}** {_REFUSED_LINK}"), + ("emphasis-pair-beside-the-refused-link", f"glpat-**{_KEY[6:]}** {_REFUSED_LINK}"), ( "pair-inside-a-linked-url-beside-the-refused-link", - f"[l](https://x/AKIA**{_KEY[4:]}**) {_REFUSED_LINK}", + f"[l](https://x/glpat-**{_KEY[6:]}**) {_REFUSED_LINK}", ), ] @@ -939,7 +937,7 @@ def test_the_form_past_the_bound_is_clean_under_every_reading(self, case_name, p _HEADING_MARKER_BETWEEN_NAME_AND_COLON = ( "[[x](u)](u)\n\nSecretAccessKey\n# : wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLEKEY" ) - _FORMAT_CHARACTER_INSIDE_THE_KEY = f"{_KEY[:4]}\u200b{_KEY[4:]}" + _FORMAT_CHARACTER_INSIDE_THE_KEY = f"{_KEY[:6]}\u200b{_KEY[6:]}" @pytest.mark.parametrize( "reading", [None, slack_format._slack_client_display], ids=["canonical", "slack"] @@ -966,15 +964,15 @@ def test_a_format_character_is_no_seam_past_the_bound_under_a_sink_reading(self) _UNMATCHED_DELIMITER_URLS = [ - "[docs](https://example.com/AKIA_IOSFODNN7EXAMPLE)", - "[docs](https://example.com/AKIA*IOSFODNN7EXAMPLE)", - "[docs](https://example.com/AKIA~IOSFODNN7EXAMPLE)", - "[docs](https://example.com/AKIA`IOSFODNN7EXAMPLE)", - "[docs](https://example.com/AKIA_IOSF_ODNN7EXAMPLE)", - "[docs](https://example.com/AKIA_IOSFODNN7EXAMPLE) snake_case remains", - "[docs](https://example.com/AKIA~~IOSF~~ODNN7EXAMPLE)", - "[docs](https://example.com/AKIA-*IOSF*-ODNN7EXAMPLE)", - "[docs](https://example.com/AKIA-_IOSF_-ODNN7EXAMPLE)", + "[docs](https://example.com/glpat-_IOSFODNN7EXAMPLE)", + "[docs](https://example.com/glpat-*IOSFODNN7EXAMPLE)", + "[docs](https://example.com/glpat-~IOSFODNN7EXAMPLE)", + "[docs](https://example.com/glpat-`IOSFODNN7EXAMPLE)", + "[docs](https://example.com/glpat-_IOSF_ODNN7EXAMPLE)", + "[docs](https://example.com/glpat-_IOSFODNN7EXAMPLE) snake_case remains", + "[docs](https://example.com/glpat-~~IOSF~~ODNN7EXAMPLE)", + "[docs](https://example.com/glpat--*IOSF*-ODNN7EXAMPLE)", + "[docs](https://example.com/glpat--_IOSF_-ODNN7EXAMPLE)", ] @@ -991,7 +989,7 @@ def test_only_a_key_the_link_free_reading_joins_is_redacted(self, payload): assert safe == payload def test_double_tilde_is_caught_without_changing_telegram_fallback(self): - payload = "[l](https://x/AKIA~~IOSF~~ODNN7EXAMPLE)" + payload = "[l](https://x/glpat-~~IOSF~~ODNN7EXAMPLE)" assert _default_redactor(_strip_md(payload)) == _strip_md(payload) assert _default_redactor(display_safety._link_free_reading(payload)) != ( display_safety._link_free_reading(payload) @@ -1118,13 +1116,13 @@ def test_the_link_pass_prints_what_the_fallback_prints(self): def test_the_unshared_bullet_pass_keeps_a_visible_separator(self): for payload in ( - "AKIA\n- IOSFODNN7EXAMPLE", + "glpat-\n- IOSFODNN7EXAMPLE", "SecretAccessKey\n- : short-secret-value", ): assert _default_redactor(_strip_md(payload)) == _strip_md(payload), payload def test_a_url_opener_pairs_with_later_triple_emphasis(self): - payload = "[l](https://x/AKIA**IOSFODNN7EXAMPLE) ***x***" + payload = "[l](https://x/glpat-**IOSFODNN7EXAMPLE) ***x***" rendered = _strip_md(payload) assert _default_redactor(rendered) != rendered safe, redacted = redact_for_display(payload, _default_redactor) @@ -1133,9 +1131,9 @@ def test_a_url_opener_pairs_with_later_triple_emphasis(self): _FENCE_REGRESSION_CASES = [ - ("empty-fence-in-link", "[l](https://x/(a)/AKIA``````IOSFODNN7EXAMPLE)"), - ("info-string-in-link", "[l](https://x/AKIA```junk```IOSFODNN7EXAMPLE)"), - ("bare-info-string", "AKIA```y```IOSFODNN7EXAMPLE"), + ("empty-fence-in-link", "[l](https://x/(a)/glpat-``````IOSFODNN7EXAMPLE)"), + ("info-string-in-link", "[l](https://x/glpat-```junk```IOSFODNN7EXAMPLE)"), + ("bare-info-string", "glpat-```y```IOSFODNN7EXAMPLE"), ] @@ -1273,7 +1271,7 @@ def test_corpus_has_both_outcomes(self): #: Where the label's ``[`` and ``]`` cut the key: before, inside or after it. The #: label is never empty: no renderer links ``[]()``, while the screen collapses it. -_LABEL_CUTS = [(0, 4), (0, 10), (0, 20), (4, 10), (4, 20), (10, 20)] +_LABEL_CUTS = [(0, 6), (0, 12), (0, 22), (6, 12), (6, 22), (12, 22)] _LINK_DELIMITERS = [ ("none", ""), ("double-star", "**"), diff --git a/test/test_markdown_link_parentheses_renderers.py b/test/test_markdown_link_parentheses_renderers.py index d72507a3ad2..b71f93c8005 100644 --- a/test/test_markdown_link_parentheses_renderers.py +++ b/test/test_markdown_link_parentheses_renderers.py @@ -79,8 +79,8 @@ def test_a_native_slack_link_delimiter_in_a_destination_stays_as_markdown(self, @pytest.mark.parametrize( "payload", [ - "AKIA[l](https://x/a|IOSFODNN7EXAMPLE)", - "[AKIA](https://x/|IOSFODNN7EXAMPLE)", + "glpat-[l](https://x/a|IOSFODNN7EXAMPLE)", + "[glpat-](https://x/|IOSFODNN7EXAMPLE)", ], ) def test_a_pipe_destination_cannot_become_a_native_slack_link(self, payload): @@ -268,27 +268,27 @@ def test_a_rendered_link_is_a_collapsed_link(self, renderer, source): _MUST_CATCH_LINK_SHAPES = [ - "[AKIA](https://x/((a)))IOSFODNN7EXAMPLE", - "[AKIA](https://x/(((a))))IOSFODNN7EXAMPLE", - "[AKIA](https://x/((((a)))))IOSFODNN7EXAMPLE", - "[AKIA](https://x/((((((((a)))))))))IOSFODNN7EXAMPLE", - r"[AKIA](https://x/p\)q)IOSFODNN7EXAMPLE", - "[AKIA]()IOSFODNN7EXAMPLE", - "[AKIA](https://x/((a)))IOSFODNN7EXAMPLE)", - "[AKIA](https://x/[y](z))IOSFODNN7EXAMPLE", + "[glpat-](https://x/((a)))IOSFODNN7EXAMPLE", + "[glpat-](https://x/(((a))))IOSFODNN7EXAMPLE", + "[glpat-](https://x/((((a)))))IOSFODNN7EXAMPLE", + "[glpat-](https://x/((((((((a)))))))))IOSFODNN7EXAMPLE", + r"[glpat-](https://x/p\)q)IOSFODNN7EXAMPLE", + "[glpat-]()IOSFODNN7EXAMPLE", + "[glpat-](https://x/((a)))IOSFODNN7EXAMPLE)", + "[glpat-](https://x/[y](z))IOSFODNN7EXAMPLE", ] _MUST_STAY_CAUGHT_LINK_SHAPES = [ - "[AKIA](https://x/(a))IOSFODNN7EXAMPLE", - '[AKIA](https://x "t")IOSFODNN7EXAMPLE', - '[AKIA](https://x/(a) "t")IOSFODNN7EXAMPLE', - "[x](https://a[AKIA](https://b)IOSFODNN7EXAMPLE)", - "[x](https://a [AKIA](https://b)IOSFODNN7EXAMPLE)", + "[glpat-](https://x/(a))IOSFODNN7EXAMPLE", + '[glpat-](https://x "t")IOSFODNN7EXAMPLE', + '[glpat-](https://x/(a) "t")IOSFODNN7EXAMPLE', + "[x](https://a[glpat-](https://b)IOSFODNN7EXAMPLE)", + "[x](https://a [glpat-](https://b)IOSFODNN7EXAMPLE)", ] _KEYLESS_LINK_SHAPES = [ f"See [Python]({WIKI}) and [MSDN]({MSDN}).", - "[AKIA](a)(b)IOSFODNN7EXAMPLE", + "[glpat-](a)(b)IOSFODNN7EXAMPLE", "[a](http://x/(y)/(z))", "[a](b", "[a](){_KEY[4:]}", - f"[AKIA](a b){_KEY[4:]}", + f'[glpat-](https://x "t"){_KEY[6:]}', + f"[glpat-](){_KEY[6:]}", + f"[glpat-](a b){_KEY[6:]}", ], ) def test_a_destination_with_a_space_is_still_collapsed(self, payload): @@ -86,7 +86,7 @@ def test_a_destination_with_a_space_is_still_collapsed(self, payload): assert _KEY not in safe def test_a_group_after_a_non_opener_label_fragment_is_redacted(self): - payload = f"[AKIA](https://x/a](b)){_KEY[4:]}" + payload = f"[glpat-](https://x/a](b)){_KEY[6:]}" assert canonicalize_display(payload) == _KEY safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True @@ -96,17 +96,17 @@ def test_a_group_after_a_non_opener_label_fragment_is_redacted(self): def test_a_balanced_pair_still_links_beside_the_refusal(self): """The refusal is scoped to a nested ``[label](``; a URL group is untouched.""" assert _slack(f"see [Python]({WIKI}) now") == f"see <{WIKI}|Python> now" - assert canonicalize_display(f"[AKIA]({WIKI}){_KEY[4:]}") == _KEY + assert canonicalize_display(f"[glpat-]({WIKI}){_KEY[6:]}") == _KEY class TestAKeySplitByEmphasisInsideAUrlIsRedacted: """The canonical form drops a collapsed link's url; a plain-text sink prints it. - ``[l](https://x/(a)/AKIA**REST**)`` collapses to ``l`` on the screen, so the + ``[l](https://x/(a)/glpat-**REST**)`` collapses to ``l`` on the screen, so the url and the key split inside it leave the canonical scan, and the literal scan - sees ``AKIA**`` and matches nothing. Telegram's ``_strip_md`` fallback (taken + sees ``glpat-**`` and matches nothing. Telegram's ``_strip_md`` fallback (taken when an HTML edit or send is rejected) strips the ``**`` and prints - ``l (https://x/(a)/AKIAIOSFODNN7EXAMPLE)``, the key whole. The screen scans + ``l (https://x/(a)/glpat-IOSFODNN7EXAMPLE)``, the key whole. The screen scans that plain-text reading too and answers with the canonical form, which carries no url. The url without parentheses and the Slack form leak the same way and are closed by the same reading. @@ -115,9 +115,9 @@ class TestAKeySplitByEmphasisInsideAUrlIsRedacted: @pytest.mark.parametrize( "payload", [ - f"[l](https://x/(a)/AKIA**{_KEY[4:]}**)", - f"[l](https://x/AKIA**{_KEY[4:]}**)", - f"", + f"[l](https://x/(a)/glpat-**{_KEY[6:]}**)", + f"[l](https://x/glpat-**{_KEY[6:]}**)", + f"", ], ) def test_the_key_is_redacted_and_absent_from_the_plain_text_fallback(self, payload): @@ -134,27 +134,27 @@ def test_emphasis_beside_a_parenthesised_link_without_a_key_is_untouched(self): class TestAKeyJoinedByALinkAnEarlierPassCloses: - """``AKIA[IOSF...]**(https://x)**`` is no link to the screen's link pass, which + """``glpat-[IOSF...]**(https://x)**`` is no link to the screen's link pass, which runs first; the emphasis pass then drops the ``**`` and the canonical form - ``AKIA[IOSF...](https://x)`` scans as split. Telegram's ``_strip_md`` removes + ``glpat-[IOSF...](https://x)`` scans as split. Telegram's ``_strip_md`` removes the ``**`` and THEN flattens the link to ``label (url)``, showing - ``AKIAIOSFODNN7EXAMPLE (https://x)``: the key whole. The plain reading has to + ``glpat-IOSFODNN7EXAMPLE (https://x)``: the key whole. The plain reading has to apply the fallback's link pass after its delimiter passes, as the fallback does, so the screen sees that join and answers with the canonical form, which the settling passes then collapse and redact. """ _JOINED = [ - ("double-star", f"AKIA[{_KEY[4:]}]**(https://x)**"), - ("double-underscore", f"AKIA[{_KEY[4:]}]__(https://x)__"), - ("inline-code", f"AKIA[{_KEY[4:]}]`(https://x)`"), - ("head-before-a-longer-label", f"AKIAIOSF[{_KEY[8:]}]**(https://x)**"), + ("double-star", f"glpat-[{_KEY[6:]}]**(https://x)**"), + ("double-underscore", f"glpat-[{_KEY[6:]}]__(https://x)__"), + ("inline-code", f"glpat-[{_KEY[6:]}]`(https://x)`"), + ("head-before-a-longer-label", f"glpat-IOSF[{_KEY[10:]}]**(https://x)**"), ] _LEFT_ALONE = [ - ("rest-after-the-url", f"[AKIA]**(https://x)**{_KEY[4:]}"), + ("rest-after-the-url", f"[glpat-]**(https://x)**{_KEY[6:]}"), ("split-label-rest-after-the-url", f"[{_KEY[:10]}]**(https://x)**{_KEY[10:]}"), - ("a-space-before-the-url", f"AKIA[{_KEY[4:]}] **(https://x)**"), - ("a-space-inside-the-emphasis", f"AKIA[{_KEY[4:]}]** (https://x)**"), + ("a-space-before-the-url", f"glpat-[{_KEY[6:]}] **(https://x)**"), + ("a-space-inside-the-emphasis", f"glpat-[{_KEY[6:]}]** (https://x)**"), ] @pytest.mark.parametrize(("case_name", "payload"), _JOINED, ids=[c[0] for c in _JOINED]) @@ -176,9 +176,9 @@ def test_a_shape_the_fallback_keeps_split_is_left_as_written(self, case_name, pa class TestAKeyJoinedByANativeLinkInsideARawMarkdownLink: - """``[l](https://x/AKIOSF...)`` collapses to ``l`` on the screen, so the + """``[l](https://x/glIOSF...)`` collapses to ``l`` on the screen, so the url and everything in it leave the canonical scan, and the literal scan sees - ``AKIOSF...``, no key. Slack leaves the Markdown raw, because a ``|`` or + ``glIOSF...``, no key. Slack leaves the Markdown raw, because a ``|`` or ``>`` in the destination cannot go into a native link, and renders the embedded ```` as a native link showing ``IA``: the reader sees the key whole. The screen scans that reading too, Markdown links raw and native links collapsed, @@ -186,12 +186,12 @@ class TestAKeyJoinedByANativeLinkInsideARawMarkdownLink: """ _JOINED = [ - ("token-in-the-middle", f"[l](https://x/AK{_KEY[4:]})"), - ("token-at-the-start", f"[l](https://x/{_KEY[4:]}|)"), - ("token-at-the-end", f"[l](https://x/AKIA)"), - ("two-tokens", f"[l](https://x/AKIOSF{_KEY[12:]})"), - ("angle-bracket-destination", f"[l](https://x/>AK{_KEY[4:]})"), - ("token-in-the-label", f"[AK{_KEY[4:]}](https://x/a|b)"), + ("token-in-the-middle", f"[l](https://x/gl{_KEY[6:]})"), + ("token-at-the-start", f"[l](https://x/{_KEY[6:]}|)"), + ("token-at-the-end", f"[l](https://x/glpat-)"), + ("two-tokens", f"[l](https://x/glIOSF{_KEY[14:]})"), + ("angle-bracket-destination", f"[l](https://x/>gl{_KEY[6:]})"), + ("token-in-the-label", f"[gl{_KEY[6:]}](https://x/a|b)"), ] @pytest.mark.parametrize(("case_name", "payload"), _JOINED, ids=[c[0] for c in _JOINED]) @@ -237,9 +237,9 @@ def test_a_cut_of_text_without_a_key_passes_through_byte_identical(self, head, w class TestAKeySplitByAPairInsideAParenthesisedUrlIsRedacted: - """``[l](https://x/(a)/AKIA~~IOSF...~~)`` collapses to ``l`` on the screen, so + """``[l](https://x/(a)/glpat-~~IOSF...~~)`` collapses to ``l`` on the screen, so the url and the key split inside it leave the canonical scan; the literal scan - sees ``AKIA~~`` and matches nothing, and the plain reading drops no ``~~``. A + sees ``glpat-~~`` and matches nothing, and the plain reading drops no ``~~``. A link grammar whose destination admits no parenthesis group leaves the link as written, its url text, where the emphasis pass joins the key: the screen scans that reading too, so a url the wider grammar links is never a url that leaves @@ -248,8 +248,8 @@ class TestAKeySplitByAPairInsideAParenthesisedUrlIsRedacted: """ @staticmethod - def _payload(pair: str, tail: str = _KEY[4:]) -> str: - return f"[l](https://x/(a)/AKIA{pair}{tail}{pair})" + def _payload(pair: str, tail: str = _KEY[6:]) -> str: + return f"[l](https://x/(a)/glpat-{pair}{tail}{pair})" @pytest.mark.parametrize(("case_name", "pair"), _PAIRS_OUTSIDE_THE_FALLBACK) def test_the_key_is_redacted_on_every_reading(self, case_name, pair): @@ -283,8 +283,8 @@ def test_a_parenthesised_link_beside_emphasis_without_a_key_is_untouched(self): class TestTheEmittedCanonicalFormRendersAsItself: """A pass after the link pass can close a link the link pass went past. - ``[AKIA]*(https://x)REST`` is text to the link pass, and the emphasis pass - then drops the ``*`` and leaves ``[AKIA](https://x)REST``, a link on every + ``[glpat-]*(https://x)REST`` is text to the link pass, and the emphasis pass + then drops the ``*`` and leaves ``[glpat-](https://x)REST``, a link on every renderer that joins the key. The canonical scan cleared the text before the star was gone, so a branch that emitted that canonical form handed Slack a link the screen never saw. The emitted text is rendered again until @@ -295,13 +295,13 @@ class TestTheEmittedCanonicalFormRendersAsItself: "payload", [ # A: the emphasis pass closes the link. - f"{_URL_SPLIT_TRIGGER} [AKIA]*(https://x){_KEY[4:]}", + f"{_URL_SPLIT_TRIGGER} [glpat-]*(https://x){_KEY[6:]}", # C: the same shape on the canonical branch, a key split by ``**``. - f"AKIA**{_KEY[4:]}** [AKIA]*(https://x){_KEY[4:]}", + f"glpat-**{_KEY[6:]}** [glpat-]*(https://x){_KEY[6:]}", # D: a format character closes the link. - f"{_URL_SPLIT_TRIGGER} [AKIA]\u200b(https://x){_KEY[4:]}", + f"{_URL_SPLIT_TRIGGER} [glpat-]\u200b(https://x){_KEY[6:]}", # E: a collapsed Slack link closes the link. - f"{_URL_SPLIT_TRIGGER} [AKIA](https://x){_KEY[4:]}", + f"{_URL_SPLIT_TRIGGER} [glpat-](https://x){_KEY[6:]}", ], ) def test_a_link_closed_by_a_later_pass_is_redacted(self, payload): @@ -314,7 +314,7 @@ def test_a_link_closed_by_a_later_pass_is_redacted(self, payload): def test_a_link_nested_one_level_deeper_settles(self): """Each pass peels one level, so the fix has to repeat until nothing moves.""" - payload = f"{_URL_SPLIT_TRIGGER} [[AKIA]*(https://x)]*(https://y){_KEY[4:]}" + payload = f"{_URL_SPLIT_TRIGGER} [[glpat-]*(https://x)]*(https://y){_KEY[6:]}" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True assert canonicalize_display(safe) == safe @@ -326,7 +326,7 @@ def test_a_link_nested_one_level_deeper_settles(self): def test_nesting_past_the_pass_bound_leaves_no_markup_to_render(self, depth): """The bound is reached before the key surfaces, so the fallback strips every delimiter: the urls stay between the halves as text.""" - payload = f"{_URL_SPLIT_TRIGGER} {_nested_link(depth)}{_KEY[4:]}" + payload = f"{_URL_SPLIT_TRIGGER} {_nested_link(depth)}{_KEY[6:]}" safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True assert _KEY not in safe @@ -337,7 +337,7 @@ def test_nesting_past_the_pass_bound_leaves_no_markup_to_render(self, depth): def test_the_construct_alone_is_left_as_written(self): """No reading of the text shows the key whole, so it goes out as written and the reader sees the brackets and the star.""" - payload = f"[AKIA]*(https://x){_KEY[4:]}" + payload = f"[glpat-]*(https://x){_KEY[6:]}" assert redact_for_display(payload, _default_redactor) == (payload, False) @@ -411,15 +411,15 @@ class TestATagShapedLabelPastTheSettlingBoundCannotBecomeALink: @staticmethod def _payload(label: str, *, separator: str = "", depth: int = 5) -> str: hidden_link = _nested_text(f"{label}(https://v)", depth) - return f"{_URL_SPLIT_TRIGGER} {hidden_link}{separator}{_KEY[4:]}" + return f"{_URL_SPLIT_TRIGGER} {hidden_link}{separator}{_KEY[6:]}" @pytest.mark.parametrize( ("case_name", "label", "separator", "depth"), [ - ("tag-shaped-label-past-bound", "[REDACTED: AKIA]", "", 5), - ("space-after-link", "[REDACTED: AKIA]", " ", 5), + ("tag-shaped-label-past-bound", "[REDACTED: glpat-]", "", 5), + ("space-after-link", "[REDACTED: glpat-]", " ", 5), ("real-credential-tag-label", CREDENTIAL_REDACTION_TAGS[0], "", 5), - ("tag-shaped-label-at-bound", "[REDACTED: AKIA]", "", 4), + ("tag-shaped-label-at-bound", "[REDACTED: glpat-]", "", 4), ], ) def test_no_renderer_shows_the_joined_key(self, case_name, label, separator, depth): @@ -451,7 +451,7 @@ def test_the_literal_pass_bound_selects_settling_or_fallback( ): payload = ( f"{_URL_SPLIT_TRIGGER} {self._FALLBACK_MARKER}" - f"{_nested_link(passes_needed - 1)}{_KEY[4:]}" + f"{_nested_link(passes_needed - 1)}{_KEY[6:]}" ) safe, redacted = redact_for_display(payload, _default_redactor) assert redacted is True @@ -470,10 +470,12 @@ def recording_redactor(text): return _default_redactor(text) monkeypatch.setattr(display_safety, "canonicalize_display", peel_one_layer) - payload = "layer:" * (DISPLAY_SETTLING_PASSES + 1) + f"AKIA{delimiter}{_KEY[4:]}" + # A Slack-shaped key: its body class has no `_`, so every delimiter splits it. + key = f"xoxb-{_KEY[6:]}" + payload = "layer:" * (DISPLAY_SETTLING_PASSES + 1) + f"xoxb-{delimiter}{_KEY[6:]}" assert recording_redactor(payload) == payload safe = display_safety.settled_display_form(payload, recording_redactor) - assert redactor_inputs[-1] == _KEY + assert redactor_inputs[-1] == key assert safe == CREDENTIAL_REDACTION_TAGS[0] diff --git a/test/test_memory_history_edit.py b/test/test_memory_history_edit.py index 1b7177da13b..5591d170758 100644 --- a/test/test_memory_history_edit.py +++ b/test/test_memory_history_edit.py @@ -174,7 +174,9 @@ def change_before_lock(content, **kwargs): else: with tier.db: tier._write_history( - date.today().isoformat(), "Preserve AKIAIOSFODNN7EXAMPLE exactly" + # nosemgrep: kirocrew.test-naive-local-time -- today's row is keyed by the same local-date read the store makes + date.today().isoformat(), + "Preserve glpat-IOSFODNN7EXAMPLE exactly", ) winner = tier.read_editable_history().encode("utf-8") return original_write(content, **kwargs) @@ -194,12 +196,12 @@ def change_before_lock(content, **kwargs): expected_code = "memory_document_changed" if change == "append" else "memory_document_redacted" assert json.loads(response.text)["code"] == expected_code sentinel = ( - b"Concurrent consolidation sentinel" if change == "append" else b"AKIAIOSFODNN7EXAMPLE" + b"Concurrent consolidation sentinel" if change == "append" else b"glpat-IOSFODNN7EXAMPLE" ) assert sentinel in winner assert (await asyncio.to_thread(tier.read_editable_history)).encode("utf-8") == winner assert not store._history_dir.exists() - assert "AKIAIOSFODNN7EXAMPLE" not in response.text + assert "glpat-IOSFODNN7EXAMPLE" not in response.text @pytest.mark.asyncio diff --git a/test/test_private_profile_error_response.py b/test/test_private_profile_error_response.py index 9dd2d5f1057..e741e24b77f 100644 --- a/test/test_private_profile_error_response.py +++ b/test/test_private_profile_error_response.py @@ -24,7 +24,7 @@ async def test_private_profile_failure_is_stable_and_keeps_safe_log_diagnostics( ): memory = await markdown_memory_for_store(env.state, "member-alice") before = memory.read_preferences(), memory.read_projects() - credential = "AKIAIOSFODNN7EXAMPLE" + credential = "glpat-IOSFODNN7EXAMPLE" writer = MagicMock(side_effect=error_type(f"identity unavailable at {path}: {credential}")) monkeypatch.setattr(memory, "write_private_profile_validated", writer) req = request( diff --git a/test/test_split_credential_boundary.py b/test/test_split_credential_boundary.py index 76336e70b2d..412e1d29765 100644 --- a/test/test_split_credential_boundary.py +++ b/test/test_split_credential_boundary.py @@ -85,7 +85,7 @@ def _repaired_names(tree: ast.AST) -> set[str]: ``redact_for_display`` / ``_display_safe`` are deliberately NOT here: they do no whitespace collapsing (``strip_ansi`` -> redactor -> ``_strip_format_chars`` - -> ``canonicalize_display``), so ``AKIA\\nIOSFODNN7EXAMPLE`` passes through them + -> ``canonicalize_display``), so ``glpat-\\nIOSFODNN7EXAMPLE`` passes through them unredacted and a later no-redactor cut at that newline delivers the key whole across two messages. Certifying their output "safe to cut again" would weaken the universal ``test_every_splitter_call_passes_a_redactor`` gate to a property @@ -346,7 +346,7 @@ def test_a_key_split_at_a_space_does_not_reach_two_messages(self) -> None: objects. The cut lands on the space, the seal takes it, and the halves sit flush on screen. """ - text = f"{'w ' * 12}{HEAD} {TAIL} and some trailing words" + text = f"{'w ' * 12}{HEAD} {TAIL} and some trailing" unguarded = split_markdown_safe(text, 35) assert len(unguarded) == 2 assert KEY not in unguarded[0] and KEY not in unguarded[1] @@ -459,13 +459,13 @@ def test_the_raw_byte_split_alone_would_hand_over_the_key(self) -> None: # key straddles a line break, so the splitter cuts HEAD and TAIL into # adjacent chunks the reader reads as one key once the break is gone. text = f"{HEAD}\n{TAIL} trailing here to force more content and length beyond" - raw = split_markdown_bytes(text, 11) + raw = split_markdown_bytes(text, 13) assert len(raw) > 1 assert _rejoins(raw) def test_chunk_for_transport_closes_that_seam(self) -> None: text = f"{HEAD}\n{TAIL} trailing here to force more content and length beyond" - chunks = chunk_for_transport(text, self._byte_capped(11)) + chunks = chunk_for_transport(text, self._byte_capped(13)) assert len(chunks) > 1 assert not _rejoins(chunks) assert KEY not in _on_screen(chunks) @@ -497,7 +497,7 @@ def test_the_byte_path_never_returns_a_rejoining_sequence(self) -> None: """ from kiro_crew.messaging.renderer import _default_redactor as _dr - head, tail = "AKIAIOSFOD", "NN7EXAMPLE" + head, tail = "glpat-IOSFOD", "NN7EXAMPLE" bodies = ( head + "# " + tail + " x" * 20, # heading-marker seam (F7 shape) head + " " * 40 + tail + " filler" * 20, # wide-space straddle -> floor @@ -521,7 +521,7 @@ def test_a_byte_heading_marker_seam_clean_whole_text_is_regraded(self) -> None: ``repaired_for_delivery`` answers with the source UNCHANGED when no literal span collapses to a key and the whole-text canonical collapse reads clean. But this PR's ``^``-anchored heading rule is POSITION-dependent: a mid-line - ``AKIA# NN7EXAMPLE`` is clean whole-text (the ``#`` is not line-leading), yet + ``glpat-# NN7EXAMPLE`` is clean whole-text (the ``#`` is not line-leading), yet a byte cut that makes ``# NN7EXAMPLE`` piece-leading strips the ``#`` at render and rejoins the key across two messages. A single re-split of the unchanged repair reproduces that unsafe sequence, so the byte path must @@ -529,7 +529,7 @@ def test_a_byte_heading_marker_seam_clean_whole_text_is_regraded(self) -> None: """ from kiro_crew.messaging.renderer import _default_redactor as _dr - head, tail = "AKIAIOSFOD", "NN7EXAMPLE" + head, tail = "glpat-IOSFOD", "NN7EXAMPLE" # budget 10: the byte cut lands exactly so ``# NN7EXAMPLE`` is piece-leading # (measured; the OLD one-pass byte path leaked this exact fixture). body = head + "# " + tail + " x" * 20 diff --git a/test/test_split_credential_boundary_channel_delivery.py b/test/test_split_credential_boundary_channel_delivery.py index 0d0a1adc5bc..c1134183f60 100644 --- a/test/test_split_credential_boundary_channel_delivery.py +++ b/test/test_split_credential_boundary_channel_delivery.py @@ -180,7 +180,7 @@ class TestAStreamedReplyNeverRevisesADeliveredChunk: """ #: The body that reproduced the revision, and the budget it happened at. - PAD, LIMIT, CUT = 108, 120, 129 + PAD, LIMIT, CUT = 108, 120, 131 def _body(self) -> str: return f"{'w' * self.PAD} {HEAD} {TAIL} trailing words after the key here" diff --git a/test/test_split_credential_boundary_readings.py b/test/test_split_credential_boundary_readings.py index c81fa539ce8..0f25c5db71d 100644 --- a/test/test_split_credential_boundary_readings.py +++ b/test/test_split_credential_boundary_readings.py @@ -68,7 +68,7 @@ class TestTheRepairIsJudgedByTheReadingThatRefusedTheCut: #: One link to the canonical grammar, which collapses it to its label and drops #: the url with the key inside it. The narrower link grammar leaves the url as #: text, where the emphasis pass joins the key across the ``~~`` pair. - PARENTHESISED_URL = "see [l](https://x/(a)/AKIA~~IOSFODNN7EXAMPLE~~) done" + PARENTHESISED_URL = "see [l](https://x/(a)/glpat-~~IOSFODNN7EXAMPLE~~) done" #: A field name and its assignment held apart by a heading marker the text #: keeps mid-line. A cut before the marker opens a piece with it, and the plain #: reading of that piece drops it. diff --git a/test/test_telegram_parity_turns.py b/test/test_telegram_parity_turns.py index 33f8eb201fe..dfd9ffd02eb 100644 --- a/test/test_telegram_parity_turns.py +++ b/test/test_telegram_parity_turns.py @@ -286,13 +286,13 @@ async def test_a_markup_split_credential_is_never_synthesized(self) -> None: """Audio is an egress a reader cannot un-see, so it gets the display floor. This leg bypasses the renderer, which is where a turn normally gets that - floor, and the driver's pass is BYTE-level: `AKIA**IOSFODNN7EXAMPLE**` does + floor, and the driver's pass is BYTE-level: `glpat-**IOSFODNN7EXAMPLE**` does not match, because the `**` sits inside the key. A synthesizer reads the characters and not the markup, so the credential the byte pass missed would be spoken aloud. """ d, _, _ = _dispatcher({1}) - head, tail = "AKIA", "IOSFODNN7EXAMPLE" + head, tail = "glpat-", "IOSFODNN7EXAMPLE" spoken: list[str] = [] # Real signature: (deliver, text, **settings). A mismatch here is swallowed diff --git a/test/test_telegram_renderer_split.py b/test/test_telegram_renderer_split.py index 41fc4ef2aba..d3e0f45a0ba 100644 --- a/test/test_telegram_renderer_split.py +++ b/test/test_telegram_renderer_split.py @@ -400,7 +400,7 @@ def _on_screen(frame: str) -> str: """What the reader sees of one bubble: Telegram's HTML, rendered. The seal ships HTML, so the raw frame keeps a key apart with the very tags - that vanish on screen -- ``AKIAIOSFODNN7EXAMPLE`` matches nothing while + that vanish on screen -- ``glpat-IOSFODNN7EXAMPLE`` matches nothing while the reader reads one key straight through it. """ return html.unescape(re.sub(r"<[^>]+>", "", frame)) @@ -454,7 +454,7 @@ def test_a_boundary_is_graded_on_the_text_the_seal_delivers( sit flush together. """ r, cli = self._renderer(monkeypatch) - r._buf = ["a" * (self._CAP - 8) + "AKIAIOSF" + "\n ODNN7EXAMPLE" + " tail" * 40] + r._buf = ["a" * (self._CAP - 10) + "glpat-IOSF" + "\n ODNN7EXAMPLE" + " tail" * 40] async def _go() -> None: await r._rotate_on_length() @@ -477,7 +477,7 @@ def test_the_fallback_offset_is_one_the_caller_can_take( is deterministic it would get the same answer on every later rotation: the segment would never go out at all. """ - raw = "a" * (self._CAP - 8) + "AKIAIOSF" + "\n ODNN7EXAMPLE" + " tail" * 40 + raw = "a" * (self._CAP - 10) + "glpat-IOSF" + "\n ODNN7EXAMPLE" + " tail" * 40 raw_offset = safe_split_offset(raw, self._CAP, _default_redactor) assert not joins_to_a_credential( raw[:raw_offset], raw[raw_offset:], _default_redactor @@ -512,7 +512,10 @@ def _three_piece_rule_source(self) -> str: """ bar = "-" * 120 pad = "a" * 330 - return pad + "\nAKIAIOS\n\n" + bar + "\n\nFODNN7\n\n" + bar + "\n\nEXAMPLE\n" + "b" * 330 + # A Stripe-shaped key: its body takes no `-`, so a rule cannot extend it. + return ( + pad + "\nsk_live_IOS\n\n" + bar + "\n\nFODNN7\n\n" + bar + "\n\nEXAMPLE\n" + "b" * 330 + ) def test_the_held_image_prefix_is_graded_as_a_sequence( self, monkeypatch: pytest.MonkeyPatch @@ -556,11 +559,14 @@ def test_a_markup_span_covering_a_whole_piece_is_caught( No neighbouring PAIR of these three pieces reveals anything -- the link needs its closing bracket, which is in the third -- while the full join collapses - the url to its label and puts that label against ``AKIA``. + the url to its label and puts that label against ``glpat-``. """ r, cli = self._renderer(monkeypatch) r._buf = [ - "a" * (self._CAP - 4) + "AKIA[IOSFODNN7EXAMPLE](http://q/" + "b" * self._CAP + ") rest" + "a" * (self._CAP - 4) + + "glpat-[IOSFODNN7EXAMPLE](http://q/" + + "b" * self._CAP + + ") rest" ] async def _go() -> None: @@ -595,7 +601,7 @@ def test_a_safe_head_that_renders_over_the_cap_is_shrunk_not_abandoned( # The key straddles a NEWLINE, which the splitter prefers as a break, so the # severing boundary needs no arithmetic. The leading `&` run is what makes a # head bounded by the source budget render past the cap. - src = "&" * 600 + "AKIAIOSF" + "\n" + "ODNN7EXAMPLE" + "a" * 2000 + src = "&" * 600 + "glpat-IOSF" + "\n" + "ODNN7EXAMPLE" + "a" * 2000 assert _rendered_len(src[:limit]) > cap, "fixture head does not inflate past the cap" r._buf = [src] @@ -619,7 +625,7 @@ def test_a_retained_buffer_holds_only_source_text( """ src = ( "a" * (self._CAP - 8) - + "AKIAIOSF" + + "glpat-IOSF" + "ODNN7EXAMPLE" + "\n\n```py\n" + "x = 1\n" * 40 diff --git a/test/test_wecom_renderer.py b/test/test_wecom_renderer.py index 83e5590b6e3..c2362f76fdd 100644 --- a/test/test_wecom_renderer.py +++ b/test/test_wecom_renderer.py @@ -243,7 +243,7 @@ class TestThinkReasoningRedaction: """The ```` reasoning frame is scrubbed render-aware, not literally. WeCom renders the ```` block as markdown, so a credential split by - emphasis (``AKIA**REST**``) survives a literal byte scan and is reassembled + emphasis (``glpat-**REST**``) survives a literal byte scan and is reassembled on screen -- the same hazard the answer body is guarded against, on the same channel. Asserted against the RENDERED form. """ @@ -257,11 +257,11 @@ async def test_think_reasoning_redacts_markup_split_credential(self) -> None: await r.on_turn_start() c.frames.clear() r._last_send = 0.0 # clear the throttle so the reasoning frame goes out - await r.on_thinking("leaking AKIAIOSF**ODNN7EXAMPLE** in the trace") + await r.on_thinking("leaking glpat-IOSF**ODNN7EXAMPLE** in the trace") think = "".join(f["content"] for f in c.frames) assert "" in think, f"no reasoning frame was sent: {c.frames}" - assert "AKIAIOSFODNN7EXAMPLE" not in canonicalize_display(think) + assert "glpat-IOSFODNN7EXAMPLE" not in canonicalize_display(think) @pytest.mark.asyncio async def test_think_reasoning_keeps_clean_text(self) -> None: @@ -280,7 +280,7 @@ class TestAnswerBodyRedaction: """The answer body is scrubbed render-aware at the send, and no cut severs a key. WeCom renders the body as markdown and extracts no attachments from it, so a - credential split by emphasis (``AKIA**REST**``) survives the driver's literal + credential split by emphasis (``glpat-**REST**``) survives the driver's literal channel-neutral pass and is reassembled on screen. ``_render_slice`` redacts each outgoing slice, and the callers pick the cut with ``_safe_raw_cut`` so a credential is never split across two bubbles -- the offsets stay in raw @@ -294,11 +294,11 @@ async def test_answer_body_redacts_markup_split_credential(self) -> None: c = FakeClient() r = _renderer(c) - await r.on_text_chunk("the key is AKIAIOSF**ODNN7EXAMPLE** ok") + await r.on_text_chunk("the key is glpat-IOSF**ODNN7EXAMPLE** ok") await r.on_done() final = c.frames[-1]["content"] - assert "AKIAIOSFODNN7EXAMPLE" not in canonicalize_display(final) + assert "glpat-IOSFODNN7EXAMPLE" not in canonicalize_display(final) def test_text_stays_raw_for_persistence(self) -> None: # text() is what drive_turn persists; the redaction lives only on the @@ -454,12 +454,12 @@ class TestTheCapCutsWhereTheReaderCannotRejoin: async def test_a_link_split_key_does_not_cross_two_bubbles(self) -> None: # The acceptance case: a Markdown link whose target carries a comma, which no # hand-written character class reached across six review rounds. - head, tail = "[AKIA](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" + head, tail = "[glpat-](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" c = await _stream_across_a_rotation(_answer_whose_cap_lands_between(head, tail)) on_screen, in_a_copy = _reader_views(c) - assert "AKIAIOSFODNN7EXAMPLE" not in on_screen - assert "AKIAIOSFODNN7EXAMPLE" not in in_a_copy + assert "glpat-IOSFODNN7EXAMPLE" not in on_screen + assert "glpat-IOSFODNN7EXAMPLE" not in in_a_copy _assert_nothing_reached_the_reader(c) @pytest.mark.parametrize(("head", "tail"), CREDENTIAL_STRADDLE_SHAPES) @@ -599,12 +599,12 @@ async def test_link_split_key_does_not_cross_the_seam(self) -> None: # The acceptance case, at the seam: a Markdown link whose target carries a # comma — the shape no hand-written character class reached across six review # rounds — with its completion in the bubble AFTER the seal. - head, tail = "[AKIA](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" + head, tail = "[glpat-](https://ex.test/a,b)", "IOSFODNN7EXAMPLE" c = await _stream_across_a_seam(head, tail) on_screen, in_a_copy = _reader_views(c) - assert "AKIAIOSFODNN7EXAMPLE" not in on_screen - assert "AKIAIOSFODNN7EXAMPLE" not in in_a_copy + assert "glpat-IOSFODNN7EXAMPLE" not in on_screen + assert "glpat-IOSFODNN7EXAMPLE" not in in_a_copy _assert_nothing_reached_the_reader(c) @pytest.mark.parametrize(("head", "tail"), CREDENTIAL_STRADDLE_SHAPES) @@ -626,7 +626,7 @@ async def test_trailing_prose_after_the_completion_survives(self) -> None: # continuation: a blanket drop would lose legitimate answer text and turn a # security guard into data loss (the failure mode the conductor decision # rejected — visible dup beats silent loss, and here we do neither). - head, tail = "AKIAIOSF", "ODNN7EXAMPLE" + head, tail = "glpat-IOSF", "ODNN7EXAMPLE" marker_word = "afterwardsuniquetoken" c = FakeClient() r = _capped_renderer(c) @@ -640,7 +640,7 @@ async def test_trailing_prose_after_the_completion_survives(self) -> None: await r.close() on_screen, _copy = _reader_views(c) - assert "AKIAIOSFODNN7EXAMPLE" not in on_screen, "the key must not survive the seam" + assert "glpat-IOSFODNN7EXAMPLE" not in on_screen, "the key must not survive the seam" delivered = "".join(f["content"] for f in c.frames) + "".join(p[1] for p in c.pushed) assert marker_word in delivered, "trailing prose past the completion was dropped" _assert_nothing_reached_the_reader(c) @@ -679,13 +679,13 @@ async def test_a_credential_after_an_unbounded_link_target_is_still_closed(self) # credential-bearing label far back in the seam, so a windowed grade would # scan a span the key's start was never inside and pass vacuously. Grading # the WHOLE delivered seam closes it. - head = "[AKIA](https://ex.test/" + "a" * 600 + ",b)" + head = "[glpat-](https://ex.test/" + "a" * 600 + ",b)" tail = "IOSFODNN7EXAMPLE" c = await _stream_across_a_seam(head, tail, cap=700) on_screen, in_a_copy = _reader_views(c) - assert "AKIAIOSFODNN7EXAMPLE" not in on_screen - assert "AKIAIOSFODNN7EXAMPLE" not in in_a_copy + assert "glpat-IOSFODNN7EXAMPLE" not in on_screen + assert "glpat-IOSFODNN7EXAMPLE" not in in_a_copy _assert_nothing_reached_the_reader(c) @pytest.mark.asyncio @@ -702,7 +702,7 @@ async def test_a_key_split_between_reasoning_and_the_answer_is_closed(self) -> N c = FakeClient() r = _capped_renderer(c, cap=200) await r.on_turn_start() - await r.on_thinking("thinking, the key is AKIAIOSF") + await r.on_thinking("thinking, the key is glpat-IOSF") await r._push(force=True) # The bubble ages past the stream lifetime with its reasoning ACCEPTED and # displayed (not refused): the next push rolls to a fresh bubble. @@ -725,7 +725,7 @@ def _seen(fc: FakeClient) -> list[str]: "".join(canonicalize_display(b) for b in _seen(c)), canonicalize_display("".join(_seen(c))), ): - assert "AKIAIOSFODNN7EXAMPLE" not in reading + assert "glpat-IOSFODNN7EXAMPLE" not in reading assert _default_redactor(reading) == reading, "the key rejoined on screen" @pytest.mark.asyncio @@ -741,14 +741,14 @@ async def test_a_refused_reasoning_frame_is_not_taken_as_the_seam(self) -> None: c = FakeClient() r = _capped_renderer(c, cap=200) await r.on_turn_start() - await r.on_thinking("reasoning, the key is AKIAIOSF") + await r.on_thinking("reasoning, the key is glpat-IOSF") await r._push(force=True) await r.on_thinking(" and some more reasoning after it") await r._push(force=True) # Both reasoning frames are candidates the fresh bubble is graded against — # the prefix-ending one is NOT dropped. assert any( - "AKIAIOSF" in s and s.endswith("AKIAIOSF") for s in r._shown_reasonings + "glpat-IOSF" in s and s.endswith("glpat-IOSF") for s in r._shown_reasonings ), "the credential-prefix reasoning frame is retained as a candidate" # The bubble ages out (reasoning displayed, no answer yet); the answer opens # with the completion and rolls to a fresh bubble. @@ -763,10 +763,10 @@ async def test_a_refused_reasoning_frame_is_not_taken_as_the_seam(self) -> None: # Whichever reasoning the reader sees, the answer head is redacted so no # candidate rejoins the key. for candidate in ( - "reasoning, the key is AKIAIOSF", - "reasoning, the key is AKIAIOSF and some more reasoning after it", + "reasoning, the key is glpat-IOSF", + "reasoning, the key is glpat-IOSF and some more reasoning after it", ): - assert "AKIAIOSFODNN7EXAMPLE" not in canonicalize_display( + assert "glpat-IOSFODNN7EXAMPLE" not in canonicalize_display( candidate + answer_frames[-1] ), "the key rejoined across the reasoning seam" @@ -781,18 +781,18 @@ async def test_a_second_reasoning_roll_keeps_the_first_rolls_seam(self) -> None: c = FakeClient() r = _capped_renderer(c, cap=200) await r.on_turn_start() - await r.on_thinking("reasoning, the key is AKIAIOSF") + await r.on_thinking("reasoning, the key is glpat-IOSF") await r._push(force=True) # Roll 1: the reasoning bubble is sealed; rolling captures its seam. c.dead_streams.add(r._stream_id) r._roll_if_sealed() - assert any(s.endswith("AKIAIOSF") for s in r._reasoning_seams), "roll 1 captured the seam" + assert any(s.endswith("glpat-IOSF") for s in r._reasoning_seams), "roll 1 captured the seam" # Roll 2: the fresh bubble is sealed too, still before any answer and with # no new reasoning frame — _shown_reasonings is empty. c.dead_streams.add(r._stream_id) r._roll_if_sealed() assert any( - s.endswith("AKIAIOSF") for s in r._reasoning_seams + s.endswith("glpat-IOSF") for s in r._reasoning_seams ), "the second roll wiped the first roll's reasoning seam" @pytest.mark.asyncio @@ -807,10 +807,10 @@ async def test_accepted_reasoning_frames_collapse_to_the_newest(self) -> None: c = FakeClient() r = _capped_renderer(c, cap=200) await r.on_turn_start() - await r.on_thinking("the key is AKIAIOSF") + await r.on_thinking("the key is glpat-IOSF") await r._push(force=True) first = r._shown_reasonings[-1] - assert first.endswith("AKIAIOSF"), "the prefix-ending frame was captured" + assert first.endswith("glpat-IOSF"), "the prefix-ending frame was captured" for i in range(30): await r.on_thinking(f" step {i}") await r._push(force=True) @@ -835,7 +835,7 @@ async def test_a_displayed_prefix_is_not_evicted_under_sustained_rejection(self) r = _capped_renderer(c, cap=200) await r.on_turn_start() # One accepted frame first — this is the one that stays on screen. - await r.on_thinking(" the key is AKIAIOSF") + await r.on_thinking(" the key is glpat-IOSF") await r._push(force=True) first = r._shown_reasonings[-1] # Now the stream carries an outstanding rejection; later frames are not @@ -959,7 +959,7 @@ async def test_the_newest_frozen_seam_is_never_sliced_across_rotations(self) -> # Prior rolls already filled _reasoning_seams to the cap; this bubble then # sealed on a NEWEST frozen prefix ending at a credential prefix. r._reasoning_seams = [f"frozen prefix {i}" for i in range(_MAX_REASONING_CANDIDATES)] - r._shown_reasonings = ["reasoning, the key is AKIAIOSF"] + r._shown_reasonings = ["reasoning, the key is glpat-IOSF"] newest = r._shown_reasonings[-1] c.dead_streams.add(r._stream_id) r._roll_if_sealed() @@ -971,12 +971,12 @@ async def test_the_newest_frozen_seam_is_never_sliced_across_rotations(self) -> @pytest.mark.asyncio async def test_a_space_separated_continuation_is_not_over_redacted(self) -> None: # GPT F1: WeCom shows ONE continuous answer across the seam, so boundary - # whitespace is REAL on-screen text. A sealed tail ending `AKIAIOSF` and a + # whitespace is REAL on-screen text. A sealed tail ending `glpat-IOSF` and a # continuation opening ` ODNN7EXAMPLE` read as two space-separated tokens — # NOT a key. The stripped repair (for separate-message channels) would strip # the space, see a join, and corrupt harmless prose; the verbatim grade must # leave it intact. - c = await _stream_across_a_seam("AKIAIOSF", " ODNN7EXAMPLE and ordinary prose") + c = await _stream_across_a_seam("glpat-IOSF", " ODNN7EXAMPLE and ordinary prose") on_screen, in_a_copy = _reader_views(c) # The two tokens are shown with their separating space, unredacted. assert "ODNN7EXAMPLE and ordinary prose" in on_screen, ( @@ -987,13 +987,13 @@ async def test_a_space_separated_continuation_is_not_over_redacted(self) -> None @pytest.mark.asyncio async def test_a_no_space_split_across_the_seam_is_still_closed(self) -> None: - # The verbatim grade still catches a GENUINE split: `AKIAIOSF` directly + # The verbatim grade still catches a GENUINE split: `glpat-IOSF` directly # abutting `ODNN7EXAMPLE` with no separator forms the key on screen and must # be redacted. - c = await _stream_across_a_seam("AKIAIOSF", "ODNN7EXAMPLE") + c = await _stream_across_a_seam("glpat-IOSF", "ODNN7EXAMPLE") on_screen, in_a_copy = _reader_views(c) - assert "AKIAIOSFODNN7EXAMPLE" not in on_screen - assert "AKIAIOSFODNN7EXAMPLE" not in in_a_copy + assert "glpat-IOSFODNN7EXAMPLE" not in on_screen + assert "glpat-IOSFODNN7EXAMPLE" not in in_a_copy _assert_nothing_reached_the_reader(c) @pytest.mark.asyncio