Add HTTP size limits

This commit is contained in:
2026-07-05 00:17:07 +00:00
parent a16f66cbc7
commit f7d821067f
15 changed files with 609 additions and 46 deletions

View File

@@ -84,11 +84,14 @@ Notes:
- `--profile-dir <dir>`: custom profile definition directory.
- `--schema-dir <dir>`: schema base directory for `json_schema` validation.
- `--artifact-root <dir>`: base directory for HTTP `file` input references.
- `--max-request-bytes <n>`: maximum HTTP request body bytes; `0` disables this limit.
- `--max-artifact-bytes <n>`: maximum HTTP file artifact bytes; `0` disables this limit.
- `--max-response-bytes <n>`: maximum encoded HTTP response body bytes; `0` disables this limit.
Notes:
- `serve` does not accept runtime model override flags such as `--model` or `--llm-base-url`.
- HTTP `file` input references are rejected unless an artifact root is configured through `server.artifact_root` or `--artifact-root`.
- `--artifact-root` affects only `serve`; `run` and `render` file input paths are unchanged.
- `--artifact-root` and the HTTP size-limit flags affect only `serve`; `run` and `render` file input paths are unchanged.
## Input And Variable Syntax

View File

@@ -35,6 +35,9 @@ schema_dir: /opt/scriptorium/schemas
server:
addr: 127.0.0.1:8080
artifact_root: /var/lib/scriptorium/artifacts
max_request_bytes: 16777216
max_artifact_bytes: 16777216
max_response_bytes: 16777216
defaults:
render_format: text
@@ -49,6 +52,9 @@ Top-level fields:
- `schema_dir` (optional): base directory for schema files used by `json_schema` validation.
- `server.addr` (optional): default listen address for `serve`.
- `server.artifact_root` (optional): base directory for HTTP `file` input references.
- `server.max_request_bytes` (optional): maximum HTTP request body size. `0` disables this limit.
- `server.max_artifact_bytes` (optional): maximum HTTP `file` input artifact size. `0` disables this limit.
- `server.max_response_bytes` (optional): maximum encoded HTTP response body size. `0` disables this limit.
- `defaults.render_format` (optional): default `render` output format (`text` or `json`).
Built-in defaults:
@@ -56,11 +62,15 @@ Built-in defaults:
- `schema_dir`: `.`
- `server.addr`: `:8080`
- `server.artifact_root`: unset; HTTP `file` input references are rejected until configured.
- `server.max_request_bytes`: `16777216` (16 MiB)
- `server.max_artifact_bytes`: `16777216` (16 MiB)
- `server.max_response_bytes`: `16777216` (16 MiB)
- `defaults.render_format`: `text`
Validation behavior:
- Config decoding is strict; unknown YAML fields are rejected.
- HTTP size limit values must be greater than or equal to `0`.
- Raw API key fields are not supported in `config.yml`.
HTTP artifact root behavior:
@@ -72,6 +82,13 @@ HTTP artifact root behavior:
- Symlinks inside the root are followed by the operating system; do not make the artifact root writable by untrusted users.
- CLI `run` and `render` file inputs keep their normal direct filesystem path behavior.
HTTP size-limit behavior:
- The request limit covers the encoded JSON request body, including inline input bodies.
- The artifact limit covers HTTP `file` input artifacts read through `serve`.
- The response limit covers the final encoded JSON response, including generated artifact bodies and `raw_model_output` when requested.
- Limits apply only to HTTP `serve`; CLI `run` and `render` keep direct filesystem behavior.
## Prompt Definition Files
Prompt definitions are YAML files anywhere under `prompt_dir`, including nested subdirectories.

View File

@@ -75,6 +75,8 @@ Relative file URIs resolve inside that root. Absolute file URIs are accepted
only when they remain inside the root. Requests that escape the root, including
`..` traversal and absolute paths outside the root, return
`400 artifact_not_allowed`. `inline` references do not require an artifact root.
HTTP file artifacts above the configured artifact limit return
`413 artifact_too_large`. Inline bodies are bounded by the request body limit.
Model override notes:
@@ -91,6 +93,8 @@ Request decoding uses strict JSON field checks:
- unknown request fields are rejected with `400 invalid_json`
- unknown `model` fields are rejected with `400 invalid_json`
- raw API-key payload fields such as `api_key` are rejected as unknown fields
- request bodies above the configured request limit are rejected with `413 request_too_large`
- trailing JSON tokens after the request object are rejected with `400 invalid_json`
## Success Response
@@ -204,6 +208,9 @@ Current error mapping (non-exhaustive):
- `400 artifact_read_failed`: input artifact loading failed
- `400 prompt_render_failed`: template render failed
- `400 api_key_env_missing`: named API-key environment variable is missing
- `413 request_too_large`: request body exceeds the configured request limit
- `413 artifact_too_large`: HTTP file input artifact exceeds the configured artifact limit
- `413 response_too_large`: encoded JSON response exceeds the configured response limit
- `404 prompt_not_found`
- `404 profile_not_found`
- `502 llm_failed`: outbound model request failed

View File

@@ -88,6 +88,9 @@ Primary app settings consumed by adapters:
- `schema_dir`
- `server.addr`
- `server.artifact_root` (HTTP `serve` file input root)
- `server.max_request_bytes`
- `server.max_artifact_bytes`
- `server.max_response_bytes`
- `defaults.render_format`
Execution profile/request settings used through runner:
@@ -122,6 +125,7 @@ Artifact refs:
- Unsupported types return `ErrUnsupportedRefType`.
- CLI `run` and `render` use direct filesystem file reads for `file` references.
- HTTP `serve` uses a restricted artifact reader: `inline` references work without a root, while `file` references require `server.artifact_root` or `--artifact-root` and must stay inside that root.
- HTTP `serve` applies request-body, file-artifact, and encoded-response size limits. CLI `run` and `render` do not use these HTTP limits.
- HTTP file paths are resolved with clean absolute paths and containment checks, not string-prefix checks.
- Symlinks inside the root are followed by the operating system; the configured root must not be writable by untrusted users.
@@ -149,6 +153,7 @@ Validator:
HTTP error mapping:
- maps domain/use-case errors to stable HTTP code + error code/message.
- maps request, artifact, and response size failures to `413` errors.
- distinguishes missing profile selection and missing `api_key_env` variable using stable use-case sentinel errors.
- avoids returning internal wrapped-cause details in response payload.

View File

@@ -36,6 +36,9 @@ Built-in defaults relevant to operations:
- `schema_dir: .`
- `server.addr: :8080`
- `server.artifact_root`: unset; HTTP `file` input references are rejected until configured
- `server.max_request_bytes: 16777216`
- `server.max_artifact_bytes: 16777216`
- `server.max_response_bytes: 16777216`
- `defaults.render_format: text`
## Normal CLI Workflow
@@ -78,6 +81,7 @@ Current inbound API behavior:
- Validation content failures still return `200 OK` with `validation.status: "failed"`.
- `inline` input references work without filesystem configuration.
- `file` input references require `server.artifact_root` or `serve --artifact-root`; relative paths resolve inside that root and paths outside it are rejected.
- Request bodies, HTTP file input artifacts, and encoded JSON responses are limited by `server.max_request_bytes`, `server.max_artifact_bytes`, and `server.max_response_bytes`.
Security caveat:
@@ -85,6 +89,13 @@ Security caveat:
- Deploy only behind trusted controls (private network boundary, authenticated reverse proxy, API gateway, or equivalent).
- Keep the HTTP artifact root as narrow as practical and do not make it writable by untrusted users.
Sizing guidance:
- Keep limits at the defaults unless a deployment has a measured need for larger prompt inputs or outputs.
- Prefer `inline` inputs for small payloads and HTTP `file` inputs for larger local artifacts inside a controlled artifact root.
- Increase the response limit when prompts intentionally return large generated artifacts or when clients request `include_raw_output`.
- Set a limit to `0` only for trusted deployments where another layer enforces request and response size.
## Output, Logs, And Exit Codes
`run` command:

View File

@@ -147,6 +147,7 @@ Symptom:
- CLI run/render error reading input artifacts.
- HTTP `400 artifact_read_failed`.
- HTTP `400 artifact_not_allowed`.
- HTTP `413 artifact_too_large`.
Likely cause:
@@ -154,12 +155,14 @@ Likely cause:
- Unsupported artifact reference type in HTTP request.
- HTTP `file` input references are disabled because no artifact root is configured.
- HTTP `file` input path escapes the configured artifact root.
- HTTP `file` input artifact exceeds `server.max_artifact_bytes`.
Diagnostic step:
- Verify every mapped file path exists and is readable by the process.
- For HTTP, verify each input uses supported `type` values.
- For HTTP `file` inputs, verify `server.artifact_root` or `serve --artifact-root` is configured and the requested path stays inside that root.
- For HTTP `file` inputs, compare file size to `server.max_artifact_bytes`.
Safe fix:
@@ -167,6 +170,7 @@ Safe fix:
- Use supported input types (`file`, `inline`).
- Configure a narrow HTTP artifact root when HTTP file inputs are required.
- Use relative paths under the artifact root, or switch to `inline` inputs.
- Increase `server.max_artifact_bytes` only when the deployment expects larger file inputs.
Relevant links:
@@ -351,22 +355,29 @@ Relevant links:
Symptom:
- HTTP `400 invalid_json` or `400 invalid_request`.
- HTTP `413 request_too_large`.
- HTTP `413 response_too_large`.
Likely cause:
- Malformed JSON body.
- Unknown JSON fields.
- Missing required `prompt_id` or `inputs`.
- Request body exceeds `server.max_request_bytes`, including inline input bodies.
- Encoded JSON response exceeds `server.max_response_bytes`, including generated artifact body and optional raw model output.
Diagnostic step:
- Revalidate request JSON.
- Confirm required request fields are present.
- Compare request and expected response sizes to configured HTTP limits.
Safe fix:
- Send valid JSON with only supported fields.
- Ensure `prompt_id` and at least one input mapping are included.
- Use smaller inline inputs, move large local inputs under the artifact root, or increase `server.max_request_bytes`.
- Omit `include_raw_output`, reduce generated output size, or increase `server.max_response_bytes`.
Relevant links: