Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/build-from-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ Every PR from this issue-backed workflow must have its own existing issue and us
Do not apply acceptance or roadmap decisions on behalf of a maintainer. Do not introduce `agent:*` workflow labels.

For first-party security-sensitive crypto, use `openshell-crypto` and extend its facade/backend contracts when needed. Follow the [crypto architecture](../../../crates/openshell-crypto/CRYPTO.md) for compatibility, failure handling, and explicit coverage exceptions.

When changing crypto dependencies, run `mise run rust:deny:policy`, including its dependency-boundary regression fixtures. Review any `deny.toml` wrapper change against the documented exception scope; an existing allowance does not authorize new security-sensitive operations outside the facade.
2 changes: 2 additions & 0 deletions .agents/skills/fix-security-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ Use this skill after an authorized `review-security-issue` review identifies an
Begin any fix comments with `> **🔧 security-fix-agent**`. Do not change human disposition or introduce `agent:*` workflow labels.

For first-party security-sensitive crypto, use `openshell-crypto` and extend its facade/backend contracts when needed. Follow the [crypto architecture](../../../crates/openshell-crypto/CRYPTO.md) for compatibility, failure handling, and explicit coverage exceptions.

When changing crypto dependencies, run `mise run rust:deny:policy`, including its dependency-boundary regression fixtures. Review any `deny.toml` wrapper change against the documented exception scope; an existing allowance does not authorize new security-sensitive operations outside the facade.
2 changes: 1 addition & 1 deletion .agents/skills/review-github-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Read through the full diff (and the PR description if available). Produce a summ
suggested change.
- Do not fabricate concerns or claim a behavioral regression without evidence
for both the prior and proposed behavior.
- **Cryptographic boundaries**: For changed first-party security-sensitive crypto, verify use of `openshell-crypto`, backend dispatch, failure propagation without fallback, and protocol/storage compatibility. Missing operations belong in the facade/backend contracts. Check dependency-owned and non-security exceptions against the repository's [crypto architecture](../../../crates/openshell-crypto/CRYPTO.md); protocol/parsing types alone are not bypasses. Report undocumented bypasses or scope expansion under **Potential Concerns**.
- **Cryptographic boundaries**: For changed first-party security-sensitive crypto, verify use of `openshell-crypto`, backend dispatch, failure propagation without fallback, and protocol/storage compatibility. Missing operations belong in the facade/backend contracts. Check dependency-owned and other explicit exceptions against the repository's [crypto architecture](../../../crates/openshell-crypto/CRYPTO.md); protocol/parsing types alone are not bypasses. Check `mise run rust:deny:policy` results and review changes to `deny.toml` wrappers; package-level allowances do not authorize new bypasses within those packages. Report undocumented bypasses or scope expansion under **Potential Concerns**.
- **Agent infrastructure**: When the PR changes behavior, commands, or development workflows, use the `sync-agent-infra` maintenance map to check that related skills were updated. When it adds, removes, or renames skills or crates; changes workflow relationships or skill coverage; modifies issue or PR templates; or changes agent cross-references, apply the full consistency checklist. Report missing companion updates or drift under **Potential Concerns**.

## Step 5: Output
Expand Down
49 changes: 47 additions & 2 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,15 @@ jobs:
prepare-shell: "true"
shell-installable: .#devShells.x86_64-linux.default

- name: Install pinned cargo-deny
run: mise install --locked github:EmbarkStudios/cargo-deny

# Enter mise inside the Nix shell so Nix's cargo-deny cannot shadow the pin.
- name: Verify crypto dependency guardrail
run: mise exec github:EmbarkStudios/cargo-deny -- uv run --no-project python tasks/scripts/test-crypto-dependency-policy.py

- name: Check dependencies
run: cargo deny check licenses bans sources
run: mise exec github:EmbarkStudios/cargo-deny -- cargo deny check licenses bans sources

rust-format:
name: Rust format
Expand Down Expand Up @@ -312,14 +319,52 @@ jobs:
- name: Verify crypto backend independence
shell: nix develop -c bash -euo pipefail {0}
run: |
cargo tree --locked -p openshell-crypto --no-default-features --edges normal,build,dev --prefix none > /tmp/openshell-crypto-dependencies.txt
cargo tree --locked -p openshell-crypto --no-default-features --edges normal,build,dev --target all --prefix none > /tmp/openshell-crypto-dependencies.txt
if grep -Eq '^(ring|aws-lc-rs|aws-lc-sys|aws-lc-fips-sys) v' /tmp/openshell-crypto-dependencies.txt; then
echo "ERROR: backend-free crypto build includes Ring or AWS-LC" >&2
cat /tmp/openshell-crypto-dependencies.txt >&2
exit 1
fi
cargo test --locked -p openshell-crypto --no-default-features --test independent_backend

- name: Verify OpenSSL backend
shell: nix develop -c bash -euo pipefail {0}
env:
OPENSSL_NO_VENDOR: "1"
OPENSSL_STATIC: "0"
run: |
cargo tree --locked -p openshell-crypto --no-default-features --features openssl --edges normal,build,dev --target all --prefix none > /tmp/openshell-openssl-dependencies.txt
if grep -Eq '^(ring|aws-lc-rs|aws-lc-sys|aws-lc-fips-sys|openssl-src) v' /tmp/openshell-openssl-dependencies.txt; then
echo "ERROR: OpenSSL-only crypto build includes another backend or vendored OpenSSL" >&2
cat /tmp/openshell-openssl-dependencies.txt >&2
exit 1
fi
cargo clippy --locked -p openshell-crypto --no-default-features --features openssl --all-targets -- -D warnings
cargo test --locked -p openshell-crypto --no-default-features --features openssl
for feature in tls-tonic tls-kube tls-sqlx; do
cargo check --locked -p openshell-crypto --no-default-features --features "openssl,$feature"
done
cargo clippy --locked -p openshell-crypto --features openssl --all-targets -- -D warnings
cargo test --locked -p openshell-crypto --features openssl

- name: Verify dynamic OpenSSL linkage on Linux
if: runner.os == 'Linux'
shell: nix develop -c bash -euo pipefail {0}
env:
OPENSSL_NO_VENDOR: "1"
OPENSSL_STATIC: "0"
run: |
cargo test --locked -p openshell-crypto --no-default-features --features openssl --test openssl_tls --no-run --message-format=json > "$RUNNER_TEMP/openssl-artifacts.jsonl"
executable=$(uv run --no-project python -c 'import json, sys; artifacts = [json.loads(line) for line in sys.stdin]; paths = [a["executable"] for a in artifacts if a.get("reason") == "compiler-artifact" and a.get("target", {}).get("name") == "openssl_tls" and a.get("executable")]; assert len(paths) == 1, paths; print(paths[0])' < "$RUNNER_TEMP/openssl-artifacts.jsonl")
ldd "$executable" > "$RUNNER_TEMP/openssl-linkage.txt"
cat "$RUNNER_TEMP/openssl-linkage.txt"
for library in libssl libcrypto; do
if ! grep -Eq "^[[:space:]]*$library\\.so[^[:space:]]* => /" "$RUNNER_TEMP/openssl-linkage.txt"; then
echo "ERROR: $library did not resolve to a dynamic library" >&2
exit 1
fi
done

- name: Test
shell: nix develop -c bash -euo pipefail {0}
env:
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ When behavior, commands, or development workflows change, review the related age

## Security

- Route first-party security-sensitive cryptographic operations through `openshell-crypto`. If an operation is missing, extend the facade and backend implementation instead of adding a direct cryptographic implementation in an application crate. Preserve protocol compatibility and propagate backend failures without fallback. Protocol/parsing types and documented non-security or dependency-owned exceptions remain permitted; classify exceptions explicitly. Follow [Cryptography and FIPS](crates/openshell-crypto/CRYPTO.md).
- Route first-party security-sensitive cryptographic operations through `openshell-crypto`. If an operation is missing, extend the facade and backend implementation instead of adding a direct cryptographic implementation in an application crate. Preserve protocol compatibility and propagate backend failures without fallback. Protocol/parsing types and documented exceptions remain permitted; classify exceptions explicitly. Run `mise run rust:deny:policy` when changing crypto dependencies; review `deny.toml` exceptions rather than widening them to pass CI. Follow [Cryptography and FIPS](crates/openshell-crypto/CRYPTO.md).
- Never commit secrets, API keys, or credentials. If a file looks like it contains secrets (`.env`, `credentials.json`, etc.), do not stage it.
- Do not run destructive operations (force push, hard reset, database drops) without explicit human confirmation.
- Scope changes to the issue at hand. Do not make unrelated changes in the same branch.
81 changes: 80 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions crates/openshell-cli/src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ pub fn build_rustls_config(materials: &TlsMaterials) -> Result<rustls::ClientCon
.into_diagnostic()?;
let key = load_private_key(&materials.key)?;

openshell_crypto::tls::client_builder()
openshell_crypto::tls::try_client_builder()
.into_diagnostic()
.wrap_err("configure gateway TLS client")?
.with_root_certificates(roots)
.with_client_auth_cert(cert_chain, key)
.into_diagnostic()
Expand Down Expand Up @@ -252,7 +254,9 @@ impl ServerCertVerifier for InsecureServerCertVerifier {
}

pub fn build_insecure_rustls_config() -> Result<rustls::ClientConfig> {
let config = openshell_crypto::tls::client_builder()
let config = openshell_crypto::tls::try_client_builder()
.into_diagnostic()
.wrap_err("configure gateway TLS client")?
.dangerous()
.with_custom_certificate_verifier(std::sync::Arc::new(InsecureServerCertVerifier))
.with_no_client_auth();
Expand Down
Loading
Loading