Skip to content

fix: harden Slurm release artifacts - #916

Open
nabinchha wants to merge 12 commits into
feat/slurm-executionfrom
codex/870-slurm-early-security-hardening
Open

fix: harden Slurm release artifacts#916
nabinchha wants to merge 12 commits into
feat/slurm-executionfrom
codex/870-slurm-early-security-hardening

Conversation

@nabinchha

@nabinchha nabinchha commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📋 Summary

Adds the dependency-ready security and provenance hardening slice for the optional Slurm package. This establishes reusable, sanitized scans and closes concrete diagnostic/license gaps without claiming the sealed-artifact release acceptance that remains blocked on the rest of the Slurm delivery.

🔗 Related Issue

Part of #870

🔄 Changes

  • Add a fail-closed public-artifact scanner for production and test source, maintained fixtures, docs/release scripts, explicit logs, wheels/ZIPs, and runtime tar archives.
  • Scan bounded content regardless of filename suffix, mask only complete path-scoped synthetic test sentinel values, and reject symbolic links and other non-regular filesystem entries before content detection.
  • Detect ZIP and tar inputs by content even under opaque filenames; reject unsafe paths, links, unsupported tar special members, and unreadable or encrypted ZIP members without disclosing member names.
  • Detect high-confidence credentials and environment-specific infrastructure without printing matched content or external paths.
  • Validate archive member safety and bounds, packaged-source SPDX headers, and exactly one Slurm wheel .dist-info root containing one byte-exact canonical license plus one Apache-2.0 metadata record.
  • Centralize credential redaction for bounded Slurm command diagnostics, covering quoted and unquoted Authorization fields, general URI-scheme userinfo through the last authority @, and non-overlapping assignment/option scanning across hyphen, underscore, dot, and mixed option names.
  • Build a token-preserving scan view for controls and non-line Unicode whitespace, redact embedded credential suffixes, normalize surviving boundaries, then redact again with collision-safe protected markers.
  • Package a byte-for-byte copy of the repository Apache-2.0 license and verify SPDX provenance in the checked-in runtime entrypoint introduced by fix(slurm): close one-node M2 integration #929.
  • Record the reviewed shell, path, environment, archive, log, cleanup, provenance, and dependency boundaries under plans/870/.

🔍 Attention Areas

⚠️ Reviewers: Please pay special attention to the scanner policy and redaction coverage. The default audit scans the complete Slurm test tree and scripts/publish.sh; only complete synthetic sentinel values in explicitly named test files are masked.

⛓️ Dependencies and remaining blockers

🧪 Testing

  • Full Slurm suite after the latest review fixes and base restack: 1,531 passed
  • Focused command-redaction, runtime-bundle, and public-artifact suite: 152 passed
  • Complete built-wheel isolation/install workflow, including an independent scan of the built Slurm wheel
  • Source/test/docs/release-script scan: 9 consolidated targets passed
  • Locked runtime dependency-license audit: 89 packages, all compatible with policy
  • make check-slurm: 196 files formatted and linted
  • Complexity checks on changed production/audit modules
  • SPDX-header audit: 794 files current
  • Script lint/format checks and git diff --check
  • Unit tests added/updated
  • E2E tests added/updated (N/A — final real-cluster acceptance remains part of the later sealed Harden the Slurm runtime and validate sealed release artifacts #870 run)

✅ Checklist

  • Follows commit message conventions
  • Commits are signed off (DCO)
  • Issue-scoped security review evidence updated

Description updated with AI

@nabinchha
nabinchha marked this pull request as ready for review September 3, 2026 16:31
@nabinchha
nabinchha requested a review from a team as a code owner September 3, 2026 16:31
@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no new actionable correctness, security, or repository-rule violations remain.

Findings

  1. P1 Security Assignment redaction leaks suffixes
  2. P1 License check accepts stubs
  3. P1 Security Adjacent assignment leaks secret
  4. P1 Security Quoted secret suffix leaks
  5. P1 Security Underscore options expose secrets
  6. P1 Security Control characters bypass redaction
  7. P1 Security Control characters leak secret suffixes
  8. P1 Security An explicitly supplied ZIP or tar archive with an unrecognized suffix falls through to the opaque-file scan. Because the CLI accepts arbitrary artifact paths, compressed credentials, unsafe member paths, and links can go uninspected while the audit reports that the artifact passed. Archive formats must be detected from their content rather than only from .zip , .whl , .tar , .tar.gz , or .tgz suffixes.
  9. P1 Security Tar members that are neither regular files nor links-including FIFOs and device nodes-are silently accepted. The audit can therefore certify a tar that later materializes special filesystem objects when extracted with tar -xzf . Unsupported special member types must be rejected while ordinary directories remain allowed.
  10. P1 Security Quoted authorization suffix leaks
Fix with agent prompt
### Issue 1
packages/data-designer-slurm/src/data_designer/slurm/security.py:12-15
When scheduler stderr contains a secret assignment such as `HF_TOKEN=abc;def` or `HF_TOKEN=abc,def`, the value pattern stops at the delimiter and only redacts the prefix, exposing the remaining credential characters in `SlurmCommandError`. **How this was verified:** The assignment regex excludes commas and semicolons while the resulting text is passed directly into caller-visible error details.

### Issue 2
scripts/audit_slurm_public_artifacts.py:undefined-222
When a wheel contains a truncated or placeholder license with only `Apache License` and `Version 2.0`, this condition marks the license as present, causing an incomplete artifact to pass the provenance gate.

### Issue 3
packages/data-designer-slurm/src/data_designer/slurm/security.py:undefined-16
When scheduler output contains a punctuation-delimited non-secret assignment followed by a secret assignment, such as `status=failed;HF_TOKEN=secret`, the greedy value match consumes both assignments and `_redact_named_value` returns them unchanged because `status` is not secret-bearing, exposing the token in `SlurmCommandError`.

**How this was verified:** The assignment pattern consumes through punctuation, while the replacement callback preserves the entire match when its first name is non-secret.

### Issue 4
packages/data-designer-slurm/src/data_designer/slurm/security.py:13-15
When scheduler stderr contains a quoted secret assignment with whitespace, such as `HF_TOKEN="quoted secret value"`, the assignment prefix consumes the opening quote before boundary detection, so only the first word is redacted and `secret value"` remains visible in `SlurmCommandError`.

**How this was verified:** Tracing the quoted assignment through `match.end()` shows that `_find_named_value_end` starts on the first value character and stops at the first whitespace.

### Issue 5
packages/data-designer-slurm/src/data_designer/slurm/security.py:undefined-15
When scheduler diagnostics contain an underscore-form secret option such as `--api_key plaintext-secret`, `_OPTION_START_PATTERN` does not match the option and the assignment scanner requires `:` or `=`, causing the plaintext value to remain visible in `SlurmCommandError`.

**How this was verified:** The option-name character class excludes underscores even though underscore-form names are recognized as secret-bearing.

```suggestion
_OPTION_START_PATTERN = re.compile(r"(?P<prefix>(?P<name>--[A-Za-z][A-Za-z0-9_.-]*)\s+)")
```

### Issue 6
packages/data-designer-slurm/src/data_designer/slurm/launcher/client.py:220-222
When scheduler diagnostics contain a secret option such as `--api-key\x00plaintext-secret`, the NUL character prevents the option pattern from matching. The later normalization turns that character into a regular space, exposing `--api-key plaintext-secret` in the caller-visible `SlurmCommandError`. Normalize control characters before redacting the text so redaction inspects the same boundaries that callers see.

**How this was verified:** Non-zero scheduler stderr reaches this helper and is included in `SlurmCommandError`, while the option grammar cannot recognize this secret-bearing option until control normalization replaces the NUL with whitespace.

```suggestion
    sanitized = "".join(" " if unicodedata.category(character).startswith("C") else character for character in value)
    redacted = redact_sensitive_text(sanitized)
    normalized = " ".join(redacted.split())
```

### Issue 7
packages/data-designer-slurm/src/data_designer/slurm/launcher/client.py:228-229
Normalizing embedded control characters to spaces before redaction splits an unquoted secret value into separate tokens. For example, `HF_TOKEN=secret\x00suffix` becomes `HF_TOKEN=secret suffix`; the scanner redacts only `secret`, leaving `suffix` visible in the caller-facing `SlurmCommandError`. The same transformation can prevent URI user-info redaction when a control character appears before the authority's `@`.

**How this was verified:** Scheduler-controlled stderr reaches this pipeline, and the named-value scanner stops at the space introduced inside the credential before the resulting text is returned to the caller.

### Issue 8
scripts/audit_slurm_public_artifacts.py:158-161
An explicitly supplied ZIP or tar archive with an unrecognized suffix falls through to the opaque-file scan. Because the CLI accepts arbitrary artifact paths, compressed credentials, unsafe member paths, and links can go uninspected while the audit reports that the artifact passed. Archive formats must be detected from their content rather than only from `.zip`, `.whl`, `.tar`, `.tar.gz`, or `.tgz` suffixes.

**How this was verified:** `_audit_file` selects member-level validation only through suffix checks and otherwise scans the compressed bytes as plain text.

### Issue 9
scripts/audit_slurm_public_artifacts.py:294-297
Tar members that are neither regular files nor links-including FIFOs and device nodes-are silently accepted. The audit can therefore certify a tar that later materializes special filesystem objects when extracted with `tar -xzf`. Unsupported special member types must be rejected while ordinary directories remain allowed.

**How this was verified:** `_audit_tar_member` returns no finding for every non-regular, non-link member, while the runtime extraction path passes the archive directly to GNU tar.

### Issue 10
packages/data-designer-slurm/src/data_designer/slurm/security.py:17-20
When a quoted Authorization value is followed by a control-obscured credential suffix, such as `Authorization: "Bearer token"\x00secret-suffix`, the first pass redacts only through the closing quote. After control normalization, the second pass sees the inserted redaction marker and preserves the remaining value, leaving `secret-suffix` visible in the caller-facing `SlurmCommandError`.

**How this was verified:** The quoted-value alternative stops at the closing quote, while the protected second pass preserves the entire remaining value whenever it starts with the first-pass redaction marker.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

  • Adds centralized credential redaction that handles assignments, options, Authorization fields, URI userinfo, Unicode whitespace, and control-obscured values.
  • Adds a bounded, fail-closed scanner for source files, logs, ZIPs, wheels, and tar archives.
  • Enforces canonical Apache-2.0 license metadata and SPDX provenance for packaged Slurm artifacts.
  • Adds focused regression coverage for credential leakage, archive safety, filesystem entry types, and wheel provenance.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Artifact path] --> B{Regular file?}
  B -- No --> X[Reject]
  B -- Yes --> C{ZIP by suffix or content?}
  C -- Yes --> D[Validate paths, links, bounds, and member content]
  D --> E{Wheel filename?}
  E -- Yes --> F[Validate dist-info root, canonical license, and metadata]
  E -- No --> Y[Report findings]
  F --> Y
  C -- No --> G{Tar by suffix or content?}
  G -- Yes --> H[Validate paths, member types, links, bounds, and content]
  H --> Y
  G -- No --> I[Bounded plain-content scan]
  I --> Y
Loading

Reviews (17) · Last reviewed commit: "redact complete Authorization diagnostic..."

Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py Outdated
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
@nabinchha
nabinchha force-pushed the codex/870-slurm-early-security-hardening branch from 413b708 to e8a4c3c Compare September 3, 2026 20:45
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py
@nabinchha
nabinchha force-pushed the codex/870-slurm-early-security-hardening branch from ee11baa to 1e0b50c Compare September 3, 2026 22:24
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py Outdated
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py Outdated

@andreatnvidia andreatnvidia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for the blocking findings above.

Comment thread packages/data-designer-slurm/src/data_designer/slurm/launcher/client.py Outdated
@nabinchha
nabinchha requested review from a team and andreatnvidia September 8, 2026 17:35
Comment thread packages/data-designer-slurm/src/data_designer/slurm/launcher/client.py Outdated
@nabinchha

Copy link
Copy Markdown
Contributor Author

Addressed the remaining whitespace-class control finding from the Greptile summary in 11fb62e. Verified on the prior head that HF_TOKEN=secret\vsuffix exposed suffix and that form-feed inside URI userinfo bypassed redaction. The diagnostic redactor now builds a collision-safe token-preserving first-pass view for non-line controls, redacts embedded assignment/URI suffixes, converts only surviving controls into visible boundaries, then applies the protected second pass. Regression coverage exercises all eight non-line Python whitespace-control codes (tab, vertical tab, form feed, FS/GS/RS/US, and NEL) across assignment and URI suffixes, plus CR/LF/CRLF as intentionally preserved diagnostic-line boundaries. Validation: focused redaction/artifact suite 113 passed; full Slurm suite 1,339 passed; make check-slurm, 9-target artifact scan, complexity, SPDX 752/752, pre-commit, diff check, and isolated wheel build/install all passed.

@nabinchha
nabinchha force-pushed the codex/870-slurm-early-security-hardening branch from 11fb62e to 36abe64 Compare September 8, 2026 18:53
@nabinchha

Copy link
Copy Markdown
Contributor Author

Restacked the exact nine PR-owned commits from old base b98c043e / old head 11fb62ed onto the current feat/slurm-execution head d7b24521; new head is 36abe646. The rebase was conflict-free and git range-diff reports all nine patches as equivalent. The two semantic overlaps remain composed: #926 adds the Slurm pip dependency and metadata assertion, while this PR retains license-files and the built-wheel artifact audit. Post-restack validation: 113 focused security/artifact tests and 1,374 full Slurm tests passed; make check-slurm, 9-target artifact scan, complexity, SPDX 758/758, full-range pre-commit, diff check, and isolated wheel build/install all passed.

@nabinchha
nabinchha force-pushed the codex/870-slurm-early-security-hardening branch from 36abe64 to 49b7344 Compare September 10, 2026 13:00
Comment thread scripts/audit_slurm_public_artifacts.py
Comment thread scripts/audit_slurm_public_artifacts.py
allowed_sentinels: Iterable[str] = (),
) -> list[AuditFinding]:
text = content.decode("utf-8", errors="replace")
for sentinel in sorted(allowed_sentinels, key=len, reverse=True):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this masking boundary-aware? str.replace also removes a sentinel when it is only a prefix of a longer value, so super-secret-token-production-value passes in an allowlisted source. Matching complete sentinel values and adding that extended-value case would keep the exception as narrow as the docstring says.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a123868. Allowlist masking now uses complete-value boundaries instead of substring replacement, so an approved sentinel used only as a prefix remains visible to the scanner. Added an isolated CLI regression against the real allowlisted path shape. Validation: 133 focused tests and 1,440 full Slurm tests passed; make check-slurm, the 9-target artifact audit, and diff checks passed.

Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py Outdated
Comment thread plans/870/slurm-early-security-review.md Outdated
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py Outdated
Comment thread scripts/audit_slurm_public_artifacts.py Outdated

@andreatnvidia andreatnvidia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few redaction and audit boundary cases are still open. I left the details inline.

@nabinchha
nabinchha requested review from a team and andreatnvidia September 10, 2026 15:52
Comment thread packages/data-designer-slurm/src/data_designer/slurm/security.py
Add sanitized credential and infrastructure scans for source, fixtures, runtime archives, logs, and wheels. Include Apache license text in the Slurm wheel and redact sensitive scheduler diagnostics.

Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Detect explicitly supplied ZIP and tar inputs from their content when filenames use opaque suffixes. Reject unsupported tar special members while continuing to allow ordinary directories.

Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Handle serialized authorization headers and Unicode whitespace without exposing credential suffixes. Keep public-artifact scanning fail-closed for non-regular files and unreadable ZIP members, and narrow test sentinels to complete values.

Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
Treat an Authorization field as credential-bearing through its line boundary even when its value is quoted. This keeps control-obscured suffixes from surviving the protected redaction pass.

Signed-off-by: Nabin Mulepati <nmulepati@nvidia.com>
@nabinchha
nabinchha force-pushed the codex/870-slurm-early-security-hardening branch from 496bd22 to 91d156a Compare September 10, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants