Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/agentkeys-mock-server/src/handlers/auth_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ pub async fn approve_auth_request(
let (child_session_json, child_wallet) = if request_type == "Pair" {
let child_wallet = crate::auth::generate_wallet_address();
let child_token = generate_token();
let ttl = 3600u64;
let ttl: u64 = 2_592_000; // 30 days per wiki/session-token.md policy

// Parse scope from request_details (canonical CBOR contains it)
// For mock: create a session with no scope restriction (full access to child wallet)
Expand Down Expand Up @@ -381,7 +381,7 @@ pub async fn approve_auth_request(

if let Some(wallet) = recovered_wallet {
let child_token = generate_token();
let ttl = 3600u64;
let ttl: u64 = 2_592_000; // 30 days per wiki/session-token.md policy

// Preserve scope from the most recent session for this wallet
let scope_json: Option<String> = db
Expand Down
17 changes: 13 additions & 4 deletions crates/agentkeys-mock-server/src/handlers/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ use crate::{
use agentkeys_types::{AuthToken, Scope};
use ed25519_dalek::SigningKey;

/// Session token TTL in seconds — 30 days.
///
/// Canonical AgentKeys policy per `wiki/session-token.md`: the bearer token
/// (master CLI or agent daemon) is a **30-day credential**. Agent/child
/// sessions share the same TTL as master for v0. Shorter TTLs for agent
/// sessions may be introduced later as a defense-in-depth tweak, but they
/// MUST align with the policy doc before being applied here.
const DEFAULT_SESSION_TTL_SECONDS: u64 = 30 * 24 * 60 * 60;

#[derive(Deserialize)]
pub struct CreateSessionRequest {
pub auth_token: String,
Expand Down Expand Up @@ -57,7 +66,7 @@ pub async fn create_session(
db.execute(
"INSERT INTO sessions (token, wallet_address, parent_token, scope_json, created_at, ttl_seconds, revoked)
VALUES (?1, ?2, NULL, NULL, ?3, ?4, 0)",
params![session_token, wallet_address, now, 86400u64],
params![session_token, wallet_address, now, DEFAULT_SESSION_TTL_SECONDS],
)
.map_err(|e| AppError::internal(e.to_string()))?;
return Ok(Json(CreateSessionResponse { session: session_token, wallet: wallet_address }));
Expand All @@ -81,7 +90,7 @@ pub async fn create_session(
db.execute(
"INSERT INTO sessions (token, wallet_address, parent_token, scope_json, created_at, ttl_seconds, revoked)
VALUES (?1, ?2, NULL, NULL, ?3, ?4, 0)",
params![session_token, wallet_address, now, 86400u64],
params![session_token, wallet_address, now, DEFAULT_SESSION_TTL_SECONDS],
)
.map_err(|e| AppError::internal(e.to_string()))?;

Expand Down Expand Up @@ -144,7 +153,7 @@ pub async fn create_child_session(
db.execute(
"INSERT INTO sessions (token, wallet_address, parent_token, scope_json, created_at, ttl_seconds, revoked)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, 0)",
params![child_token, child_wallet, parent.token, scope_json, now, 3600u64],
params![child_token, child_wallet, parent.token, scope_json, now, DEFAULT_SESSION_TTL_SECONDS],
)
.map_err(|e| AppError::internal(e.to_string()))?;

Expand Down Expand Up @@ -242,7 +251,7 @@ pub async fn recover_session(
db.execute(
"INSERT INTO sessions (token, wallet_address, parent_token, scope_json, created_at, ttl_seconds, revoked)
VALUES (?1, ?2, NULL, ?3, ?4, ?5, 0)",
params![session_token, wallet_address, scope_json, now, 86400u64],
params![session_token, wallet_address, scope_json, now, DEFAULT_SESSION_TTL_SECONDS],
)
.map_err(|e| AppError::internal(e.to_string()))?;

Expand Down
8 changes: 4 additions & 4 deletions crates/agentkeys-mock-server/src/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl CredentialBackend for InProcessBackend {
wallet: wallet.clone(),
scope: None,
created_at: 0,
ttl_seconds: 86400,
ttl_seconds: 2_592_000, // 30 days per wiki/session-token.md policy
};
Ok((session, wallet))
}
Expand Down Expand Up @@ -197,7 +197,7 @@ impl CredentialBackend for InProcessBackend {
wallet: wallet.clone(),
scope: Some(scope),
created_at: 0,
ttl_seconds: 3600,
ttl_seconds: 2_592_000, // 30 days per wiki/session-token.md policy
};
Ok((session, wallet))
}
Expand Down Expand Up @@ -585,7 +585,7 @@ impl CredentialBackend for InProcessBackend {
let session = body["session"].as_object().map(|_| {
let token = body["session"]["token"].as_str().unwrap_or("").to_string();
let wallet = body["session"]["wallet"].as_str().unwrap_or("").to_string();
let ttl = body["session"]["ttl_seconds"].as_u64().unwrap_or(3600);
let ttl = body["session"]["ttl_seconds"].as_u64().unwrap_or(2_592_000);
let created = body["session"]["created_at"].as_u64().unwrap_or(0);
Session {
token,
Expand Down Expand Up @@ -650,7 +650,7 @@ impl CredentialBackend for InProcessBackend {
wallet: wallet.clone(),
scope: None,
created_at: 0,
ttl_seconds: 86400,
ttl_seconds: 2_592_000, // 30 days per wiki/session-token.md policy
};
Ok((session, wallet))
}
Expand Down
6 changes: 3 additions & 3 deletions docs/spec/1-step-analysis.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ AgentKeys' answer is structurally different from 1Password: **we don't hand user

| Tier | Lifetime | Storage (original spec) | Storage (corrected, JWT model) | Usage |
| --------------------- | ---------------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Master auth token** | Short (15 min – 24 h, configurable via `AuthOptions.expires_at`) | OS keychain | Plain file or env var (JWT string, not a private key) | Management commands: `agentkeys init`, `store`, `usage`, `teardown`, `approve`. Never used by running agents. |
| **Master auth token** | 30 days (canonical AgentKeys policy per `wiki/session-token.md`; `AuthOptions.expires_at` can shorten per-session) | OS keychain | Plain file or env var (JWT string, not a private key) | Management commands: `agentkeys init`, `store`, `usage`, `teardown`, `approve`. Never used by running agents. |
| **Agent auth token** | Long (hours to days) | Sandbox filesystem (`~/.agentkeys/session`, 0600) | Same (JWT string in file, 0600) | MCP Credential Server authentication. Scoped to specific credentials for a specific agent. |


Expand Down Expand Up @@ -781,10 +781,10 @@ This section explicitly reconciles any points where earlier rounds of this sub-i
| **Canonical account name (Round 6)** | **x402 wallet address (EVM), minted in Heima TEE on account creation. Same primary key for master and each child.** |
| **Billing model (Round 6)** | **Each account's wallet holds its own USDC. Master funds children. Empty wallet = agent stops. No on-chain spend-limit code needed — the balance IS the limit.** |
| Master session storage | OS keychain (Keychain Services / Credential Manager / libsecret), biometric-gated |
| Master session TTL | Short (15 min - 24 h idle, 1P/Enpass style) |
| Master session TTL | 30 days (canonical AgentKeys policy per `wiki/session-token.md`) |
| **Agent session storage** | **On stock sandbox: `/home/gem/.agentkeys/session`** (mode 0600, owner gem) + memfd_secret runtime pages + seccomp-bpf process restrictions + daemon with Unix socket (ssh-agent model). **On cloud LLM or custom sandbox: `$HOME/.agentkeys/session`** with the same hardening stack. *(Original Round 6 design specified `/var/lib/agentkeys/session` with dedicated UID + LSM + Landlock — see §3.3a for historical reference, §3.3c for what ships.)* |
| **Storage stack order (Round 6)** | **S1 (this Round 6 hardening) → S2 (rolling ratchet) → S3 (provider attestation). S4 and S5 rejected.** |
| Agent session TTL | Long (4 h default, up to 24 h for v0) |
| Agent session TTL | 30 days (same policy as master CLI per `wiki/session-token.md`; may be shortened in a future defense-in-depth tweak) |
| Scope | Each agent session bound to its specific service credentials only |
| Revocation | Instant via master CLI (`agentkeys revoke 0x...`) |
| Recovery | New sandbox runs `agentkeys pair` → master runs `agentkeys approve <pair-code>` (mints new session for same wallet address). *(Original design used `agentkeys attach agent-A` with direct HTTP push — superseded by rendezvous model.)* |
Expand Down
Loading