clawft
Weftos

Config & Auth Services

ConfigService for typed namespaced configuration and AuthService for SHA-256 credential hashing with scoped tokens.

Two kernel services provide configuration management and authentication for WeftOS agents and system components.

Source: crates/clawft-kernel/src/config_service.rs, auth_service.rs Phase: K5

ConfigService

Typed, namespaced key-value configuration with change notification and secret storage.

Config Values

pub enum ConfigValue {
    Text(String),
    Int(i64),
    Float(f64),
    Bool(bool),
    Json(serde_json::Value),
}

Each value is stored as a ConfigEntry with metadata:

pub struct ConfigEntry {
    pub namespace: String,
    pub key: String,
    pub value: ConfigValue,
    pub updated_at: SystemTime,
    pub version: u64,
}

API

let config = ConfigService::new(encryption_key);

// Typed storage
config.set_typed("mesh", "heartbeat_interval_ms", ConfigValue::Int(5000));
config.get_typed("mesh", "heartbeat_interval_ms") -> Option<ConfigEntry>;
config.list("mesh") -> Vec<ConfigEntry>;
config.delete_typed("mesh", "heartbeat_interval_ms");

// JSON storage (legacy)
config.set("mesh", "peers", json!(["node-a", "node-b"]));
config.get("mesh", "peers") -> Option<Value>;
config.list_keys("mesh") -> Vec<String>;

// Secrets (encrypted at rest)
config.set_secret("api", "openai_key", "sk-...");
config.get_secret("api", "openai_key") -> Option<String>;

// Change notifications
let changes = config.subscribe("mesh");
// Poll changes: changes.read().unwrap()

Change Tracking

Every mutation emits a ConfigChange:

pub struct ConfigChange {
    pub namespace: String,
    pub key: String,
    pub old_value: Option<serde_json::Value>,
    pub new_value: Option<serde_json::Value>,
    pub timestamp: SystemTime,
}

Subscribers receive changes via Arc<RwLock<Vec<ConfigChange>>>.

AuthService

SHA-256 credential hashing with scoped, time-limited tokens. Raw credentials are never stored.

Credential Model

pub enum CredentialType {
    Password,
    ApiKey,
    Certificate,
    Token,
}

pub struct HashedCredential {
    pub hash: String,       // SHA-256 hex
    pub credential_type: CredentialType,
    pub scopes: Vec<String>,
}

Token Issuance

pub struct AuthToken {
    pub token_id: String,
    pub subject: String,
    pub scopes: Vec<String>,
    pub issued_at: SystemTime,
    pub expires_at: SystemTime,
}

Tokens are scoped — each token carries a list of allowed scopes (e.g., ["mesh:read", "config:write"]). Operations check token.scopes before proceeding.

API

let auth = AuthService::new();

// Register credentials (stores SHA-256 hash only)
auth.register("admin", CredentialRequest {
    credential: "secret123",
    credential_type: CredentialType::Password,
    scopes: vec!["admin".into()],
});

// Authenticate → returns token
let token = auth.authenticate("admin", "secret123")?;

// Validate and check scope
auth.validate(&token.token_id)?;
auth.check_scope(&token.token_id, "admin") -> bool;

// Revoke
auth.revoke(&token.token_id);

Security Properties

  • Credentials hashed with SHA-256 before storage (never raw)
  • Tokens include expiry timestamps, checked on every validation
  • Scope-based access control (not role-based)
  • Revocation is immediate (token removed from registry)
  • 10 tests covering hash verification, expiry, scope checking, revocation

On this page