shieldops-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shieldops_sdk-0.1.0/.gitattributes +36 -0
- shieldops_sdk-0.1.0/.github/CODEOWNERS +22 -0
- shieldops_sdk-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- shieldops_sdk-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- shieldops_sdk-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +37 -0
- shieldops_sdk-0.1.0/.github/ISSUE_TEMPLATE/security_advisory.md +22 -0
- shieldops_sdk-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +44 -0
- shieldops_sdk-0.1.0/.github/dependabot.yml +62 -0
- shieldops_sdk-0.1.0/.github/scripts/assemble_release_evidence.sh +110 -0
- shieldops_sdk-0.1.0/.github/workflows/ci.yml +62 -0
- shieldops_sdk-0.1.0/.github/workflows/release.yml +253 -0
- shieldops_sdk-0.1.0/CHANGELOG.md +79 -0
- shieldops_sdk-0.1.0/CODE_OF_CONDUCT.md +37 -0
- shieldops_sdk-0.1.0/CONTRIBUTING.md +155 -0
- shieldops_sdk-0.1.0/HITL-SETUP.md +164 -0
- shieldops_sdk-0.1.0/LICENSE +19 -0
- shieldops_sdk-0.1.0/MAINTAINERS.md +75 -0
- shieldops_sdk-0.1.0/PKG-INFO +221 -0
- shieldops_sdk-0.1.0/README.md +169 -0
- shieldops_sdk-0.1.0/ROADMAP.md +81 -0
- shieldops_sdk-0.1.0/SECURITY.md +106 -0
- shieldops_sdk-0.1.0/docs/api-reference.md +462 -0
- shieldops_sdk-0.1.0/docs/configuration.md +222 -0
- shieldops_sdk-0.1.0/docs/onboarding.md +115 -0
- shieldops_sdk-0.1.0/docs/troubleshooting.md +254 -0
- shieldops_sdk-0.1.0/eval/README.md +41 -0
- shieldops_sdk-0.1.0/examples/README.md +93 -0
- shieldops_sdk-0.1.0/examples/crewai_crew.py +198 -0
- shieldops_sdk-0.1.0/examples/custom_policies.py +236 -0
- shieldops_sdk-0.1.0/examples/fastapi_app.py +253 -0
- shieldops_sdk-0.1.0/examples/langchain_agent.py +161 -0
- shieldops_sdk-0.1.0/examples/standalone_interceptor.py +160 -0
- shieldops_sdk-0.1.0/pyproject.toml +101 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/__init__.py +50 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/_policy/__init__.py +41 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/_policy/_defaults.py +33 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/_response.py +72 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/async_client.py +83 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/client.py +85 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/config.py +95 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/exceptions.py +85 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/experimental/__init__.py +22 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/experimental/autogen.py +114 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/experimental/openai_agents.py +96 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/integrations/__init__.py +3 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/integrations/crewai.py +83 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/integrations/langchain.py +91 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/integrations/llamaindex.py +86 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/interceptor.py +217 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/models.py +120 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/__init__.py +31 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/agents.py +90 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/investigations.py +137 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/remediations.py +218 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/security.py +168 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/resources/vulnerabilities.py +253 -0
- shieldops_sdk-0.1.0/src/shieldops_sdk/telemetry.py +196 -0
- shieldops_sdk-0.1.0/tests/__init__.py +0 -0
- shieldops_sdk-0.1.0/tests/integration/__init__.py +0 -0
- shieldops_sdk-0.1.0/tests/integration/sigstore/__init__.py +0 -0
- shieldops_sdk-0.1.0/tests/integration/sigstore/conftest.py +89 -0
- shieldops_sdk-0.1.0/tests/integration/sigstore/test_staging_round_trip.py +167 -0
- shieldops_sdk-0.1.0/tests/test_async_client.py +74 -0
- shieldops_sdk-0.1.0/tests/test_client.py +232 -0
- shieldops_sdk-0.1.0/tests/test_config.py +62 -0
- shieldops_sdk-0.1.0/tests/test_crewai_integration.py +167 -0
- shieldops_sdk-0.1.0/tests/test_experimental.py +124 -0
- shieldops_sdk-0.1.0/tests/test_interceptor.py +125 -0
- shieldops_sdk-0.1.0/tests/test_langchain_integration.py +175 -0
- shieldops_sdk-0.1.0/tests/test_llamaindex_integration.py +170 -0
- shieldops_sdk-0.1.0/tests/test_models.py +132 -0
- shieldops_sdk-0.1.0/tests/test_packaging.py +84 -0
- shieldops_sdk-0.1.0/tests/test_policy_defaults.py +120 -0
- shieldops_sdk-0.1.0/tests/test_resources.py +158 -0
- shieldops_sdk-0.1.0/tests/test_telemetry.py +169 -0
- shieldops_sdk-0.1.0/tests/test_telemetry_modes.py +196 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Normalize line endings on commit; check out with platform-native endings.
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Source / docs / config — always LF, always text.
|
|
5
|
+
*.py text eol=lf
|
|
6
|
+
*.pyi text eol=lf
|
|
7
|
+
*.md text eol=lf
|
|
8
|
+
*.rst text eol=lf
|
|
9
|
+
*.txt text eol=lf
|
|
10
|
+
*.toml text eol=lf
|
|
11
|
+
*.yaml text eol=lf
|
|
12
|
+
*.yml text eol=lf
|
|
13
|
+
*.json text eol=lf
|
|
14
|
+
*.cfg text eol=lf
|
|
15
|
+
*.ini text eol=lf
|
|
16
|
+
|
|
17
|
+
# Shell scripts must stay LF even on Windows clones.
|
|
18
|
+
*.sh text eol=lf
|
|
19
|
+
Makefile text eol=lf
|
|
20
|
+
|
|
21
|
+
# Common binaries — never normalize.
|
|
22
|
+
*.png binary
|
|
23
|
+
*.jpg binary
|
|
24
|
+
*.jpeg binary
|
|
25
|
+
*.gif binary
|
|
26
|
+
*.ico binary
|
|
27
|
+
*.pdf binary
|
|
28
|
+
*.zip binary
|
|
29
|
+
*.gz binary
|
|
30
|
+
*.tar binary
|
|
31
|
+
*.whl binary
|
|
32
|
+
|
|
33
|
+
# Linguist hints for GitHub's language stats.
|
|
34
|
+
docs/** linguist-documentation
|
|
35
|
+
examples/** linguist-documentation
|
|
36
|
+
tests/** linguist-detectable=false
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# CODEOWNERS for shieldops-sdk
|
|
2
|
+
#
|
|
3
|
+
# Every path in this repository is owned by at least one reviewer listed
|
|
4
|
+
# below. Pull requests automatically request review from the matching
|
|
5
|
+
# owner. Order matters: the last matching pattern wins for a given path.
|
|
6
|
+
#
|
|
7
|
+
# TODO: replace @ghantakiran with team handles (e.g. @shieldops/maintainers,
|
|
8
|
+
# @shieldops/security) after the GitHub organization is provisioned and
|
|
9
|
+
# the maintainers/security teams exist. See HITL-SETUP.md.
|
|
10
|
+
|
|
11
|
+
* @ghantakiran
|
|
12
|
+
|
|
13
|
+
# Security-sensitive paths require a security reviewer in addition to
|
|
14
|
+
# the default owner. After org setup, add @shieldops/security here.
|
|
15
|
+
/SECURITY.md @ghantakiran
|
|
16
|
+
/.github/ @ghantakiran
|
|
17
|
+
/src/shieldops_sdk/ @ghantakiran
|
|
18
|
+
|
|
19
|
+
# Release + license docs require a maintainer review.
|
|
20
|
+
/LICENSE @ghantakiran
|
|
21
|
+
/CHANGELOG.md @ghantakiran
|
|
22
|
+
/pyproject.toml @ghantakiran
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a defect in shieldops-sdk
|
|
4
|
+
title: "[bug] "
|
|
5
|
+
labels: ["bug", "triage"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Reproduction
|
|
10
|
+
|
|
11
|
+
Steps to reproduce the behavior. A minimal code sample is ideal.
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
# paste minimal repro here
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Expected
|
|
18
|
+
|
|
19
|
+
What you expected to happen.
|
|
20
|
+
|
|
21
|
+
## Actual
|
|
22
|
+
|
|
23
|
+
What actually happened. Include the full traceback if an exception was
|
|
24
|
+
raised. Redact any API keys, tokens, or customer data before posting.
|
|
25
|
+
|
|
26
|
+
## Environment
|
|
27
|
+
|
|
28
|
+
| Field | Value |
|
|
29
|
+
|-------|-------|
|
|
30
|
+
| Python version | e.g. 3.12.2 |
|
|
31
|
+
| `shieldops-sdk` version | e.g. 1.0.0 |
|
|
32
|
+
| Integration framework | e.g. LangChain 0.2.5 / CrewAI 0.30 / LlamaIndex 0.10 / none |
|
|
33
|
+
| Operating system | e.g. macOS 14.4 / Ubuntu 22.04 / Windows 11 |
|
|
34
|
+
| SDK mode | `audit` or `enforce` |
|
|
35
|
+
|
|
36
|
+
## Additional context
|
|
37
|
+
|
|
38
|
+
Logs, screenshots, or anything else that helps. Remember: do not paste
|
|
39
|
+
secrets.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability report
|
|
4
|
+
url: https://github.com/shieldops/shieldops-sdk/blob/main/SECURITY.md
|
|
5
|
+
about: Do not report security issues in public GitHub issues. See SECURITY.md for the private disclosure process and our response SLAs.
|
|
6
|
+
- name: Usage questions and discussions
|
|
7
|
+
url: https://github.com/shieldops/shieldops-sdk/discussions
|
|
8
|
+
about: For general questions about using shieldops-sdk, open a discussion instead of an issue.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Propose an enhancement to shieldops-sdk
|
|
4
|
+
title: "[feat] "
|
|
5
|
+
labels: ["enhancement", "triage"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Use case
|
|
10
|
+
|
|
11
|
+
What are you trying to accomplish? Describe the user or system problem,
|
|
12
|
+
not the solution.
|
|
13
|
+
|
|
14
|
+
## Current workaround
|
|
15
|
+
|
|
16
|
+
How are you solving this today, if at all? Include code if helpful.
|
|
17
|
+
|
|
18
|
+
## Proposed API
|
|
19
|
+
|
|
20
|
+
What would the ideal public API look like? Sketch the shape in code:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# your proposed usage
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Call out any new public classes, methods, config fields, or env vars.
|
|
27
|
+
|
|
28
|
+
## Alternatives considered
|
|
29
|
+
|
|
30
|
+
What other approaches did you evaluate? Why did you rule them out?
|
|
31
|
+
|
|
32
|
+
## Additional context
|
|
33
|
+
|
|
34
|
+
Links to related issues, upstream framework docs, prior art in other
|
|
35
|
+
SDKs, or benchmarks. If this is a new framework integration, also read
|
|
36
|
+
the "Proposing a new framework integration" section of
|
|
37
|
+
`CONTRIBUTING.md` before filing.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Security issue (do not use)
|
|
3
|
+
about: Redirects to SECURITY.md
|
|
4
|
+
title: "[security] DO NOT FILE HERE"
|
|
5
|
+
labels: ["security"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Do not report security issues here
|
|
10
|
+
|
|
11
|
+
Public issues are visible to everyone, including attackers. Reporting a
|
|
12
|
+
vulnerability here can put users at risk before a patch is available.
|
|
13
|
+
|
|
14
|
+
Instead, follow the process in [`SECURITY.md`](../../SECURITY.md):
|
|
15
|
+
|
|
16
|
+
- Email **security@shieldops.io** with details.
|
|
17
|
+
- Encrypt sensitive reports with the PGP key referenced in `SECURITY.md`.
|
|
18
|
+
- Expect an acknowledgement within the SLA published in that document.
|
|
19
|
+
|
|
20
|
+
If you opened this template by mistake, please close it and redirect
|
|
21
|
+
your report to the email address above. Thank you for helping keep
|
|
22
|
+
`shieldops-sdk` users safe.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
One-paragraph description of what this PR changes and why. Focus on the
|
|
4
|
+
"why" -- the diff already shows the "what".
|
|
5
|
+
|
|
6
|
+
## Linked issue
|
|
7
|
+
|
|
8
|
+
Closes #<issue-number>
|
|
9
|
+
|
|
10
|
+
(Use `Closes` / `Fixes` for bug fixes, `Refs` for partial work.)
|
|
11
|
+
|
|
12
|
+
## Tests added
|
|
13
|
+
|
|
14
|
+
- [ ] Unit tests for new code paths
|
|
15
|
+
- [ ] Integration tests updated if public behavior changed
|
|
16
|
+
- [ ] Coverage on changed lines is >= 80%
|
|
17
|
+
- [ ] `pytest tests/ -v` passes locally
|
|
18
|
+
|
|
19
|
+
Describe what the new tests cover and how they exercise the change.
|
|
20
|
+
|
|
21
|
+
## DCO signed
|
|
22
|
+
|
|
23
|
+
- [ ] Every commit on this branch is signed off with `git commit -s`
|
|
24
|
+
(adds a `Signed-off-by:` trailer). The DCO bot blocks merge
|
|
25
|
+
otherwise. See `CONTRIBUTING.md` for details.
|
|
26
|
+
|
|
27
|
+
## Breaking change?
|
|
28
|
+
|
|
29
|
+
- [ ] Yes -- describe the break and the migration path below.
|
|
30
|
+
- [ ] No.
|
|
31
|
+
|
|
32
|
+
If yes: document the before/after API, whether a deprecation period
|
|
33
|
+
was offered, and link the RFC issue that approved the break.
|
|
34
|
+
|
|
35
|
+
## Checklist
|
|
36
|
+
|
|
37
|
+
- [ ] `ruff check src/ tests/` passes with no new warnings
|
|
38
|
+
- [ ] `ruff format --check src/ tests/` passes
|
|
39
|
+
- [ ] `pytest tests/ -v --tb=short` passes
|
|
40
|
+
- [ ] Type hints on all new public functions and methods
|
|
41
|
+
- [ ] Docstrings on all new public classes, functions, and methods
|
|
42
|
+
- [ ] `CHANGELOG.md` updated under `[Unreleased]`
|
|
43
|
+
- [ ] Documentation updated in `docs/` if public behavior changed
|
|
44
|
+
- [ ] No secrets, API keys, or customer data in the diff or tests
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Dependabot config for shieldops-sdk (PRD-028 PR α).
|
|
2
|
+
#
|
|
3
|
+
# Authored in the private monorepo at sdk/.github/dependabot.yml; rides
|
|
4
|
+
# the carve-out mirror to shieldops-io/shieldops-sdk.
|
|
5
|
+
#
|
|
6
|
+
# SLA per PRD-028 §"PR α / Acceptance criteria":
|
|
7
|
+
# - high-severity advisories → 7 days
|
|
8
|
+
# - medium-severity advisories → 30 days
|
|
9
|
+
#
|
|
10
|
+
# Dependabot itself respects the GitHub Advisory Database for severity
|
|
11
|
+
# labeling; the timelines above are enforced by team policy + the
|
|
12
|
+
# auto-merge schedule below (informational `commit-message.prefix`
|
|
13
|
+
# tagging that monitoring can grep).
|
|
14
|
+
|
|
15
|
+
version: 2
|
|
16
|
+
|
|
17
|
+
updates:
|
|
18
|
+
# ── Python (the SDK itself) ──────────────────────────────────────────
|
|
19
|
+
- package-ecosystem: "pip"
|
|
20
|
+
directory: "/"
|
|
21
|
+
schedule:
|
|
22
|
+
interval: "weekly"
|
|
23
|
+
day: "monday"
|
|
24
|
+
open-pull-requests-limit: 10
|
|
25
|
+
commit-message:
|
|
26
|
+
prefix: "deps(pip)"
|
|
27
|
+
include: "scope"
|
|
28
|
+
groups:
|
|
29
|
+
runtime:
|
|
30
|
+
patterns:
|
|
31
|
+
- "*"
|
|
32
|
+
exclude-patterns:
|
|
33
|
+
- "pytest*"
|
|
34
|
+
- "ruff"
|
|
35
|
+
- "mypy"
|
|
36
|
+
- "hatch*"
|
|
37
|
+
- "build"
|
|
38
|
+
dev:
|
|
39
|
+
patterns:
|
|
40
|
+
- "pytest*"
|
|
41
|
+
- "ruff"
|
|
42
|
+
- "mypy"
|
|
43
|
+
- "hatch*"
|
|
44
|
+
- "build"
|
|
45
|
+
# Security-only updates run on a tighter cadence — Dependabot opens
|
|
46
|
+
# those PRs immediately on advisory publish.
|
|
47
|
+
labels:
|
|
48
|
+
- "dependencies"
|
|
49
|
+
- "python"
|
|
50
|
+
|
|
51
|
+
# ── GitHub Actions (release.yml + ci.yml) ────────────────────────────
|
|
52
|
+
- package-ecosystem: "github-actions"
|
|
53
|
+
directory: "/"
|
|
54
|
+
schedule:
|
|
55
|
+
interval: "weekly"
|
|
56
|
+
day: "monday"
|
|
57
|
+
open-pull-requests-limit: 5
|
|
58
|
+
commit-message:
|
|
59
|
+
prefix: "deps(actions)"
|
|
60
|
+
labels:
|
|
61
|
+
- "dependencies"
|
|
62
|
+
- "github-actions"
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# sdk/.github/scripts/assemble_release_evidence.sh — PRD-028 PR α companion.
|
|
3
|
+
#
|
|
4
|
+
# Invoked by release.yml after verify-published succeeds. Collects build
|
|
5
|
+
# metadata + SBOM digest + SLSA provenance URL + Sigstore bundle ref +
|
|
6
|
+
# private-source SHA, writes RELEASE_EVIDENCE.md, and attaches it as a
|
|
7
|
+
# GitHub Release asset.
|
|
8
|
+
#
|
|
9
|
+
# Row schema is forward-compatible with PRD-013 Merkle ledger.
|
|
10
|
+
#
|
|
11
|
+
# Required environment:
|
|
12
|
+
# GITHUB_REF_NAME — the sdk-v<X.Y.Z> tag
|
|
13
|
+
# GITHUB_SHA — the tagged commit SHA on the public repo
|
|
14
|
+
# SDK_VERSION — X.Y.Z (resolved by release.yml/prepare)
|
|
15
|
+
# IS_RC — "true" or "false"
|
|
16
|
+
# SDIST_SHA256 — from release.yml/build
|
|
17
|
+
# WHEEL_SHA256 — from release.yml/build
|
|
18
|
+
# SBOM_PATH — path to sbom.cdx.json (downloaded artifact)
|
|
19
|
+
# SLSA_PROVENANCE_URL — URL to the .intoto.jsonl provenance asset
|
|
20
|
+
# SIGSTORE_BUNDLE — Sigstore signing bundle ref (set by publish job)
|
|
21
|
+
# PRIVATE_REPO_READ_TOKEN — fine-grained PAT, read-only, single path on
|
|
22
|
+
# ghantakiran/ShieldOps; used to resolve the
|
|
23
|
+
# matching private source SHA from
|
|
24
|
+
# tools/SDK_TREE_PINS.txt.
|
|
25
|
+
#
|
|
26
|
+
# Output:
|
|
27
|
+
# RELEASE_EVIDENCE.md in repo root, then `gh release upload`'d.
|
|
28
|
+
|
|
29
|
+
set -euo pipefail
|
|
30
|
+
|
|
31
|
+
: "${GITHUB_REF_NAME:?}"
|
|
32
|
+
: "${GITHUB_SHA:?}"
|
|
33
|
+
: "${SDK_VERSION:?}"
|
|
34
|
+
: "${SDIST_SHA256:?}"
|
|
35
|
+
: "${WHEEL_SHA256:?}"
|
|
36
|
+
|
|
37
|
+
# Optional with sensible defaults so the script is testable locally.
|
|
38
|
+
IS_RC="${IS_RC:-false}"
|
|
39
|
+
SBOM_PATH="${SBOM_PATH:-sbom.cdx.json}"
|
|
40
|
+
SLSA_PROVENANCE_URL="${SLSA_PROVENANCE_URL:-pending}"
|
|
41
|
+
SIGSTORE_BUNDLE="${SIGSTORE_BUNDLE:-pending}"
|
|
42
|
+
|
|
43
|
+
# Resolve the matching private-source SHA from tools/SDK_TREE_PINS.txt
|
|
44
|
+
# on the private monorepo using the single-path read-only PAT. The pin
|
|
45
|
+
# file is the only file this token can read.
|
|
46
|
+
PRIVATE_SOURCE_SHA="unknown"
|
|
47
|
+
if [[ -n "${PRIVATE_REPO_READ_TOKEN:-}" ]]; then
|
|
48
|
+
PINS=$(curl -sf \
|
|
49
|
+
-H "Accept: application/vnd.github.raw" \
|
|
50
|
+
-H "Authorization: Bearer ${PRIVATE_REPO_READ_TOKEN}" \
|
|
51
|
+
"https://api.github.com/repos/ghantakiran/ShieldOps/contents/tools/SDK_TREE_PINS.txt" \
|
|
52
|
+
|| echo "")
|
|
53
|
+
if [[ -n "${PINS}" ]]; then
|
|
54
|
+
PRIVATE_SOURCE_SHA=$(echo "${PINS}" \
|
|
55
|
+
| awk -v ver="${SDK_VERSION}" '
|
|
56
|
+
$0 ~ "^sdk-v"ver"$" { found=1; next }
|
|
57
|
+
found && /^private_main_sha:/ { print $2; exit }
|
|
58
|
+
' || echo "lookup-failed")
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
SBOM_DIGEST="unknown"
|
|
63
|
+
if [[ -f "${SBOM_PATH}" ]]; then
|
|
64
|
+
SBOM_DIGEST=$(sha256sum "${SBOM_PATH}" | cut -d' ' -f1)
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
cat > RELEASE_EVIDENCE.md <<EOF
|
|
68
|
+
# Release Evidence — ${GITHUB_REF_NAME}
|
|
69
|
+
|
|
70
|
+
This file is auto-generated by .github/scripts/assemble_release_evidence.sh.
|
|
71
|
+
Schema is forward-compatible with the PRD-013 Merkle ledger.
|
|
72
|
+
|
|
73
|
+
| Field | Value |
|
|
74
|
+
|---|---|
|
|
75
|
+
| Tag | \`${GITHUB_REF_NAME}\` |
|
|
76
|
+
| SDK version | \`${SDK_VERSION}\` |
|
|
77
|
+
| Release candidate | \`${IS_RC}\` |
|
|
78
|
+
| Public release SHA | \`${GITHUB_SHA}\` |
|
|
79
|
+
| Private source SHA | \`${PRIVATE_SOURCE_SHA}\` |
|
|
80
|
+
| sdist SHA-256 | \`${SDIST_SHA256}\` |
|
|
81
|
+
| wheel SHA-256 | \`${WHEEL_SHA256}\` |
|
|
82
|
+
| SBOM (CycloneDX) digest | \`${SBOM_DIGEST}\` |
|
|
83
|
+
| SLSA provenance | ${SLSA_PROVENANCE_URL} |
|
|
84
|
+
| Sigstore bundle | ${SIGSTORE_BUNDLE} |
|
|
85
|
+
| Generated at | $(date -u +%Y-%m-%dT%H:%M:%SZ) |
|
|
86
|
+
|
|
87
|
+
## Verifying this release
|
|
88
|
+
|
|
89
|
+
\`\`\`bash
|
|
90
|
+
# Verify the wheel matches the published artifact
|
|
91
|
+
pip download --no-deps shieldops-sdk==${SDK_VERSION} -d /tmp/verify
|
|
92
|
+
sha256sum /tmp/verify/shieldops_sdk-*.whl # should match wheel SHA-256 above
|
|
93
|
+
|
|
94
|
+
# Verify Sigstore signature (after PR β #647 lands)
|
|
95
|
+
python -m sigstore verify identity \\
|
|
96
|
+
--bundle "\${SIGSTORE_BUNDLE_PATH}" \\
|
|
97
|
+
--cert-identity-regexp '^https://github.com/shieldops-io/shieldops-sdk/' \\
|
|
98
|
+
--cert-oidc-issuer https://token.actions.githubusercontent.com \\
|
|
99
|
+
/tmp/verify/shieldops_sdk-*.whl
|
|
100
|
+
|
|
101
|
+
# Verify SLSA provenance via slsa-verifier
|
|
102
|
+
slsa-verifier verify-artifact /tmp/verify/shieldops_sdk-*.whl \\
|
|
103
|
+
--provenance-path provenance.intoto.jsonl \\
|
|
104
|
+
--source-uri github.com/shieldops-io/shieldops-sdk \\
|
|
105
|
+
--source-tag ${GITHUB_REF_NAME}
|
|
106
|
+
\`\`\`
|
|
107
|
+
EOF
|
|
108
|
+
|
|
109
|
+
echo "RELEASE_EVIDENCE.md written:"
|
|
110
|
+
cat RELEASE_EVIDENCE.md
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pull-requests: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ci-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
test:
|
|
19
|
+
name: test (py${{ matrix.python-version }} / ${{ matrix.os }})
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
25
|
+
os: [ubuntu-latest, macos-latest]
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
32
|
+
uses: actions/setup-python@v5
|
|
33
|
+
with:
|
|
34
|
+
python-version: ${{ matrix.python-version }}
|
|
35
|
+
cache: pip
|
|
36
|
+
|
|
37
|
+
- name: Install
|
|
38
|
+
run: |
|
|
39
|
+
python -m pip install --upgrade pip
|
|
40
|
+
pip install -e ".[dev]"
|
|
41
|
+
|
|
42
|
+
- name: Lint (ruff check)
|
|
43
|
+
run: ruff check src/ tests/
|
|
44
|
+
|
|
45
|
+
- name: Format (ruff format --check)
|
|
46
|
+
run: ruff format --check src/ tests/
|
|
47
|
+
|
|
48
|
+
- name: Test (pytest)
|
|
49
|
+
run: pytest tests/ -v --tb=short
|
|
50
|
+
|
|
51
|
+
dco:
|
|
52
|
+
name: DCO sign-off check
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
if: github.event_name == 'pull_request'
|
|
55
|
+
steps:
|
|
56
|
+
- name: Checkout
|
|
57
|
+
uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
fetch-depth: 0
|
|
60
|
+
|
|
61
|
+
- name: Verify DCO
|
|
62
|
+
uses: tim-actions/dco@v1.1.0
|