API reference: no example reads as a real secret
The webhook examples carried a made-up signing secret in g1t's whsec_ format, which GitHub's secret scanning flagged as a Stripe webhook secret (alert #1). It was never a real secret: g1t seals webhook secrets and never returns them after creation. Examples now write whsec_… as the others do, and a test fails on any example that reads as a real credential.
3 files+27−40/3 viewed
| 688 | 688 | "apps/docs/src/data/openapi.json is out of date: run G1T_WRITE_OPENAPI=1 cargo test -p g1t-api openapi" | |
| 689 | 689 | ); | |
| 690 | 690 | } | |
| 691 | + | ||
| 692 | + | /// Examples never hold anything that reads as a real credential, which | |
| 693 | + | /// secret scanners rightly flag in a public repository: they end in `…` | |
| 694 | + | /// after the prefix, as `whsec_…` and `g1t_…` do. | |
| 695 | + | #[test] | |
| 696 | + | fn examples_hold_no_real_looking_secrets() { | |
| 697 | + | let prefixes = ["whsec_", "g1t_", "sk_live_", "sk_test_", "ghp_", "github_pat_", "xoxb-", "AKIA"]; | |
| 698 | + | for (line, text) in REFERENCE.lines().enumerate() { | |
| 699 | + | for prefix in prefixes { | |
| 700 | + | let mut rest = text; | |
| 701 | + | while let Some(at) = rest.find(prefix) { | |
| 702 | + | let after = &rest[at + prefix.len()..]; | |
| 703 | + | let run = after.chars().take_while(|c| c.is_ascii_alphanumeric()).count(); | |
| 704 | + | assert!( | |
| 705 | + | run < 12, | |
| 706 | + | "reference.json line {}: `{prefix}` followed by {run} characters reads as a real secret; write `{prefix}…`", | |
| 707 | + | line + 1 | |
| 708 | + | ); | |
| 709 | + | rest = after; | |
| 710 | + | } | |
| 711 | + | } | |
| 712 | + | } | |
| 713 | + | } | |
| 691 | 714 | } |
| 2108 | 2108 | "lastStatus": "delivered", | |
| 2109 | 2109 | "lastDeliveredAt": "2026-10-04T15:42:07.611Z" | |
| 2110 | 2110 | }, | |
| 2111 | − | "secret": "whsec_4be1a07c93d2f5e8a6b1c0d9e2f3a4b5c6d79c2e" | |
| 2111 | + | "secret": "whsec_…" | |
| 2112 | 2112 | }, | |
| 2113 | 2113 | "notes": "A ping is sent before the response, so `lastStatus` is usually set already. When g1t made the signing secret, `secret` holds it: it is shown only this once. See [webhooks](/guides/webhooks/)." | |
| 2114 | 2114 | }, | |
| 2136 | 2136 | "lastStatus": "delivered", | |
| 2137 | 2137 | "lastDeliveredAt": "2026-10-04T15:42:07.611Z" | |
| 2138 | 2138 | }, | |
| 2139 | − | "secret": "whsec_4be1a07c93d2f5e8a6b1c0d9e2f3a4b5c6d79c2e" | |
| 2139 | + | "secret": "whsec_…" | |
| 2140 | 2140 | }, | |
| 2141 | 2141 | "notes": "A ping is sent before the response, so `lastStatus` is usually set already. When g1t made the signing secret, `secret` holds it: it is shown only this once. See [webhooks](/guides/webhooks/)." | |
| 2142 | 2142 | }, |
| 3839 | 3839 | "lastStatus": "delivered", | |
| 3840 | 3840 | "lastDeliveredAt": "2026-10-04T15:42:07.611Z" | |
| 3841 | 3841 | }, | |
| 3842 | − | "secret": "whsec_4be1a07c93d2f5e8a6b1c0d9e2f3a4b5c6d79c2e" | |
| 3842 | + | "secret": "whsec_…" | |
| 3843 | 3843 | } | |
| 3844 | 3844 | } | |
| 3845 | 3845 | } | |
| 4830 | 4830 | "lastStatus": "delivered", | |
| 4831 | 4831 | "lastDeliveredAt": "2026-10-04T15:42:07.611Z" | |
| 4832 | 4832 | }, | |
| 4833 | − | "secret": "whsec_4be1a07c93d2f5e8a6b1c0d9e2f3a4b5c6d79c2e" | |
| 4833 | + | "secret": "whsec_…" | |
| 4834 | 4834 | } | |
| 4835 | 4835 | } | |
| 4836 | 4836 | } |