Add security.txt to the settlement program - #91
Conversation
Embed machine-readable security contact information in the program binary, following the security.txt standard for Solana programs (https://github.com/neodyme-labs/solana-security-txt). A researcher who finds a problem typically has only the program address to go on; shipping the contacts inside the binary means they can be recovered from the deployed program alone. The macro definition is copied into `programs/settlement` rather than pulled in as a dependency: upstream is a single `macro_rules!` with no runtime code, so inlining it produces the same output without adding supply chain surface to a program we compile on-chain. Two deviations from upstream worth noting: - The `link_section` attribute is gated on `target_os = "solana"` rather than upstream's `target_arch = "bpf"`, which no longer matches any Solana target. `cargo build-sbf` builds for `sbpf-solana-solana`, which reports `target_arch = "sbf"`, so upstream's gate never fires and the `.security.txt` ELF section is silently dropped. Some gate is required because a bare section name is invalid on Mach-O hosts. - `policy` carries free text instead of a link, so the one required field every parser surfaces also warns that this program is for testing only and should not be trusted with funds. The standard has no field for that, and a researcher reading the notice off a deployed program has no other way to learn it. `source_revision`/`source_release` are deliberately omitted: populating them from the build environment would make the binary depend on environment variables and break the byte-for-byte reproducibility that `just build-verified` establishes. Add an integration test that naively scans the built .so for the standard begin/end markers. The blob is never referenced from Rust, so nothing about the host build proves it survives compilation and linking into the deployed artifact — only reading the .so back does. The markers are counted rather than merely located, since the standard requires them to be unique for naive parsers to work. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
b4a6bb7 to
3827a65
Compare
| /// Copied from `solana-security-txt` v1.1.3 (dual-licensed MIT/Apache-2.0), | ||
| /// with the `link_section` gate corrected below. The upstream crate is a single |
There was a problem hiding this comment.
The code is a bit different. Also I don't really get what has been corrected in link_section.
| // - `source_revision` / `source_release`, which upstream suggests populating | ||
| // from the build environment. Doing so would make the binary depend on | ||
| // environment variables and break the byte-for-byte reproducibility that | ||
| // `just build-verified` establishes. `solana-verify` already pins the | ||
| // deployed binary to a commit. |
There was a problem hiding this comment.
I expect this is only true if we hardcode the release/revision, not in general for envs.
For the release, I expect env!("CARGO_PKG_VERSION") to work here because it should be available.
The revision is harder because there's no env for that AFAIK. We can work around it (build.rs) but I don't think it's worth it since we have reproducible builds.
Anyway, the comment doesn't say the most important thing: we don't need the commit because we have the exact code thanks to reproducibility.
| // Also required. Takes a link or free text; free text lets the one field | ||
| // every parser surfaces carry the warning that this isn't production | ||
| // software, which the standard has no dedicated field for. | ||
| policy: "TESTING ONLY: this program is an unaudited work in progress, \ | ||
| deployed for testing purposes only. Do not approve this contract \ | ||
| to spend more funds than you can expect to lose.", |
There was a problem hiding this comment.
I like that you can see the text in the explorer.
What about also creating a SECURITY.txt with this text? Later we can replace the text here with a link to that file once we're actually finalizing the code.
| } | ||
|
|
||
| #[test] | ||
| fn program_binary_contains_security_txt() { |
| }; | ||
| } | ||
|
|
||
| // Deliberately omitted: |
There was a problem hiding this comment.
You could move this block after the // Optional fields. block, it reads nicely and consistently then.
|
will reopen when/if its necessary, as this ticket has been postponed. |

Embeds machine-readable security contact information in the settlement program binary, following the security.txt standard for Solana programs.
Motivation
We are still missing one element on the etherscan display of the settlement program:
Fair note though, many other apparently very popular solana programs, such as Pump.fun AMM or Jupiter Aggregator programs, do NOT publish a
security.txt(or a solana program verification, for that matter), so we could probably get a way with deploying without this if we really wanted to.Considerations
programs/settlement/src/security_txt.rsinlines the macro definition rather than addingsolana-security-txtas a dependency. Upstream is a singlemacro_rules!with no runtime code, so this produces identical output without adding supply chain surface to a program we compile on-chain.source_revision/source_releaseare deliberately omitted. Upstream suggests populating them from the build environment, but that would make the binary depend on environment variables and break the byte-for-byte reproducibilityjust build-verifiedestablishes.solana-verifyalready pins the deployed binary to a commit.Test
tests/security_txt.rsnaively scans the built.soto verify the presence of the security.txt section is included in the compiled .so program.Verification
The
.security.txtsection now appears in the built artifact (16 bytes — a&strstatic is a fat pointer, so the section holds the pointer/length pair while the bytes stay in.rodata):For the ultimate test--I verified it is recognized by the block explorer on our devnet Mooohh program.

🤖 Generated with Claude Code