{
  "compartment_id": "section-5-1",
  "number": "Section 5.1",
  "title_local": "The standards were public and dated: Valve builds against them every day",
  "title_english": "The standards were public and dated: Valve builds against them every day",
  "source_url": "https://phishdestroy.io/steam_dossier/#integration-paradox-title",
  "source_document": "index.html",
  "content": {
    "html": "<section aria-labelledby=\"integration-paradox-title\" class=\"integration-paradox\" id=\"integration-paradox\">\n<div class=\"ip-head\">\n<span class=\"kicker\">Section 5.1 — The standards were not unpublished</span>\n<h3 id=\"integration-paradox-title\">Valve builds against these rules every day. It did not build to them here.</h3>\n<p class=\"ip-lede\">Steam ships on the App Store and Google Play, sells through the major card processors, and consumes third-party APIs like any other large platform. Each of those relationships carries a published, dated security requirement that Valve must satisfy to keep operating. Set the dates of those requirements against the dates on which Steam's own Web API acquired the same protections. <b>Nothing below is a private standard, an internal memo or a trade secret: every row is a public document with a publication date.</b></p>\n</div>\n<div class=\"ip-table-wrap\">\n<table class=\"ip-table\">\n<caption class=\"sr-only\">Published external security requirements, with their dates, set against the date the Steam Web API acquired the equivalent control</caption>\n<thead><tr><th scope=\"col\">The published standard, and the date it took effect</th><th scope=\"col\">The Steam Web API on the same question</th></tr></thead>\n<tbody>\n<tr>\n<th scope=\"row\"><b>Scoped authorisation</b><span>OAuth 2.0 — RFC 6749, <time datetime=\"2012-10\">October 2012</time>. Section 3.3 defines <code>scope</code> so a client receives only the access it asks for. It has been the default of every major platform API since.</span></th>\n<td><b>Granular scopes arrived on <time datetime=\"2026-01-16\">16 January 2026</time>.</b><span>Before that a single Steam Web API key carried full read and write over the account's trades regardless of why it was issued. <b class=\"ip-gap\">Thirteen years and three months</b> after the specification that defines the control.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>A key is not an authorisation</b><span>Google's own Cloud documentation: <q>A standard API key doesn't authenticate a principal</q>, and for APIs that create or manage resources, <q>don't use authorization keys in production.</q></span></th>\n<td><b>The Steam Web API key was exactly that.</b><span>A bearer string, issued to an account, sufficient on its own to read the inventory, cancel a pending trade and send a new one. No principal was authenticated at the point of use.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>Multi-factor authentication on privileged access</b><span>PCI DSS 3.2, requirement 8.3 — mandatory from <time datetime=\"2018-02-01\">1 February 2018</time> for all non-console administrative and all remote access to the cardholder data environment. Apple then required two-factor authentication of every Developer Program account holder from <time datetime=\"2019-02-27\">27 February 2019</time>: <q>developers with the Account Holder role in a developer program will need to enable two-factor authentication to sign in.</q></span></th>\n<td><b>A second factor was required to create an API key from <time datetime=\"2023-12-04\">4 December 2023</time>.</b><span>Until then a stolen session cookie was enough, with no prompt on the account holder's phone and no notification afterwards. <b class=\"ip-gap\">Four years and nine months</b> after Apple made Valve itself use a second factor merely to sign in to a developer portal.</span></td>\n</tr>\n<tr>\n<th scope=\"row\"><b>Credential lifecycle and revocation</b><span>Twitch requires of every third-party application: <q>Your app must validate the OAuth token when it starts and on an hourly basis thereafter</q>, and states that it audits for applications that do not. Its legacy v5 API was retired outright on <time datetime=\"2022-02-28\">28 February 2022</time> on a published schedule.</span></th>\n<td><b>No published key-lifecycle record.</b><span>The 2023 change protected the creation endpoint. No Valve statement located with it addresses keys already registered, and no changelog accompanied the change at all. Whether keys created before it were invalidated cannot be established from public data — which is the question a data subject would need answered to know whether a key created on their account years earlier is still live.</span></td>\n</tr>\n</tbody>\n</table>\n</div>\n<div class=\"api-token-comparator ds-b8c11f1dd6d8\" id=\"token-comparator\">\n<div class=\"ds-96c219008143\">\n<div>\n<span class=\"kicker ds-7c59d7cf7795\">Architectural Benchmark // Token Architecture</span>\n<h4 class=\"ds-252f5d8f5e75\">GitHub Fine-Grained Scopes vs Valve Steam Web API</h4>\n<p class=\"ds-db03930d207b\">Valve developers manage open-source software on GitHub daily using granular least-privilege tokens. Compare that with the monolithic key issued to 130M Steam players.</p>\n</div>\n<button class=\"btn ds-9e6d8af4ecf3\" id=\"btn-simulate-mitm\" type=\"button\">\n<span class=\"ds-a70c68aa4a03\"></span>\n<span id=\"mitm-btn-label\">Simulate Phishing Interception (MITM)</span>\n</button>\n</div>\n<div class=\"grid grid-cols-1 md:grid-cols-2 gap-6 items-stretch\">\n\n<div class=\"ds-38a0569b4e06\">\n<div>\n<div class=\"ds-185ca53d2c80\">\n<div class=\"ds-a4e017b7b0ef\">\n<svg viewBox=\"0 0 24 24\" class=\"ds-2449c9280001\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z\"></path></svg>\n<span class=\"ds-6716093f1afa\">GitHub Fine-Grained Token</span>\n</div>\n<span class=\"ds-6b1f6dfe1a52\">Used by Valve on GitHub</span>\n</div>\n<p class=\"ds-d8208f515427\">Fine-grained token with scoped isolation and mandatory lifecycle enforcement.</p>\n<div class=\"ds-7230026cd28b\">\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Repository Access:</span>\n<span class=\"ds-f5aee7fc5fc4\">Selected Repos only (1 repo)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Issue Permissions:</span>\n<span class=\"ds-062563832b98\">Read-only [✓]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Code &amp; Secrets:</span>\n<span class=\"ds-acc22d4dbe8e\">No access [✕]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Expiration:</span>\n<span class=\"ds-062563832b98\">30 Days (Mandatory TTL)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Audit Logging:</span>\n<span class=\"ds-062563832b98\">IP, User-Agent &amp; Timestamp</span>\n</div>\n</div>\n</div>\n<div id=\"github-mitm-result\" class=\"ds-08e070b7c49a\">\n<strong>Security Posture:</strong> Least-privilege token limits damage to a single read-only resource.\n      </div>\n</div>\n\n<div class=\"ds-ce8dade9d8c2\">\n<div>\n<div class=\"ds-185ca53d2c80\">\n<div class=\"ds-a4e017b7b0ef\">\n<span class=\"ds-386ccb939d53\">!</span>\n<span class=\"ds-6716093f1afa\">Valve Steam Web API Key</span>\n</div>\n<span class=\"ds-32370dc253e2\">Issued to 130M Users</span>\n</div>\n<p class=\"ds-d8208f515427\">Single 32-character master string carrying all-or-nothing trade and inventory authority.</p>\n<div class=\"ds-7230026cd28b\">\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Account Access:</span>\n<span class=\"ds-f60fb1042a0e\">FULL ACCOUNT (Monolithic)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Trade Management:</span>\n<span class=\"ds-f60fb1042a0e\">Read, Cancel, Decline [!]</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Granular Scopes:</span>\n<span class=\"ds-f60fb1042a0e\">NONE (Arrived 2026, 13y late)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Expiration:</span>\n<span class=\"ds-f60fb1042a0e\">NEVER (Valid indefinitely)</span>\n</div>\n<div class=\"ds-0bd2243377cf\">\n<span class=\"ds-acc22d4dbe8e\">Audit Logging:</span>\n<span class=\"ds-f60fb1042a0e\">NONE (Zero IP history for user)</span>\n</div>\n</div>\n</div>\n<div id=\"valve-mitm-result\" class=\"ds-772039b58e09\">\n<strong>Vulnerability:</strong> Stolen key allows silent interception of all outgoing trade offers.\n      </div>\n</div>\n</div>\n</div>\n<div class=\"ip-question\">\n<span class=\"kicker\">The standard applied in one direction</span>\n<p>Suppose a vendor Valve depends on — a cloud provider, a payment processor, a CDN — left a credential endpoint without a second factor, and months later Valve's own corporate data left through a key minted at that endpoint. Would Valve accept that the fault lay with whoever clicked the link? The archived refusals preserved in this dossier answer the mirror-image question for the user: the position taken is that the account holder created the key and bears the loss. <b>The same architecture is described as the vendor's failure in one direction and the user's responsibility in the other.</b> Which it is, is not a technical question, and it is not one this investigation can settle — it is what a court or a supervisory authority decides.</p>\n</div>\n<div class=\"ip-reversal\">\n<span class=\"kicker\">Illustration, not evidence — the standard read back the other way</span>\n<ul>\n<li>A payment processor that let a third-party script mint a full-privilege transaction credential from a browser cookie alone, with no prompt to the account holder.</li>\n<li>An identity provider that closed the hole its tokens were minted through and published nothing about the tokens already minted.</li>\n<li>A bank that answered a disputed transfer by observing that the credential used was registered on the customer's own account, and closed the ticket.</li>\n</ul>\n<p>None of these is offered as a finding about any named company. They are the same design decisions, moved to a setting where the supervisory response is well documented — which is the comparison a regulator is being asked to make.</p>\n</div>\n<p class=\"ip-verdict\"><b>What the record establishes:</b> the controls absent from the Steam Web API were public, dated and, in several cases, conditions Valve had to satisfy to keep shipping its own products. The interval between each standard and the equivalent Steam change is measurable and is set out above. <b>What it does not establish is why.</b> No Valve statement of reasons for any of these intervals has been located, and none is assumed here; that record exists inside Valve and has not been published.</p>\n<p class=\"ip-source\">Sources, each a public document: OAuth 2.0 — <a href=\"https://datatracker.ietf.org/doc/rfc6749/\" rel=\"noopener noreferrer\" target=\"_blank\">RFC 6749, October 2012 ↗</a> · Google Cloud — <a href=\"https://docs.cloud.google.com/docs/authentication/api-keys\" rel=\"noopener noreferrer\" target=\"_blank\">API keys documentation ↗</a> · PCI DSS 3.2 requirement 8.3 — <a href=\"https://listings.pcisecuritystandards.org/pdfs/PCI_DSS_Resource_Guide_(003).pdf\" rel=\"noopener noreferrer\" target=\"_blank\">PCI SSC resource guide ↗</a> · Apple — <a href=\"https://developer.apple.com/news/?id=02202019a\" rel=\"noopener noreferrer\" target=\"_blank\">Upcoming Two-Factor Authentication Requirement for Account Holders, 20 February 2019 ↗</a> <a class=\"archived-link\" href=\"https://web.archive.org/web/20250506070026/https://developer.apple.com/news/?id=02202019a\" rel=\"noopener noreferrer\" target=\"_blank\">archived 2025-05-06 ↗</a> · Twitch — <a href=\"https://dev.twitch.tv/docs/authentication/validate-tokens/\" rel=\"noopener noreferrer\" target=\"_blank\">token validation requirement ↗</a> and the <a href=\"https://discuss.dev.twitch.com/t/legacy-twitch-api-v5-i-e-kraken-shutdown-reminder-february-28-2022/36589\" rel=\"noopener noreferrer\" target=\"_blank\">v5 shutdown notice ↗</a> <a class=\"archived-link\" href=\"https://web.archive.org/web/20250127085635/https://discuss.dev.twitch.com/t/legacy-twitch-api-v5-i-e-kraken-shutdown-reminder-february-28-2022/36589\" rel=\"noopener noreferrer\" target=\"_blank\">archived 2025-01-27 ↗</a>. Steam's own dates are those in the update record in this section; the 2023 and 2026 entries are the ones Valve shipped without a changelog. Retrieved 2026-09-22.</p>\n</section>"
  },
  "original_content_sha256": "494d3acfc3a0b3d03355278324d0e9ad28128e4dd8cce7ba3585be5945235223",
  "author_pseudonym": "Agent Lucia",
  "schema": "phishdestroy.macro-fact.v1",
  "language": "en",
  "aggregator": "PhishDestroy",
  "exports": {
    "pdf": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_1_agent_lucia.pdf",
    "json": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_1_agent_lucia.json",
    "signature": "/steam_dossier/exports/agent-protocol/files/en/steam_dossier_section_5_1_agent_lucia.json.asc"
  },
  "integrity": {
    "signed_object": "steam_dossier_section_5_1_agent_lucia.json",
    "signature_file": "steam_dossier_section_5_1_agent_lucia.json.asc",
    "signing_key_fingerprint": "129FC7F39C40C69D2EF3C329BFCF9E8DD295EE01",
    "scope": "Exact JSON bytes, including macro-fact author and corresponding PDF SHA-256. PhishDestroy is the integrity signer; original evidence attribution is unchanged."
  },
  "pdf": {
    "filename": "steam_dossier_section_5_1_agent_lucia.pdf",
    "sha256": "56d98c4a471164225d073d3c03a7bea7c989ecd83780d50e543cecce58a00297",
    "pages": 5
  }
}
