Skip to content

Commit aa7aedf

Browse files
committed
introduce admin_api_ro flag to restrict operations to only r/o
In operator-based deployments, kbs-client (and in general the admin API) should not be allowed to try and modify the resources, for two reasons: 1. trustee runs in a container so the fs is r/o 2. management of such resources is by design delegated to kubernetes configmaps Therefore add admin_api_ro flags defaulting to false under the [admin] section of kbs-config.toml. Signed-off-by: Emanuele Giuseppe Esposito <[email protected]>
1 parent 761e251 commit aa7aedf

File tree

5 files changed

+27
-2
lines changed

5 files changed

+27
-2
lines changed

kbs/docs/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ The following properties can be set under the `[admin]` section.
207207
|--------------------------|--------------|------------------------------------------------------------------------------------------------------------|----------|----------------------|
208208
| `auth_public_key` | String | Path to the public key used to authenticate the admin APIs | No | None |
209209
| `insecure_api` | Boolean | Whether KBS will not verify the public key when called admin APIs | No | `false` |
210+
| `admin_api_ro` | Boolean | Limit the admin APIs to only get resources. Useful for operator-based deployments | No | `false` |
210211

211212
### Policy Engine Configuration
212213

kbs/src/admin/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::path::PathBuf;
77
use serde::Deserialize;
88

99
pub const DEFAULT_INSECURE_API: bool = false;
10+
pub const DEFAULT_ADMIN_API_RO: bool = false;
1011

1112
#[derive(Clone, Debug, Deserialize, PartialEq)]
1213
pub struct AdminConfig {
@@ -18,13 +19,18 @@ pub struct AdminConfig {
1819
/// WARNING: Using this option enables KBS insecure APIs such as Resource Registration without
1920
/// verifying the JWK.
2021
pub insecure_api: bool,
22+
23+
/// Whether the admin APIs should be read-only or not.
24+
/// Useful for operator-based deployments.
25+
pub admin_api_ro: bool,
2126
}
2227

2328
impl Default for AdminConfig {
2429
fn default() -> Self {
2530
Self {
2631
auth_public_key: None,
2732
insecure_api: DEFAULT_INSECURE_API,
33+
admin_api_ro: DEFAULT_ADMIN_API_RO,
2834
}
2935
}
3036
}

kbs/src/admin/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ pub enum Error {
1919
#[error("`auth_public_key` is not set in the config file")]
2020
NoPublicKeyGiven,
2121

22+
#[error("Admin API is limited to read-only operations (GET)")]
23+
AdminApiReadOnly,
24+
2225
#[error("Failed to parse admin public key")]
2326
ParsePublicKey(#[from] jwt_simple::Error),
2427

kbs/src/admin/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use actix_web::{http::header::Header, HttpRequest};
5+
use actix_web::{http::{header::Header, Method}, HttpRequest};
66
use actix_web_httpauth::headers::authorization::{Authorization, Bearer};
77
use config::AdminConfig;
88
use jwt_simple::{
@@ -19,12 +19,21 @@ use log::warn;
1919
#[derive(Default, Clone)]
2020
pub struct Admin {
2121
public_key: Option<Ed25519PublicKey>,
22+
admin_api_ro: bool,
2223
}
2324

2425
impl TryFrom<AdminConfig> for Admin {
2526
type Error = Error;
2627

2728
fn try_from(value: AdminConfig) -> Result<Self> {
29+
if value.admin_api_ro {
30+
warn!("admin API is disabled");
31+
return Ok(Self {
32+
public_key: None,
33+
admin_api_ro: true,
34+
});
35+
}
36+
2837
if value.insecure_api {
2938
warn!("insecure admin APIs are enabled");
3039
return Ok(Admin::default());
@@ -35,12 +44,17 @@ impl TryFrom<AdminConfig> for Admin {
3544
let key = Ed25519PublicKey::from_pem(&user_public_key_pem)?;
3645
Ok(Self {
3746
public_key: Some(key),
47+
admin_api_ro: false,
3848
})
3949
}
4050
}
4151

4252
impl Admin {
4353
pub(crate) fn validate_auth(&self, request: &HttpRequest) -> Result<()> {
54+
if request.method() == Method::POST && self.admin_api_ro {
55+
return Err(Error::AdminApiReadOnly);
56+
}
57+
4458
let Some(public_key) = &self.public_key else {
4559
return Ok(());
4660
};

kbs/src/config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
// SPDX-License-Identifier: Apache-2.0
44

5-
use crate::admin::config::{AdminConfig, DEFAULT_INSECURE_API};
5+
use crate::admin::config::{AdminConfig, DEFAULT_INSECURE_API, DEFAULT_ADMIN_API_RO};
66
use crate::plugins::PluginsConfig;
77
use crate::policy_engine::PolicyEngineConfig;
88
use crate::token::AttestationTokenVerifierConfig;
@@ -83,6 +83,7 @@ impl TryFrom<&Path> for KbsConfig {
8383
fn try_from(config_path: &Path) -> Result<Self, Self::Error> {
8484
let c = Config::builder()
8585
.set_default("admin.insecure_api", DEFAULT_INSECURE_API)?
86+
.set_default("admin.admin_api_ro", DEFAULT_ADMIN_API_RO)?
8687
.set_default("http_server.insecure_http", DEFAULT_INSECURE_HTTP)?
8788
.set_default("http_server.sockets", vec![DEFAULT_SOCKET])?
8889
.set_default(

0 commit comments

Comments
 (0)