RFC 9116 security.txt parser, validator, generator and audit toolkit for MoonBit.
Module: moyunijieshi1/moon-securitytxt
Version: 0.1.0-dev
Status: GitHub development
Repository: https://github.com/moyunijieshi1/moon-securitytxt
Mooncakes: not published
Maintainer: 谭海杰 <wx20061011@qq.com>| Field | Cardinality | Purpose |
|---|---|---|
| Contact | One or more | Ordered reporting channels; the first is preferred |
| Expires | Exactly one | Time after which the document is stale |
| Preferred-Languages | Zero or one | Equally preferred report languages |
| Other standard fields | Optional, repeatable | Policy, keys, acknowledgments, hiring and canonical locations |
| Extension fields | Optional, repeatable | Forward-compatible registered or private information |
let text =
"Contact: mailto:security@example.com\n" +
"Expires: 2027-01-01T00:00:00Z\n" +
"Preferred-Languages: en, de\n"
match parse_security_txt(text) {
Ok(doc) =>
match validate(doc) {
Ok(_) => println("valid; preferred contact: \{doc.preferred_contact().unwrap()}")
Err(err) => println("invalid: \{err.to_string()}")
}
Err(err) => println("parse error: \{err.to_string()}")
}moon run ./cmd/securitytxt-tool --target wasm-gc -- validate --text "Contact: mailto:a@example.com`nExpires: 2027-01-01T00:00:00Z`n"
moon run ./cmd/securitytxt-tool --target wasm-gc -- fresh --text "..." --now 2026-08-13T00:00:00Z| Path | Contents |
|---|---|
| *.mbt | Core library (parser, validator, serializer, audit, ...) |
| test_*.mbt | Named tests, property grids and truncation-fuzz suite |
| cmd/securitytxt-tool/ | CLI executable package |
| examples/ | Runnable examples (parse, validate, freshness, generate, audit) |
| docs/ | Architecture, API, testing, security, limitations, CLI |
| scripts/ | verify_all.ps1, count_code.py |
powershell -File scripts/verify_all.ps1pub(all) suberror SecurityTxtError {
SecurityTxtError(SecurityTxtErrorStage, SecurityTxtErrorKind, Int, Int, Int, String)
}pub struct AuditFinding {
kind : AuditFindingKind
severity : AuditSeverity
message : String
line : Int
} derive(Eq, Debug)pub struct SecurityFieldEntry {
field : SecurityField
line : Int
byte_offset : Int
} derive(Eq, Debug)pub struct SecurityTxt {
entries : Array[SecurityFieldEntry]
comments : Array[String]
signature : SignatureState
armor_headers : Array[String]
line_count : Int
byte_count : Int
} derive(Debug)fn SecurityTxtBuilder::acknowledgments(self : SecurityTxtBuilder, uri : String) -> SecurityTxtBuilderfn SecurityTxtBuilder::extension(self : SecurityTxtBuilder, name : String, value : String) -> SecurityTxtBuilderfn SecurityTxtBuilder::preferred_languages(self : SecurityTxtBuilder, tags : Array[String]) -> SecurityTxtBuilderpub(all) enum SecurityTxtErrorKind {
InvalidLine
MissingColon
EmptyFieldName
EmptyFieldValue
InvalidUtf8
InvalidUri
InvalidScheme
InvalidDateTime
InvalidLanguage
DuplicateExpires
DuplicatePreferredLanguages
DuplicateField
MissingContact
MissingExpires
ContextMismatch
InvalidContext
LimitExceeded
InvalidSignatureEnvelope
} derive(Eq, Debug)let EXPIRES_SOON_SECONDS : Int64let RFC3339_MAX_FRACTIONAL_DIGITS : Intfn audit(document : SecurityTxt, now : DateTime, context : SecurityTxtContext) -> Array[AuditFinding]fn audit_finding(kind : AuditFindingKind, severity : AuditSeverity, message : String, line : Int) -> AuditFindingfn check_field_value(field : SecurityField, line : Int, byte_offset : Int) -> Result[Unit, SecurityTxtError]fn check_uri_scheme(value : String, allowed : Array[String], field_name : String, line : Int, byte_offset : Int) -> Result[Unit, SecurityTxtError]fn contains_uri_illegal(value : String) -> Boolfn days_from_civil(year : Int, month : Int, day : Int) -> Int64fn days_in_month(year : Int, month : Int) -> Intfn div_floor_i64(a : Int64, b : Int64) -> Int64fn is_standard_field_name(name : String) -> Boolfn library_version() -> Stringfn make_utc(year : Int, month : Int, day : Int, hour : Int, minute : Int, second : Int) -> Result[DateTime, SecurityTxtError]fn make_utc_nanos(year : Int, month : Int, day : Int, hour : Int, minute : Int, second : Int, nanos : Int64) -> Result[DateTime, SecurityTxtError]fn parse_security_txt_bytes(input : Bytes, limits : Limits) -> Result[SecurityTxt, SecurityTxtError]fn parse_security_txt_with_limits(input : String, limits : Limits) -> Result[SecurityTxt, SecurityTxtError]fn security_txt(entries : Array[SecurityFieldEntry], comments : Array[String], signature : SignatureState, armor_headers : Array[String], line_count : Int, byte_count : Int) -> SecurityTxtfn security_txt_error(stage : SecurityTxtErrorStage, kind : SecurityTxtErrorKind, line : Int, column : Int, byte_offset : Int, message : String) -> SecurityTxtErrorfn split_signed_envelope(lines : Array[String], offsets : Array[Int]) -> Result[SignedPayload?, SecurityTxtError]fn standard_field_name(name : String) -> String?fn uri_scheme(value : String) -> String?fn validate_retrieval_context(document : SecurityTxt, context : SecurityTxtContext) -> Result[Unit, SecurityTxtError]RFC 9116 security.txt parser, validator, generator and audit toolkit for MoonBit.