The integrity requirement
The AFL Brownlow Medal is a live-broadcast voting event. Vote integrity has to survive:
- A regulator audit (the AFL’s integrity unit).
- A media accusation that votes were tampered with.
- A platform-engineering team that’s well-intentioned but human.
The architecture has to make tampering not just hard, but provably absent — verifiable by parties who don’t trust the platform team.
Cloud KMS for signing
Every vote was signed at submission. The signing key lived in Cloud KMS; the platform code called KMS.Sign(key, voteBytes) and got a signature back.
client := kms.NewKeyManagementClient(ctx, ...)
resp, _ := client.AsymmetricSign(ctx, &kmspb.AsymmetricSignRequest{
Name: "projects/.../locations/.../keyRings/brownlow/cryptoKeys/vote-signer/cryptoKeyVersions/1",
Digest: &kmspb.Digest{Digest: &kmspb.Digest_Sha256{Sha256: hashVote(vote)}},
})
storeVoteWithSignature(vote, resp.Signature)
The key never left KMS. Even the platform team’s code couldn’t read it. Even a compromised platform host couldn’t forge signatures — it could request signatures (which are logged), but not retrieve the key.
What this gives the auditor
The AFL’s integrity team had:
- Read access to the votes table in Spanner.
- Read access to KMS verify (not sign).
For any vote, they could:
client := kms.NewKeyManagementClient(ctx, integrityCreds)
verifyResp, _ := client.AsymmetricVerify(ctx, &kmspb.AsymmetricVerifyRequest{
Name: "...vote-signer/cryptoKeyVersions/1",
Signature: vote.Signature,
Digest: &kmspb.Digest{Digest: &kmspb.Digest_Sha256{Sha256: hashVote(vote)}},
})
// verifyResp.Success = true → vote is genuine
The auditor verified votes without trusting the platform team. The platform team couldn’t fake signatures because the key wasn’t accessible. The separation of duties — platform can sign, integrity can verify — was enforced by KMS IAM, not by policy.
Security Command Center during the broadcast
SCC ran continuously. The monitored controls:
- IAM anomalies. Any IAM change during the broadcast window (there shouldn’t be any).
- API anomalies. Unusual response patterns from the vote API.
- Network anomalies. Unusual traffic patterns at the load balancer.
- Workload identity drift. Cloud Run service accounts shouldn’t change permissions during the window.
SCC findings during the broadcast went to a dedicated Slack channel staffed by a 2-person security team — not the broadcast on-call. Different team; different priorities; integrity not operations.
The findings during the broadcast
Across the season (multiple broadcast windows):
- 0 integrity-affecting findings.
- ~12 noise findings (Looker dashboard rebuilds, backup jobs, scheduled rotations).
- 3 non-noise findings investigated within 5 minutes.
The non-noise findings were: 1. A new IAM binding added by an unrelated team in the same project (out of scope for the broadcast; reviewed and OK). 2. A Cloud Run revision deployment that hit a brief authentication spike during cold start (resolved within minutes). 3. A spike in 403s from one geographic region (a known bot scraper; rate-limited).
None of these affected votes. SCC made them visible; the integrity team had context to decide on the spot.
What I’d carry forward
For any high-integrity workload during a high-stakes event:
- Move integrity-critical operations into managed services you can’t bypass. KMS for signing; the platform team can’t fake votes because it can’t sign without leaving an audit trail.
- Separate the verifier from the signer. The platform team signs; the integrity team verifies. Different credentials; different blast radii.
- Run SCC with a dedicated team during the window. The on-call’s attention is on operations; the integrity team’s attention is on findings.
The architecture wasn’t novel. The discipline around integrity was the differentiator. Same architecture without the discipline produces the same protections in theory and nothing in practice.