diff --git a/AGENTS.md b/AGENTS.md index 86eecb297..de90f9bd8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,15 +7,25 @@ generator owns the code you are changing, preserve existing generated behavior, authoritative source when it is available. The `openai-java-example/` directory is not modified by the generator. -## Custom-code budget + -Follow [the custom-code guidance](scripts/castiron/CUSTOM_CODE.md). Budget changes -belong in a separate PR containing only `.castiron-ratchet.json`, with an explicit justification -in the PR description. Increases require a **human approving review** before merging. -Agents may investigate and draft proposals, but must not approve budget increases -(including through a human's credentials) or bypass the gate. Do not weaken -counting, broaden exclusions, or alter generation metadata to make a change pass. -The checker and effective budget come from main, not the PR. Keep default CODEOWNERS. +## Generated-file ownership + +Never hand-edit generated SDK files, including generated tests, documentation, +workflows, or the generated-file inventory. Change the authoritative API schema, +configuration, or compiler, then regenerate. Put SDK-specific behavior in +separately owned handwritten helpers and extension points. + +Regeneration replaces generator-owned files and deletes retired generated paths. +Handwritten edits to generated files are overwritten; they are never replayed or +merged into new output. Preserve separately owned handwritten files and resolve +ownership collisions explicitly. Follow this AGENTS.md rule and review generated output and inventory changes +together. The simplified workflow relies on contributor guidance and code review. +This intermediate revision retains the legacy strict generated-file checker, +which rejects manifest mismatches when invoked. Respect retained checks and any +currently required statuses until canonical regeneration removes the tooling. +Fix violations in the inputs/compiler and regenerate; never update inventory +hashes to accept a handwritten patch. ## Security requirements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6febab8f4..494415ec5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,22 +24,31 @@ management. The framework-neutral SDK requires Java 8, while development require Kotlin toolchain. See the [Java version support policy](docs/version-support-policy.md) for artifact-level runtime, framework, lifecycle, and release rules. -## Custom-code budget - -The custom-code budget counts additions plus deletions in the remaining patch -against verified generated output. `.castiron-ratchet.json` defines this repository's -ceiling. CI uses the checker and budget on main, not the PR's proposed versions. - -Budget changes must be in a separate PR modifying **only `.castiron-ratchet.json`**. -Justify the current usage, proposed ceiling, and why fixing generation is not -appropriate in the PR description. Increases require a **human approving review** -and must merge before an SDK change relies on them. Agents may draft proposals, -but must not approve increases or bypass the gate. Keep default CODEOWNERS. -Lower the ceiling after cleanup while retaining headroom; decreases must still -fit the measured usage. - -See [custom-code technical details](scripts/castiron/CUSTOM_CODE.md) for accounting, -local checks, trusted CI, and activation instructions. + + +## Generated-file ownership + +Do not edit generated SDK files by hand. Fix the API schema, generation +configuration, or compiler and regenerate instead. Put SDK-specific behavior in +separately owned handwritten helpers and extension points. + +Regeneration replaces generated files and removes retired generated paths. +Handwritten edits to generated output are overwritten, not carried forward. +Separately owned handwritten files are preserved. Resolve ownership conflicts +explicitly before regeneration. Follow the ownership rules in `AGENTS.md` +and review generated output and inventory changes together. Generated-file +ownership under the simplified workflow relies on contributor guidance and code +review. This revision still contains the legacy strict generated-file checker, +which rejects manifest mismatches when invoked; inspect live workflow settings +and required statuses separately until canonical regeneration removes it. Fix violations in the +generation inputs/compiler and regenerate; do not edit inventory hashes to +accept a handwritten patch. + +This `next` guidance precedes canonical regeneration: the legacy reporting +workflow definitions and tools still exist in this revision. Preserve their +security checks until removal, and inspect actual workflow settings and results +rather than assuming this document disables them. Do not start new budget +changes or bypass required checks. ## Security expectations @@ -90,8 +99,8 @@ artifact's eligibility on a given JVM come from `gradle/version-support.properti ## Modifying or adding code -Most of the SDK is generated code. Modifications to code will be persisted between generations, but may -result in merge conflicts between manual patches and changes from the generator. The generator will never +Most of the SDK is generated code. Never edit generated files by hand; change +the authoritative generation inputs or compiler and regenerate instead. The generator will never modify the contents of the `openai-java-example/` directory. ## Adding and running examples diff --git a/docs/architecture/security-model.md b/docs/architecture/security-model.md index d3b27b2a8..046644440 100644 --- a/docs/architecture/security-model.md +++ b/docs/architecture/security-model.md @@ -1,5 +1,15 @@ # OpenAI Java SDK security model +Generated files are updated through authoritative inputs or the compiler and +regeneration; handwritten edits to them are forbidden. Code review enforces this +ownership rule. This `next` revision still contains the legacy budget/reporting +workflows and publisher code pending separate canonical regeneration. This +change does not remove or disable those workflows. Until removal, preserve and +review their trusted-code, artifact-validation, event/repository/revision, +freshness, and least-privilege boundaries. Their historical protocol is documented +in `scripts/castiron/CUSTOM_CODE.md`; it does not authorize new generated-file +patches or a replacement budget system. + This is the repository's single canonical detailed threat model. Use it for security review and Codex Security scans of the revision being reviewed. SECURITY.md remains the authority for private disclosure and reportability @@ -20,10 +30,10 @@ repository. | Component | Purpose and important flow | Evidence | | --- | --- | --- | -| openai-java-core | Transport-neutral client, generated services and models, request construction, authentication headers, retry/logging wrappers, JSON/SSE parsing, and webhook verification. | CONTRIBUTING.md:69-72; openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt:57-140; openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:747-808 | -| openai-java-client-okhttp | Default HTTP transport, caller-configurable proxy, redirects, timeouts, TLS, and hostname verification. | CONTRIBUTING.md:73-75; openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt:54-65; openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt:180-242 | -| openai-java | Umbrella artifact exposing core and OkHttp APIs without its own logic. | CONTRIBUTING.md:76-78; openai-java/build.gradle.kts:1-8 | -| openai-java-bedrock | Optional Bedrock endpoint selection and bearer or AWS SigV4 authentication. | CONTRIBUTING.md:79-80; openai-java-bedrock/src/main/kotlin/com/openai/bedrock/BedrockAuth.kt:64-215 | +| openai-java-core | Transport-neutral client, generated services and models, request construction, authentication headers, retry/logging wrappers, JSON/SSE parsing, and webhook verification. | CONTRIBUTING.md:78-81; openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt:57-140; openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:747-808 | +| openai-java-client-okhttp | Default HTTP transport, caller-configurable proxy, redirects, timeouts, TLS, and hostname verification. | CONTRIBUTING.md:82-84; openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OpenAIOkHttpClient.kt:54-65; openai-java-client-okhttp/src/main/kotlin/com/openai/client/okhttp/OkHttpClient.kt:180-242 | +| openai-java | Umbrella artifact exposing core and OkHttp APIs without its own logic. | CONTRIBUTING.md:85-87; openai-java/build.gradle.kts:1-8 | +| openai-java-bedrock | Optional Bedrock endpoint selection and bearer or AWS SigV4 authentication. | CONTRIBUTING.md:88-89; openai-java-bedrock/src/main/kotlin/com/openai/bedrock/BedrockAuth.kt:64-215 | | openai-java-vertex | Optional Vertex endpoint selection and Google bearer authentication. | openai-java-vertex/README.md; openai-java-vertex/src/main/kotlin/com/openai/client/okhttp/VertexOpenAIOkHttpClient.kt | | Build and release workflows | Unprivileged PR validation and separately gated main-only release/publish jobs. | .github/workflows/ci.yml:3-24; .github/workflows/create-releases.yml:3-25 | @@ -79,7 +89,7 @@ not exposed to the attestation action. application's responsibility. - Large JSON bodies and streaming events are supported API contracts. Reviews should prefer incremental processing, cleanup, and cancellation; a large - payload is not by itself hostile or malformed. (AGENTS.md:49-66) + payload is not by itself hostile or malformed. (AGENTS.md:59-76) - Main-branch integrity, protected release credentials, GPG signing material, OIDC attestation authority, artifact/source binding, and Gradle cache isolation must remain unreachable from unmerged PR code. @@ -169,7 +179,7 @@ These are review hypotheses, not confirmed findings. | --- | --- | --- | --- | --- | --- | --- | | High | PR-controlled code reaches protected release credentials or signing/attestation authority before merge/release governance. | A workflow trigger, checkout ref, artifact restore, or environment gate is weakened. | Credential theft or forged official artifacts. | Release is main/schedule/manual only, selects/verifies source, gates runtime compatibility, uses protected publish, and disables release cache reuse. | Preserve source binding, least permissions, environment protection, and no PR artifact/cache import. | .github/workflows/create-releases.yml:3-25; .github/workflows/create-releases.yml:90-164; .github/workflows/create-releases.yml:241-290; .github/workflows/create-releases.yml:426-469 | | High | Untrusted webhook bytes are parsed or acted on without valid signature/freshness checks. | Embedding application exposes webhook ingress and relies on SDK verification. | Forged event acceptance. | Required headers, bounded timestamp tolerance, HMAC-SHA256, timing-safe compare, then parse; no replay deduplication. | Preserve verify-before-parse ordering and focused regression tests; embedding applications must deduplicate accepted webhook IDs when replay matters. | openai-java-core/src/main/kotlin/com/openai/services/WebhookVerification.kt:19-99; openai-java-core/src/main/kotlin/com/openai/services/blocking/WebhookServiceImpl.kt:33-41 | -| Medium | Independently mutable API/SSE JSON crosses a parser boundary and causes unsafe interpretation, resource exhaustion, or sensitive exception/log output. | Attacker controls an API/network response or configured proxy; sink is reachable in caller deployment. | Client failure, data exposure, or downstream misuse. | Strict mapper defaults, typed parsing, stream iteration, and explicit DEBUG diagnostics. | Keep parsing robust and large-payload-compatible; avoid treating model output as executable authority without caller controls. | openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt:34-116; openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt:19-60; AGENTS.md:49-66 | +| Medium | Independently mutable API/SSE JSON crosses a parser boundary and causes unsafe interpretation, resource exhaustion, or sensitive exception/log output. | Attacker controls an API/network response or configured proxy; sink is reachable in caller deployment. | Client failure, data exposure, or downstream misuse. | Strict mapper defaults, typed parsing, stream iteration, and explicit DEBUG diagnostics. | Keep parsing robust and large-payload-compatible; avoid treating model output as executable authority without caller controls. | openai-java-core/src/main/kotlin/com/openai/core/ObjectMappers.kt:34-116; openai-java-core/src/main/kotlin/com/openai/core/handlers/SseHandler.kt:19-60; AGENTS.md:59-76 | | Medium | Credentials or customer payloads reach an unintended destination or uncontrolled log. | Lower-trust actor independently controls base URL/proxy/TLS/log sink, or diagnostics are enabled in an unsafe deployment. | Secret or customer-data disclosure. | Production URL default, caller-owned configuration, auth wrappers, and default sensitive-header redaction; DEBUG is explicit. | Preserve redaction and destination/TLS controls; document caller obligations. | openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:151-172; openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:601-665; openai-java-core/src/main/kotlin/com/openai/core/http/LoggingHttpClient.kt:24-48; openai-java-core/src/main/kotlin/com/openai/core/http/LoggingHttpClient.kt:91-142 | | Medium | A separately privileged evaluator consumes mutable PR Git objects, artifacts, or cache entries as trusted code/data. | Privileged workflow reads candidate state without binding/ref validation. | Privilege crossing beyond ordinary PR CI. | Custom-code workflow checks out main, uses current PR objects, and freshness-checks exact head; PR cache scope remains isolated. | Preserve trusted checkout and exact-head/digest binding. | .github/workflows/castiron-custom-code-comment.yml:34-57; .github/workflows/castiron-custom-code-comment.yml:128-181; .github/workflows/ci.yml:120-129 | | Low / not a boundary by itself | A PR changes a checked-in example, test, fixture, build script, or generated source and ordinary PR CI executes it. | The same PR author already controls the tracked executable checkout. | No new capability beyond the unprivileged PR job. | PR CI has read-only contents and no release credentials; cache scope is enforced outside PR code. | Investigate only if execution crosses an independent input or protected-authority boundary. | .github/workflows/ci.yml:8-20; .github/workflows/ci.yml:33-48; .github/workflows/ci.yml:92-107 |