Files
Mike Nguyen 9fd41e6bfd fix(ssh): persist sandbox host identities (#4094)
* fix(ssh): persist sandbox host identities

Store each sandbox's Ed25519 host key in the gateway credential store and
deliver it only to the supervisor. Preserve identity across restarts,
delete owned credentials with the sandbox, and expose the public SHA256
fingerprint through sandbox and SSH-session APIs and client SDKs.

Cover credential ownership, cancellation, deletion retries, client
compatibility, and pinned SSH connections through lifecycle transitions.

Closes #3835

Signed-off-by: Mike Nguyen <miken@nvidia.com>

* fix(compute): clean up failed sandbox SSH identity creation

Signed-off-by: Mike Nguyen <miken@nvidia.com>

* test(ssh): wait for sandbox deletion before name reuse

Signed-off-by: Mike Nguyen <miken@nvidia.com>

---------

Signed-off-by: Mike Nguyen <miken@nvidia.com>
2026-10-06 20:09:20 +00:00

150 lines
5.1 KiB
TOML

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
[package]
name = "openshell-server"
description = "OpenShell gRPC/HTTP server with protocol multiplexing"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
[dependencies]
openshell-bootstrap = { path = "../openshell-bootstrap" }
openshell-core = { path = "../openshell-core", default-features = false, features = ["jwt", "oauth"] }
openshell-driver-db-credstore = { path = "../openshell-driver-db-credstore" }
openshell-driver-kubernetes-secrets = { path = "../openshell-driver-kubernetes-secrets" }
openshell-driver-vault = { path = "../openshell-driver-vault" }
openshell-extension-core = { path = "../openshell-extension-core" }
openshell-gateway-interceptors = { path = "../openshell-gateway-interceptors" }
openshell-ocsf = { path = "../openshell-ocsf" }
openshell-otel = { path = "../openshell-otel" }
openshell-policy = { path = "../openshell-policy" }
openshell-prover = { path = "../openshell-prover" }
openshell-providers = { path = "../openshell-providers" }
openshell-supervisor-middleware = { path = "../openshell-supervisor-middleware" }
openshell-supervisor-middleware-builtins = { path = "../openshell-supervisor-middleware-builtins" }
# Kubernetes client used by ServiceAccount bootstrap authentication and the
# `generate-certs` subcommand.
kube = { workspace = true }
k8s-openapi = { workspace = true }
# Async runtime
tokio = { workspace = true }
socket2 = { workspace = true, features = ["all"] }
nix = { workspace = true }
libc = "0.2"
# gRPC
tonic = { workspace = true, features = ["channel", "tls-native-roots"] }
prost = { workspace = true }
prost-reflect = { workspace = true }
prost-types = { workspace = true }
# HTTP server
axum = { workspace = true }
tower = { workspace = true }
tower-http = { workspace = true }
hyper = { workspace = true }
hyper-util = { workspace = true, features = ["client", "http1", "http2"] }
http = { workspace = true }
http-body = { workspace = true }
http-body-util = { workspace = true }
# TLS
tokio-rustls = { workspace = true }
rustls = { workspace = true }
rustls-pemfile = { workspace = true }
# CLI
clap = { workspace = true }
# Error handling
miette = { workspace = true }
thiserror = { workspace = true }
anyhow = { workspace = true }
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
# Logging
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
tracing-appender = { workspace = true }
# OpenTelemetry (OTLP trace export, opt-in via [openshell.gateway.otlp])
opentelemetry = { workspace = true }
opentelemetry_sdk = { workspace = true }
tracing-opentelemetry = { workspace = true }
# Metrics
metrics = { workspace = true }
metrics-exporter-prometheus = { workspace = true }
# Utilities
base64 = { workspace = true }
futures = { workspace = true }
bytes = { workspace = true }
pin-project-lite = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
toml = { workspace = true }
tokio-stream = { workspace = true }
sqlx = { workspace = true }
sqlx-core = { workspace = true }
reqwest = { workspace = true }
aws-config = { workspace = true }
aws-sdk-sts = { workspace = true }
uuid = { workspace = true }
hmac = "0.12"
sha2 = { workspace = true }
jsonwebtoken = { workspace = true }
spiffe = { workspace = true }
async-trait = "0.1"
url = { workspace = true }
glob = { workspace = true }
hex = "0.4"
russh = "0.63.1"
rand = { workspace = true }
rand-ssh = { package = "rand", version = "0.10" }
petname = "2"
ipnet = "2"
tempfile = "3"
rustix = { workspace = true }
x509-parser = "0.16"
arc-swap = "1"
notify = "8"
[features]
default = ["telemetry"]
## Compile in anonymous telemetry emission (forwards to openshell-core/telemetry).
## On by default; build with `--no-default-features` for a telemetry-free gateway
## that contains no telemetry endpoint, HTTP client, or emission code.
telemetry = ["openshell-core/telemetry"]
vendored-z3 = ["openshell-prover/vendored-z3"]
prebuilt-z3 = ["openshell-prover/prebuilt-z3"]
test-support = []
[build-dependencies]
tonic-prost-build = { workspace = true }
protoc-bin-vendored = { workspace = true }
[dev-dependencies]
tracing-core = "0.1"
tokio = { workspace = true, features = ["test-util"] }
# Tests import the example profiles from providers/ the way an operator
# would; the feature is test-only and never reaches a release binary.
openshell-providers = { path = "../openshell-providers", features = ["example-profiles"] }
base64 = { workspace = true }
hyper-rustls = { version = "0.27", default-features = false, features = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] }
rcgen = { workspace = true }
rsa = { version = "0.9", features = ["pem"] }
tokio-tungstenite = { workspace = true }
futures-util = "0.3"
wiremock = "0.6"
# `testing` provides InMemorySpanExporter, so span assertions do not need a
# collector, a network hop, or a flush barrier.
opentelemetry_sdk = { workspace = true, features = ["testing"] }
[lints]
workspace = true