Skip to content

Commit 6c7de4f

Browse files
committed
Add security response policy
1 parent 738c019 commit 6c7de4f

5 files changed

Lines changed: 123 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ The first production milestone is M3UA over a transport abstraction. SCCP, TCAP,
4040
| External interoperability evidence | Phase 7 registry added for peer-stack lab results and packet trace references; current evidence inventory is empty until real lab artifacts are captured |
4141
| Release candidates | Phase 7 manifest added for package version, source commit, internal release gates, and commercial promotion gates |
4242
| Package governance | Phase 7 policy added: current package metadata is tracked; commercial target still requires package signing and SBOM automation |
43+
| Security governance | Phase 7 security policy added with private disclosure and severity response targets |
4344

4445
## Requirements
4546

@@ -127,6 +128,7 @@ if (!M3uaTypedMessageParser.TryParseSignallingCongestion(
127128
- [SCTP Transport](docs/SCTP_TRANSPORT.md)
128129
- [References](docs/REFERENCES.md)
129130
- [Quality and contribution rules](docs/QUALITY.md)
131+
- [Security policy](SECURITY.md)
130132

131133
## Project Direction
132134

SECURITY.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Security Policy
2+
3+
SIGTRAN.NET uses private disclosure for security issues.
4+
5+
## Reporting
6+
7+
Report suspected vulnerabilities to `security@sigtran.net`.
8+
9+
Do not publish exploit details publicly before the issue has been triaged and a coordinated fix path is available.
10+
11+
## Response Targets
12+
13+
| Severity | Target response |
14+
| --- | --- |
15+
| Critical | 2 days |
16+
| High | 7 days |
17+
| Moderate | 14 days |
18+
| Low | 14 days |
19+
20+
The SDK exposes this policy through `SigtranSecurityPolicy.CreateCurrentPolicy()` so release tooling and downstream governance checks can reference the same response targets.

docs/PHASE7_COMMERCIALIZATION.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,9 @@ Release candidates can be published after internal gates pass. Promotion to comm
6262
`SigtranPackageGovernance.CreateCommercialTargetPolicy()` adds the commercial governance target: package signing and SBOM publication.
6363

6464
Commercial release governance remains incomplete until signing and SBOM automation are added to the release pipeline.
65+
66+
## Security Policy
67+
68+
`SECURITY.md` defines the public disclosure process and response targets. `SigtranSecurityPolicy.CreateCurrentPolicy()` exposes the same values to SDK governance tooling.
69+
70+
Critical vulnerabilities target a 2-day response. High severity vulnerabilities target a 7-day response. Other severities target a 14-day response.

src/sigtran.net.Tests/Program.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
Run("SIGTRAN interop evidence registry tracks lab results", SigtranInteropEvidenceRegistryTracksLabResults);
2626
Run("SIGTRAN release candidate manifest reports promotion gates", SigtranReleaseCandidateManifestReportsPromotionGates);
2727
Run("SIGTRAN package governance reports commercial requirements", SigtranPackageGovernanceReportsCommercialRequirements);
28+
Run("SIGTRAN security policy reports response targets", SigtranSecurityPolicyReportsResponseTargets);
2829
Run("TCAP BER element encodes short and long lengths", TcapBerElementEncodesShortAndLongLengths);
2930
Run("TCAP transaction identifiers use BER context tags", TcapTransactionIdentifiersUseBerContextTags);
3031
Run("TCAP BER Invoke component round-trips", TcapBerInvokeComponentRoundTrips);
@@ -328,6 +329,16 @@ static void SigtranPackageGovernanceReportsCommercialRequirements()
328329
Assert(commercial.Describe().Contains("sbom=True", StringComparison.Ordinal), commercial.Describe());
329330
}
330331

332+
static void SigtranSecurityPolicyReportsResponseTargets()
333+
{
334+
SigtranSecurityResponsePolicy policy = SigtranSecurityPolicy.CreateCurrentPolicy();
335+
336+
Assert(policy.UsesPrivateDisclosure, "security policy should use private disclosure");
337+
AssertEqual(TimeSpan.FromDays(2), policy.GetResponseTime(SigtranSecuritySeverity.Critical), "critical security response time");
338+
AssertEqual(TimeSpan.FromDays(7), policy.GetResponseTime(SigtranSecuritySeverity.High), "high security response time");
339+
AssertEqual(TimeSpan.FromDays(14), policy.GetResponseTime(SigtranSecuritySeverity.Low), "low security response time");
340+
}
341+
331342
static void TcapBerElementEncodesShortAndLongLengths()
332343
{
333344
Span<byte> shortBuffer = stackalloc byte[8];
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
namespace sigtran.net.Core.Utilities;
2+
3+
/// <summary>
4+
/// Identifies security vulnerability severity.
5+
/// </summary>
6+
public enum SigtranSecuritySeverity
7+
{
8+
/// <summary>Low severity.</summary>
9+
Low,
10+
11+
/// <summary>Moderate severity.</summary>
12+
Moderate,
13+
14+
/// <summary>High severity.</summary>
15+
High,
16+
17+
/// <summary>Critical severity.</summary>
18+
Critical
19+
}
20+
21+
/// <summary>
22+
/// Describes the SDK security response policy.
23+
/// </summary>
24+
public sealed class SigtranSecurityResponsePolicy
25+
{
26+
/// <summary>Creates a security response policy.</summary>
27+
/// <param name="contact">The security contact.</param>
28+
/// <param name="criticalResponseTime">The critical issue response time.</param>
29+
/// <param name="highResponseTime">The high issue response time.</param>
30+
/// <param name="usesPrivateDisclosure">Whether private disclosure is required.</param>
31+
public SigtranSecurityResponsePolicy(
32+
string contact,
33+
TimeSpan criticalResponseTime,
34+
TimeSpan highResponseTime,
35+
bool usesPrivateDisclosure)
36+
{
37+
Contact = string.IsNullOrWhiteSpace(contact) ? throw new ArgumentException("Security contact is required.", nameof(contact)) : contact;
38+
CriticalResponseTime = criticalResponseTime <= TimeSpan.Zero ? throw new ArgumentOutOfRangeException(nameof(criticalResponseTime)) : criticalResponseTime;
39+
HighResponseTime = highResponseTime <= TimeSpan.Zero ? throw new ArgumentOutOfRangeException(nameof(highResponseTime)) : highResponseTime;
40+
UsesPrivateDisclosure = usesPrivateDisclosure;
41+
}
42+
43+
/// <summary>The security contact.</summary>
44+
public string Contact { get; }
45+
46+
/// <summary>The critical issue response time.</summary>
47+
public TimeSpan CriticalResponseTime { get; }
48+
49+
/// <summary>The high issue response time.</summary>
50+
public TimeSpan HighResponseTime { get; }
51+
52+
/// <summary>Whether private disclosure is required.</summary>
53+
public bool UsesPrivateDisclosure { get; }
54+
55+
/// <summary>Returns the response time for a severity.</summary>
56+
/// <param name="severity">The vulnerability severity.</param>
57+
/// <returns>The response time.</returns>
58+
public TimeSpan GetResponseTime(SigtranSecuritySeverity severity)
59+
{
60+
return severity switch
61+
{
62+
SigtranSecuritySeverity.Critical => CriticalResponseTime,
63+
SigtranSecuritySeverity.High => HighResponseTime,
64+
_ => TimeSpan.FromDays(14)
65+
};
66+
}
67+
}
68+
69+
/// <summary>
70+
/// Provides the SDK security policy.
71+
/// </summary>
72+
public static class SigtranSecurityPolicy
73+
{
74+
/// <summary>Creates the current security response policy.</summary>
75+
/// <returns>The current security response policy.</returns>
76+
public static SigtranSecurityResponsePolicy CreateCurrentPolicy()
77+
{
78+
return new(
79+
"security@sigtran.net",
80+
TimeSpan.FromDays(2),
81+
TimeSpan.FromDays(7),
82+
usesPrivateDisclosure: true);
83+
}
84+
}

0 commit comments

Comments
 (0)