Skip to content
15 changes: 15 additions & 0 deletions architecture/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,21 @@ Driver-specific values that are not part of the inheritance allowlist
(e.g. Podman `socket_path`, VM `vcpus`) only come from the driver's own
table.

### Package-managed gateway registry

The CLI reads its active-gateway and per-gateway metadata from
`$XDG_CONFIG_HOME/openshell/`. It also looks for a package-manager owned
system config root at `/etc/openshell`, using the same layout as the per-user
config root: `active_gateway` plus `gateways/<name>/metadata.json`. Packages
or runtimes that need a different location can override that root with a
non-empty absolute `OPENSHELL_SYSTEM_GATEWAY_DIR`; empty or relative values
fall back to `/etc/openshell` and emit a warning. The CLI falls back to this
system config when no per-user `metadata.json` exists; malformed user metadata
still shadows the system entry, but stray empty directories do not.

System entries are read-only from the CLI, so `gateway remove` rejects a pure
system entry instead of pretending to delete package-manager owned state.

## Operational Constraints

- Gateway TLS and client certificate distribution are deployment concerns owned
Expand Down
6 changes: 3 additions & 3 deletions crates/openshell-bootstrap/src/edge_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
//! `$XDG_CONFIG_HOME/openshell/gateways/<name>/edge_token`.
//! The token is a plain-text JWT string with `0600` permissions.

use crate::paths::gateways_dir;
use crate::paths::user_gateways_dir;
use miette::{IntoDiagnostic, Result, WrapErr};
use openshell_core::paths::{ensure_parent_dir_restricted, set_file_owner_only};
use std::path::PathBuf;

/// Path to the stored edge auth token for a gateway.
pub fn edge_token_path(gateway_name: &str) -> Result<PathBuf> {
Ok(gateways_dir()?.join(gateway_name).join("edge_token"))
Ok(user_gateways_dir()?.join(gateway_name).join("edge_token"))
}

/// Legacy path used before the rename to `edge_token`.
fn legacy_token_path(gateway_name: &str) -> Result<PathBuf> {
Ok(gateways_dir()?.join(gateway_name).join("cf_token"))
Ok(user_gateways_dir()?.join(gateway_name).join("cf_token"))
}

/// Store an edge authentication token for a gateway.
Expand Down
11 changes: 6 additions & 5 deletions crates/openshell-bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod oidc_token;

mod metadata;
pub mod mtls;
pub mod paths;
mod paths;
pub mod pki;

#[cfg(test)]
Expand All @@ -21,8 +21,9 @@ use std::sync::Mutex;
pub(crate) static XDG_TEST_LOCK: Mutex<()> = Mutex::new(());

pub use crate::metadata::{
GatewayMetadata, clear_active_gateway, clear_last_sandbox_if_matches,
extract_host_from_ssh_destination, get_gateway_metadata, list_gateways, load_active_gateway,
load_gateway_metadata, load_last_sandbox, remove_gateway_metadata, resolve_ssh_hostname,
save_active_gateway, save_last_sandbox, store_gateway_metadata,
GatewayMetadata, GatewayMetadataSource, ListedGateway, clear_active_gateway,
clear_last_sandbox_if_matches, extract_host_from_ssh_destination, gateway_metadata_source,
get_gateway_metadata, list_gateways, list_gateways_with_source, load_active_gateway,
load_gateway_metadata, load_last_sandbox, load_user_active_gateway, remove_gateway_metadata,
resolve_ssh_hostname, save_active_gateway, save_last_sandbox, store_gateway_metadata,
};
Loading
Loading