Skip to content

Commit 52efbc7

Browse files
committed
docs: add security policy
1 parent ffbdd48 commit 52efbc7

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

SECURITY.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Security Policy
2+
3+
## Reporting a Vulnerability
4+
5+
**This is a public repository. Do not open a public GitHub issue for a security
6+
vulnerability** — that discloses it to everyone before a fix is available.
7+
8+
Instead, report privately through GitHub's **Private Vulnerability Reporting**:
9+
10+
1. Go to the **Security** tab of this repository.
11+
2. Click **Report a vulnerability**.
12+
3. Describe the problem, including steps to reproduce, affected version(s), and
13+
the impact.
14+
15+
We will acknowledge the report, keep you informed as we investigate, and
16+
coordinate the disclosure timeline and a fixed release with you. Please give us
17+
a reasonable window to ship a fix before any public disclosure.
18+
19+
## Scope
20+
21+
This repo is the **MarketData Java SDK** — a client library published to Maven
22+
Central and pulled into consumers' applications. It runs on the consumer's
23+
machine (or their servers), not on MarketData infrastructure. The security
24+
concerns that matter here are therefore about how the library treats *its
25+
consumers*:
26+
27+
- **Credential handling** — the caller's API token must never be logged
28+
verbatim, leaked in exception messages, or written to disk. Query strings are
29+
stripped from log output; tokens are redacted (`Tokens.redact`). Regressions
30+
here are in scope.
31+
- **Transport security** — TLS is validated by default and the SDK exposes no
32+
skip-verify option. Anything that weakens this is in scope.
33+
- **Injection into outbound requests** — request-building that lets caller
34+
input smuggle headers, path segments, or query parameters it shouldn't.
35+
- **Deserialization safety** — the Jackson-based response decoding path handling
36+
hostile or malformed API responses without RCE, resource exhaustion, or
37+
crashes that a consumer can't defend against.
38+
- **Supply-chain integrity of the published artifact** — the build, signing, and
39+
Maven Central publish pipeline (`tag-and-release.yml`, `publish.yml`), and the
40+
dependency tree of the shipped JAR.
41+
42+
Out of scope:
43+
44+
- **The MarketData API backend** itself. Report API/server vulnerabilities
45+
through the API's own channel, not here.
46+
- **Third-party dependencies.** Vulnerabilities in Gradle-resolved dependencies
47+
are tracked by Dependabot (see `.github/dependabot.yml`); report them upstream.
48+
We will bump the affected dependency here once a fixed version exists.
49+
50+
## Security Fix Policy
51+
52+
This policy governs how security fixes are applied to this repository, including
53+
fixes made by automated agents (e.g. Claude Code) working in the repo. It sorts
54+
every security fix into one of two tiers.
55+
56+
The dividing line for a **library** is *consumer compatibility*. A fix that any
57+
consumer can pick up by upgrading, with no source or behavior change on their
58+
side, is low-risk. A fix that forces consumers to change their code, recompile
59+
against a changed API, or adapt to changed runtime behavior is a breaking change
60+
and follows SemVer — those get the maintainer gate.
61+
62+
### Tier 1 — Fix immediately (no approval needed)
63+
64+
Security fixes that are **API- and behavior-compatible for legitimate
65+
consumers**. Existing callers keep compiling and keep working the same way after
66+
upgrading; only the vulnerability is closed.
67+
68+
These may be fixed, tested, and committed right away. Every Tier 1 fix must be
69+
called out in its commit message, in `CHANGELOG.md`, and in the summary reported
70+
to the maintainer, so nothing ships silently.
71+
72+
Typical Tier 1 fixes:
73+
74+
- Tightening credential redaction, or plugging a token/secret/PII leak into logs
75+
or exception messages
76+
- Fixing injection in request building (header/path/query smuggling) where valid
77+
caller input is unaffected
78+
- Hardening the response-deserialization path against malformed or hostile API
79+
responses (bounds, resource limits, null handling)
80+
- Correcting a logic flaw in an existing security check without changing its
81+
public contract
82+
- Patching a vulnerable dependency by bumping to a compatible version — no
83+
public API or behavior change for consumers
84+
- Hardening internal, non-public code paths (package-private infra: transport,
85+
retry, rate-limit, status-cache) that consumers cannot observe or depend on
86+
- Fixing the build/publish/signing pipeline (CI workflows, artifact signing)
87+
88+
### Tier 2 — Requires maintainer approval first
89+
90+
Any security fix that **breaks consumer compatibility or changes observable
91+
runtime behavior**. These must NOT be applied unilaterally. The agent or
92+
contributor stops, writes up the issue, the proposed fix, and the specific
93+
consumer impact, and waits for the maintainer's approval before proceeding.
94+
95+
A fix is **Tier 2** if it does any of the following:
96+
97+
- Removes, renames, or changes the signature of any **public** type, method, or
98+
parameter (a source/binary-incompatible change — SemVer major)
99+
- Tightens input validation so that requests the SDK previously accepted are now
100+
rejected (could break existing callers)
101+
- Changes a user-visible default (request/connect timeouts, retry counts or
102+
backoff, rate-limit behavior, base URL, API version, `validateOnStartup`)
103+
- Changes an API/response contract — the shape of response records, exception
104+
types thrown, or the sealed `MarketDataException` hierarchy — that consumers
105+
compile against or `switch` over exhaustively
106+
- Raises the minimum JDK, changes the published coordinates, or otherwise forces
107+
a consumer to change their build to keep using the SDK
108+
- Adds a new required dependency to the published JAR, or changes shading/relocation
109+
110+
### Classification rules
111+
112+
- **When in doubt, it's Tier 2.** If it is unclear which tier a fix falls into,
113+
treat it as Tier 2 and ask for approval.
114+
- **No urgency exception.** Even for a critical, actively-exploitable
115+
vulnerability, a compatibility-breaking (Tier 2) fix waits for maintainer
116+
approval. Flag the urgency loudly, propose the fix, and wait. The maintainer is
117+
always the gate for changes that break consumers. (If a break is genuinely
118+
unavoidable to close a critical hole, that's a maintainer decision about
119+
cutting a major version — not an agent's.)
120+
121+
### Release of security fixes
122+
123+
Tiering governs *what* may be changed; the repo's normal release rules govern
124+
*what ships to consumers*. A Tier 1 fix may be committed to a branch and merged
125+
via the usual PR flow. **Publishing a release to Maven Central** — cutting the
126+
tag and running the publish pipeline (`tag-and-release.yml``publish.yml`) —
127+
requires explicit maintainer confirmation, exactly like every other release.
128+
Automated agents never cut or publish a release on their own.

0 commit comments

Comments
 (0)