pub struct HermeticParallelConfig {
iteration: u32,
admin_secret_handling: AdministrativeSecretHandling,
non_admin_secret_handling: NonAdministrativeSecretHandling,
connections: HashSet<Connection>,
users: HashSet<UserMapping>,
settings: ConfigSettings,
}
Expand description
A configuration for parallel use of connections with a set of system and NetHSM users.
This configuration type is meant to be used in a read-only fashion and does not support tracking the passphrases for users. As such, it is useful for tools, that create system users, as well as NetHSM users and keys according to it.
Various mappings of system and [NetHsm
] users exist, that are defined by the variants of
UserMapping
.
Some system users require providing SSH authorized key(s), while others do not allow that at all. NetHSM users can be added in namespaces, or system-wide, depending on their use-case. System and NetHSM users must be unique.
Key IDs must be unique per namespace or system-wide (depending on where they are used). Tags, used to provide access to keys for NetHSM users must be unique per namespace or system-wide (depending on in which scope the user and key are used)
§Examples
The below example provides a fully functional TOML configuration, outlining all available functionalities.
let config_string = r#"
# A non-negative integer, that describes the iteration of the configuration.
# The iteration should only ever be increased between changes to the config and only under the circumstance,
# that user mappings are removed and should also be removed from the state of the system making use of this
# configuration.
# Applications reading the configuration are thereby enabled to compare existing state on the system with the
# current iteration and remove user mappings and accompanying data accordingly.
iteration = 1
# The handling of administrative secrets on the system.
# One of:
# - "shamirs-secret-sharing": Administrative secrets are never persisted on the system and only provided as shares of a shared secret.
# - "systemd-creds": Administrative secrets are persisted on the system as host-specific files, encrypted using systemd-creds (only for testing).
# - "plaintext": Administrative secrets are persisted on the system in unencrypted plaintext files (only for testing).
admin_secret_handling = "shamirs-secret-sharing"
# The handling of non-administrative secrets on the system.
# One of:
# - "systemd-creds": Non-administrative secrets are persisted on the system as host-specific files, encrypted using systemd-creds (the default).
# - "plaintext": Non-administrative secrets are persisted on the system in unencrypted plaintext files (only for testing).
non_admin_secret_handling = "systemd-creds"
[[connections]]
url = "https://localhost:8443/api/v1/"
tls_security = "Unsafe"
# The NetHSM user "admin" is a system-wide Administrator
[[users]]
nethsm_only_admin = "admin"
# The SSH-accessible system user "ssh-backup1" is used in conjunction with
# the NetHSM user "backup1" (system-wide Backup)
[[users]]
[users.system_nethsm_backup]
nethsm_user = "backup1"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkpXKiNhy39A3bZ1u19a5d4sFwYMBkWQyCbzgUfdKBm user@host"
system_user = "ssh-backup1"
# The SSH-accessible system user "ssh-metrics1" is used with several NetHSM users:
# - "metrics1" (system-wide Metrics)
# - "keymetrics1" (system-wide Operator)
# - "ns1~keymetrics1" (namespace Operator)
[[users]]
[users.system_nethsm_metrics]
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDgwGfIRBAsOUuDEZw/uJQZSwOYr4sg2DAZpcc7MfOj user@host"
system_user = "ssh-metrics1"
[users.system_nethsm_metrics.nethsm_users]
metrics_user = "metrics1"
operator_users = ["keymetrics1", "ns1~keymetrics1"]
# The SSH-accessible system user "ssh-operator1" is used in conjunction with
# the NetHSM user "operator1" (system-wide Operator).
# User "operator1" shares tag "tag1" with key "key1" and can therefore use it
# (for OpenPGP signing).
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "operator1"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAN54Gd1jMz+yNDjBRwX1SnOtWuUsVF64RJIeYJ8DI7b user@host"
system_user = "ssh-operator1"
tag = "tag1"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key1"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
# The SSH-accessible system user "ssh-operator2" is used in conjunction with
# the NetHSM user "operator2" (system-wide Operator).
# User "operator2" shares tag "tag2" with key "key2" and can therefore use it
# (for OpenPGP signing).
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "operator2"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh9BTe81DC6A0YZALsq9dWcyl6xjjqlxWPwlExTFgBt user@host"
system_user = "ssh-operator2"
tag = "tag2"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key2"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
# The NetHSM user "ns1~admin" is a namespace Administrator
[[users]]
nethsm_only_admin = "ns1~admin"
# The SSH-accessible system user "ns1-ssh-operator1" is used in conjunction with
# the NetHSM user "ns1~operator1" (namespace Operator).
# User "ns1~operator1" shares tag "tag1" with key "key1" and can therefore use it
# in its namespace (for OpenPGP signing).
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "ns1~operator1"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILWqWyMCk5BdSl1c3KYoLEokKr7qNVPbI1IbBhgEBQj5 user@host"
system_user = "ns1-ssh-operator1"
tag = "tag1"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key1"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
# The SSH-accessible system user "ns1-ssh-operator2" is used in conjunction with
# the NetHSM user "ns2~operator1" (namespace Operator).
# User "ns1~operator2" shares tag "tag2" with key "key1" and can therefore use it
# in its namespace (for OpenPGP signing).
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "ns1~operator2"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrIYA+bfMBThUP5lKbMFEHiytmcCPhpkGrB/85n0mAN user@host"
system_user = "ns1-ssh-operator2"
tag = "tag2"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key2"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
# The hermetic system user "local-metrics1" is used with several NetHSM users:
# - "metrics2" (system-wide Metrics)
# - "keymetrics2" (system-wide Operator)
# - "ns1~keymetrics2" (namespace Operator)
[[users]]
[users.hermetic_system_nethsm_metrics]
system_user = "local-metrics1"
[users.hermetic_system_nethsm_metrics.nethsm_users]
metrics_user = "metrics2"
operator_users = ["keymetrics2", "ns1~keymetrics2"]
# The SSH-accessible system user "ssh-share-down" is used for the
# download of shares of a shared secret (divided by Shamir's Secret Sharing).
[[users]]
[users.system_only_share_download]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host"]
system_user = "ssh-share-down"
# The SSH-accessible system user "ssh-share-up" is used for the
# upload of shares of a shared secret (divided by Shamir's Secret Sharing).
[[users]]
[users.system_only_share_upload]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host"]
system_user = "ssh-share-up"
# The SSH-accessible system user "ssh-wireguard-down" is used for the
# download of WireGuard configuration, used on the host.
[[users]]
[users.system_only_wireguard_download]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIClIXZdx0aDOPcIQA+6Qx68cwSUgGTL3TWzDSX3qUEOQ user@host"]
system_user = "ssh-wireguard-down"
"#;
Fields§
§iteration: u32
§admin_secret_handling: AdministrativeSecretHandling
§non_admin_secret_handling: NonAdministrativeSecretHandling
§connections: HashSet<Connection>
§users: HashSet<UserMapping>
§settings: ConfigSettings
Implementations§
Source§impl HermeticParallelConfig
impl HermeticParallelConfig
Sourcepub fn new_from_file(
config_settings: ConfigSettings,
path: Option<&Path>,
) -> Result<Self, Error>
pub fn new_from_file( config_settings: ConfigSettings, path: Option<&Path>, ) -> Result<Self, Error>
Creates a new HermeticParallelConfig
from a configuration file.
§Errors
Returns an error if the configuration file can not be loaded.
§Examples
use nethsm_config::{ConfigInteractivity, ConfigName, ConfigSettings, HermeticParallelConfig};
let config_file = testdir::testdir!().join("basic_parallel_config_new.conf");
{
#[rustfmt::skip]
let config_string = r#"
iteration = 1
admin_secret_handling = "shamirs-secret-sharing"
non_admin_secret_handling = "systemd-creds"
[[connections]]
url = "https://localhost:8443/api/v1/"
tls_security = "Unsafe"
[[users]]
nethsm_only_admin = "admin"
[[users]]
[users.system_nethsm_backup]
nethsm_user = "backup1"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkpXKiNhy39A3bZ1u19a5d4sFwYMBkWQyCbzgUfdKBm user@host"
system_user = "ssh-backup1"
[[users]]
[users.system_nethsm_metrics]
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDgwGfIRBAsOUuDEZw/uJQZSwOYr4sg2DAZpcc7MfOj user@host"
system_user = "ssh-metrics1"
[users.system_nethsm_metrics.nethsm_users]
metrics_user = "metrics1"
operator_users = ["operator1metrics1"]
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "operator1"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAN54Gd1jMz+yNDjBRwX1SnOtWuUsVF64RJIeYJ8DI7b user@host"
system_user = "ssh-operator1"
tag = "tag1"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key1"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
[[users]]
[users.system_nethsm_operator_signing]
nethsm_user = "operator2"
ssh_authorized_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh9BTe81DC6A0YZALsq9dWcyl6xjjqlxWPwlExTFgBt user@host"
system_user = "ssh-operator2"
tag = "tag2"
[users.system_nethsm_operator_signing.nethsm_key_setup]
key_id = "key2"
key_type = "Curve25519"
key_mechanisms = ["EdDsaSignature"]
signature_type = "EdDsa"
[users.system_nethsm_operator_signing.nethsm_key_setup.key_context.openpgp]
user_ids = ["Foobar McFooface <foobar@mcfooface.org>"]
version = "4"
[[users]]
[users.hermetic_system_nethsm_metrics]
system_user = "local-metrics1"
[users.hermetic_system_nethsm_metrics.nethsm_users]
metrics_user = "metrics2"
operator_users = ["operator2metrics1"]
[[users]]
[users.system_only_share_download]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host"]
system_user = "ssh-share-down"
[[users]]
[users.system_only_share_upload]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host"]
system_user = "ssh-share-up"
[[users]]
[users.system_only_wireguard_download]
ssh_authorized_keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIClIXZdx0aDOPcIQA+6Qx68cwSUgGTL3TWzDSX3qUEOQ user@host"]
system_user = "ssh-wireguard-down"
"#;
let mut buffer = std::fs::File::create(&config_file)?;
buffer.write_all(config_string.as_bytes())?;
}
HermeticParallelConfig::new_from_file(
ConfigSettings::new(
"my_app".to_string(),
ConfigInteractivity::NonInteractive,
None,
),
Some(&config_file),
)?;
Sourcepub fn new(
config_settings: ConfigSettings,
iteration: u32,
admin_secret_handling: AdministrativeSecretHandling,
non_admin_secret_handling: NonAdministrativeSecretHandling,
connections: HashSet<Connection>,
users: HashSet<UserMapping>,
) -> Result<Self, Error>
pub fn new( config_settings: ConfigSettings, iteration: u32, admin_secret_handling: AdministrativeSecretHandling, non_admin_secret_handling: NonAdministrativeSecretHandling, connections: HashSet<Connection>, users: HashSet<UserMapping>, ) -> Result<Self, Error>
Creates a new HermeticParallelConfig
.
§Errors
Returns an error if the configuration file can not be loaded.
§Examples
use std::collections::HashSet;
use nethsm::UserRole;
use nethsm_config::{
AdministrativeSecretHandling,
AuthorizedKeyEntryList,
ConfigCredentials,
ConfigInteractivity,
ConfigName,
ConfigSettings,
Connection,
HermeticParallelConfig,
NonAdministrativeSecretHandling,
UserMapping,
};
HermeticParallelConfig::new(
ConfigSettings::new(
"my_app".to_string(),
ConfigInteractivity::NonInteractive,
None,
),
1,
AdministrativeSecretHandling::ShamirsSecretSharing,
NonAdministrativeSecretHandling::SystemdCreds,
HashSet::from([Connection::new(
"https://localhost:8443/api/v1/".parse()?,
"Unsafe".parse()?,
)]),
HashSet::from([
UserMapping::NetHsmOnlyAdmin("admin".parse()?),
UserMapping::SystemOnlyShareDownload {
system_user: "ssh-share-down".parse()?,
ssh_authorized_keys: AuthorizedKeyEntryList::new(vec!["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host".parse()?])?,
},
UserMapping::SystemOnlyShareUpload {
system_user: "ssh-share-up".parse()?,
ssh_authorized_keys: AuthorizedKeyEntryList::new(vec!["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host".parse()?])?,
}]),
)?;
Sourcepub fn store(&self, path: Option<&Path>) -> Result<(), Error>
pub fn store(&self, path: Option<&Path>) -> Result<(), Error>
Writes a HermeticParallelConfig
to file.
§Errors
Returns an error if the configuration file can not be written.
§Examples
use std::collections::HashSet;
use nethsm::{CryptographicKeyContext, OpenPgpUserIdList, SigningKeySetup, UserRole};
use nethsm_config::{
AuthorizedKeyEntryList,
AdministrativeSecretHandling,
ConfigCredentials,
ConfigInteractivity,
ConfigName,
ConfigSettings,
Connection,
HermeticParallelConfig,
NetHsmMetricsUsers,
NonAdministrativeSecretHandling,
UserMapping,
};
let config = HermeticParallelConfig::new(
ConfigSettings::new(
"my_app".to_string(),
ConfigInteractivity::NonInteractive,
None,
),
1,
AdministrativeSecretHandling::ShamirsSecretSharing,
NonAdministrativeSecretHandling::SystemdCreds,
HashSet::from([Connection::new(
"https://localhost:8443/api/v1/".parse()?,
"Unsafe".parse()?,
)]),
HashSet::from([UserMapping::NetHsmOnlyAdmin("admin".parse()?),
UserMapping::SystemNetHsmBackup {
nethsm_user: "backup1".parse()?,
ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkpXKiNhy39A3bZ1u19a5d4sFwYMBkWQyCbzgUfdKBm user@host".parse()?,
system_user: "ssh-backup1".parse()?,
},
UserMapping::SystemNetHsmMetrics {
nethsm_users: NetHsmMetricsUsers::new("metrics1".parse()?, vec!["operator2metrics1".parse()?])?,
ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIioJ9uvAxUPunFh89T+ENo7OQerqHE8SQ+2v4VWbfUZ user@host".parse()?,
system_user: "ssh-metrics1".parse()?,
},
UserMapping::SystemNetHsmOperatorSigning {
nethsm_user: "operator1".parse()?,
nethsm_key_setup: SigningKeySetup::new(
"key1".parse()?,
"Curve25519".parse()?,
vec!["EdDsaSignature".parse()?],
None,
"EdDsa".parse()?,
CryptographicKeyContext::OpenPgp{
user_ids: OpenPgpUserIdList::new(vec!["Foobar McFooface <foobar@mcfooface.org>".parse()?])?,
version: "4".parse()?,
})?,
ssh_authorized_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAN54Gd1jMz+yNDjBRwX1SnOtWuUsVF64RJIeYJ8DI7b user@host".parse()?,
system_user: "ssh-operator1".parse()?,
tag: "tag1".to_string(),
},
UserMapping::HermeticSystemNetHsmMetrics {
nethsm_users: NetHsmMetricsUsers::new("metrics2".parse()?, vec!["operator1metrics1".parse()?])?,
system_user: "local-metrics1".parse()?,
},
UserMapping::SystemOnlyShareDownload {
system_user: "ssh-share-down".parse()?,
ssh_authorized_keys: AuthorizedKeyEntryList::new(
vec!["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host".parse()?],
)?,
},
UserMapping::SystemOnlyShareUpload {
system_user: "ssh-share-up".parse()?,
ssh_authorized_keys: AuthorizedKeyEntryList::new(
vec!["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOh96uFTnvX6P1ebbLxXFvy6sK7qFqlMHDOuJ0TmuXQQ user@host".parse()?],
)?,
},
UserMapping::SystemOnlyWireGuardDownload {
system_user: "ssh-wireguard-down".parse()?,
ssh_authorized_keys: AuthorizedKeyEntryList::new(
vec!["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIClIXZdx0aDOPcIQA+6Qx68cwSUgGTL3TWzDSX3qUEOQ user@host".parse()?],
)?,
},
]),
)?;
let config_file = testdir::testdir!().join("basic_parallel_config_store.conf");
config.store(Some(&config_file))?;
Sourcepub fn iter_connections(&self) -> impl Iterator<Item = &Connection>
pub fn iter_connections(&self) -> impl Iterator<Item = &Connection>
Returns an Iterator over the available Connection
s.
Sourcepub fn iter_user_mappings(&self) -> impl Iterator<Item = &UserMapping>
pub fn iter_user_mappings(&self) -> impl Iterator<Item = &UserMapping>
Returns an Iterator over the available UserMapping
s.
Trait Implementations§
Source§impl Clone for HermeticParallelConfig
impl Clone for HermeticParallelConfig
Source§fn clone(&self) -> HermeticParallelConfig
fn clone(&self) -> HermeticParallelConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more