Skip to main content

sekuire_protocol/
lib.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4// --- Sekuire Identity Protocol ---
5
6#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
7pub struct Manifest {
8    pub project: ProjectMetadata,
9    pub identity: IdentityConfig,
10    /// Optional: agent capability declaration for discovery/orchestration.
11    #[serde(default, skip_serializing_if = "Option::is_none")]
12    pub capabilities: Option<AgentCapabilities>,
13    /// Optional: discovery metadata (tags, categories, keywords).
14    #[serde(default, skip_serializing_if = "Option::is_none")]
15    pub discovery: Option<DiscoveryMetadata>,
16    /// Optional: A2A (Agent-to-Agent) runtime settings for managed routing.
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub a2a: Option<A2AConfig>,
19    /// Optional: deployment/install metadata (env vars, container hints, etc).
20    #[serde(default, skip_serializing_if = "Option::is_none")]
21    pub deployment: Option<DeploymentConfig>,
22}
23
24#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
25pub struct ProjectMetadata {
26    pub name: String,
27    pub version: String,
28    pub description: Option<String>,
29    #[serde(default)]
30    pub authors: Vec<String>,
31    pub license: Option<String>,
32}
33
34#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
35pub struct IdentityConfig {
36    /// The model identifier (e.g., "gpt-4-0613")
37    pub model: String,
38
39    /// Path to the system prompt file (relative to sekuire.json)
40    pub system_prompt_path: String,
41
42    /// Path to the tools definition file (relative to sekuire.json)
43    pub tools_path: String,
44
45    /// The Blake3 hash of the system prompt content
46    pub system_prompt_hash: Option<String>,
47
48    /// The Blake3 hash of the tools definition content
49    pub tools_hash: Option<String>,
50}
51
52// --- Agent Discovery / Orchestration (Optional) ---
53
54#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
55pub struct AgentCapabilities {
56    /// Capabilities this agent provides (e.g., "jira:tickets:create").
57    #[serde(default)]
58    pub provides: Vec<String>,
59    /// Capabilities this agent may require to complete its own tasks.
60    #[serde(default)]
61    pub requires: Vec<String>,
62    /// Optional: preferred delegation targets for sub-tasks.
63    #[serde(default)]
64    pub delegates_to: Vec<DelegationTarget>,
65}
66
67#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
68pub struct DelegationTarget {
69    pub agent_type: String,
70    #[serde(default)]
71    pub capabilities: Vec<String>,
72}
73
74#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
75pub struct DiscoveryMetadata {
76    #[serde(default)]
77    pub tags: Vec<String>,
78    #[serde(default)]
79    pub categories: Vec<String>,
80    #[serde(default)]
81    pub search_keywords: Vec<String>,
82}
83
84#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
85pub struct A2AConfig {
86    /// The agent's upstream A2A task endpoint (used by Sekuire-managed routing).
87    /// This should be the base tasks URL, e.g. `http://localhost:8001/a2a/tasks`.
88    pub upstream_url: String,
89    /// Optional: public base URL for direct calls (non-managed environments).
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub public_base_url: Option<String>,
92}
93
94// --- Installation / Deployment Metadata (Optional) ---
95
96#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
97pub struct DeploymentConfig {
98    /// Environment variables required or supported by this agent.
99    #[serde(default)]
100    pub env: Vec<EnvVarSpec>,
101    /// Optional: suggested container image reference for BYO-host deployments.
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub docker_image: Option<String>,
104    /// Optional: runtime notes to display in installation instructions.
105    #[serde(default, skip_serializing_if = "Option::is_none")]
106    pub notes: Option<String>,
107}
108
109#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
110pub struct EnvVarSpec {
111    pub name: String,
112    #[serde(default)]
113    pub required: bool,
114    #[serde(default)]
115    pub secret: bool,
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub description: Option<String>,
118    #[serde(default, skip_serializing_if = "Option::is_none")]
119    pub example: Option<String>,
120    #[serde(default, skip_serializing_if = "Option::is_none")]
121    pub default_value: Option<String>,
122}
123
124// --- Registry API Types ---
125
126#[derive(Debug, Serialize, Deserialize, JsonSchema)]
127pub struct PublishRequest {
128    pub manifest: Manifest,
129    pub sekuire_id: String, // The calculated hash
130    pub signature: String,  // Signed hash
131    pub public_key: String, // The signer's public key
132    // Organization publishing support
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub publisher_org_id: Option<String>, // Organization ID if publishing on behalf of org
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub visibility: Option<String>, // Override default visibility (public, private, internal)
137}
138
139// --- Trust Registry Types ---
140
141#[derive(Debug, Serialize, Deserialize, JsonSchema)]
142pub struct AgentResponse {
143    pub sekuire_id: String,
144    pub public_key: String, // Renamed from author_key to match frontend
145    pub name: String,
146    pub version: String,
147    pub description: Option<String>,
148    pub created_at: String, // ISO8601
149    pub verification_status: VerificationStatus,
150    pub reputation_score: i32, // 0-100
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub manifest: Option<serde_json::Value>, // Full manifest for detailed views
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub updated_at: Option<String>,
155
156    // Publisher information
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub publisher_user_id: Option<String>,
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub publisher_email: Option<String>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub publisher_name: Option<String>,
163
164    // Organization ownership
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub publisher_org_id: Option<String>,
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub publisher_org_name: Option<String>,
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub org_metadata: Option<serde_json::Value>,
171
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub visibility: Option<AgentVisibility>,
174
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub public_url: Option<String>,
177
178    // Repository information
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub git_repository: Option<String>,
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub commit_hash: Option<String>,
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub tag: Option<String>,
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub repository_verified: Option<bool>,
187
188    // Documentation
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub readme_content: Option<String>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub changelog_content: Option<String>,
193
194    // Review process
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub code_review_status: Option<String>,
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub security_score: Option<i32>,
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub reviewed_by: Option<String>,
201    #[serde(skip_serializing_if = "Option::is_none")]
202    pub reviewed_at: Option<String>,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub review_notes: Option<String>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
208#[cfg_attr(feature = "backend", derive(sqlx::Type))]
209#[serde(rename_all = "snake_case")]
210#[cfg_attr(
211    feature = "backend",
212    sqlx(type_name = "verification_status", rename_all = "snake_case")
213)]
214pub enum VerificationStatus {
215    Unverified,
216    Pending,
217    Verified,
218    Suspended,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
222#[cfg_attr(feature = "backend", derive(sqlx::Type))]
223#[serde(rename_all = "snake_case")]
224#[cfg_attr(
225    feature = "backend",
226    sqlx(type_name = "agent_visibility", rename_all = "snake_case")
227)]
228pub enum AgentVisibility {
229    Public,
230    Private,
231    Internal,
232}
233
234#[derive(Debug, Serialize, Deserialize, JsonSchema)]
235pub struct ReputationResponse {
236    pub score: i32,
237    pub task_count: i32,
238    pub verification_badge: Option<String>, // e.g., "HIPAA"
239    pub recent_logs: Vec<ReputationLog>,
240}
241
242#[derive(Debug, Serialize, Deserialize, JsonSchema)]
243pub struct ReputationLog {
244    pub id: String,
245    pub task_hash: String,
246    pub rating: i32, // 1-5
247    pub comment: Option<String>,
248    pub timestamp: String,
249}
250
251#[derive(Debug, Serialize, Deserialize, JsonSchema)]
252pub struct SubmitReputationRequest {
253    pub sekuire_id: String,
254    pub task_hash: String,
255    pub rating: i32,
256    pub comment: Option<String>,
257    pub signature: String, // Employer's signature over the rating
258}
259
260// --- Handshake Protocol ---
261
262#[derive(Debug, Serialize, Deserialize, JsonSchema)]
263pub struct HandshakeHello {
264    pub client_nonce: String, // Random 32-byte hex
265}
266
267#[derive(Debug, Serialize, Deserialize, JsonSchema)]
268pub struct HandshakeWelcome {
269    pub agent_id: String,
270    pub agent_nonce: String,      // Random 32-byte hex
271    pub signature_c: String,      // Sign(client_nonce) by Agent
272    pub credentials: Vec<String>, // List of Signed VCs (JWTs)
273}
274
275#[derive(Debug, Serialize, Deserialize, JsonSchema)]
276pub struct HandshakeAuth {
277    pub signature_a: String, // Sign(agent_nonce) by Client
278}
279
280// --- Categories ---
281
282#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
283pub struct Category {
284    pub id: String,
285    pub name: String,
286    pub slug: String,
287    pub description: Option<String>,
288    pub icon: Option<String>,
289    pub parent_id: Option<String>,
290    pub parent_name: Option<String>,
291    pub is_active: bool,
292    pub display_order: i32,
293}
294
295#[derive(Debug, Serialize, Deserialize, JsonSchema)]
296pub struct AssignCategoryRequest {
297    pub sekuire_id: String,
298    pub category_ids: Vec<String>,           // Category IDs or slugs
299    pub primary_category_id: Option<String>, // Optional primary category
300}
301
302// --- Verification & Disputes ---
303
304#[derive(Debug, Serialize, Deserialize, JsonSchema)]
305pub struct VerifyAgentRequest {
306    pub sekuire_id: String,
307    pub status: VerificationStatus, // Verified, Suspended
308    pub badge: Option<String>,      // e.g. "safe", "hipaa"
309    pub reason: Option<String>,
310}
311
312#[derive(Debug, Serialize, Deserialize, JsonSchema)]
313pub struct DisputeRequest {
314    pub sekuire_id: String,
315    pub accuser_id: String, // Employer ID
316    pub reason: String,
317    pub evidence_log: String, // Signed conversation
318}
319
320// --- Deprecated / Legacy Management API (To be refactored) ---
321
322#[derive(Debug, Serialize, Deserialize, JsonSchema)]
323pub struct CreateOrgRequest {
324    pub slug: String,
325    pub display_name: String,
326    pub billing_email: String,
327}
328
329#[derive(Debug, Serialize, Deserialize, JsonSchema)]
330pub struct OrgResponse {
331    pub id: String,
332    pub slug: String,
333    pub role: String,
334}
335
336#[derive(Debug, Serialize, Deserialize, JsonSchema)]
337pub struct CreateWorkspaceRequest {
338    pub name: String,
339    pub policy_preset: String,
340}
341
342#[derive(Debug, Serialize, Deserialize, JsonSchema)]
343pub struct WorkspaceResponse {
344    pub id: String,
345    pub name: String,
346    #[serde(skip_serializing_if = "Option::is_none")]
347    pub created_at: Option<String>,
348    #[serde(skip_serializing_if = "Option::is_none")]
349    pub updated_at: Option<String>,
350}
351
352#[derive(Debug, Serialize, Deserialize, JsonSchema)]
353pub struct InviteRequest {
354    pub email: String,
355    pub role: String,
356}
357
358#[derive(Debug, Serialize, Deserialize, JsonSchema)]
359pub struct InviteResponse {
360    pub id: String,
361    pub status: String,
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
365pub struct UserContextResponse {
366    pub id: String,
367    pub email: String,
368    pub onboarded: bool,
369    pub mfa_enabled: bool,
370    pub role: Option<String>,
371    pub full_name: Option<String>,
372    pub avatar_url: Option<String>,
373    pub onboarding_step: i32,
374    pub profile_completed: bool,
375    pub orgs: Vec<OrgSummary>,
376    pub workspaces: Vec<WorkspaceSummary>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
380pub struct OrgSummary {
381    pub id: String,
382    pub slug: String,
383    #[serde(default, skip_serializing_if = "Vec::is_empty")]
384    pub workspaces: Vec<WorkspaceSummary>,
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
388pub struct WorkspaceSummary {
389    pub id: String,
390    pub name: String,
391    pub org_id: String,
392}
393
394// Task Completion & Reputation
395#[derive(Debug, Serialize, Deserialize, JsonSchema)]
396pub struct TaskCompletionRequest {
397    pub sekuire_id: String,
398    pub task_hash: String,
399    pub rating: i32, // 1-5 stars
400    pub comment: Option<String>,
401    pub employer_id: String, // Who's rating the agent
402}
403
404#[derive(Debug, Serialize, Deserialize, JsonSchema)]
405pub struct TaskCompletionResponse {
406    pub success: bool,
407    pub new_reputation_score: i32,
408    pub reputation_change: i32,
409}
410
411#[derive(Debug, Serialize, Deserialize, JsonSchema)]
412pub struct LeaderboardEntry {
413    pub rank: i32,
414    pub sekuire_id: String,
415    pub name: String,
416    pub reputation_score: i32,
417    pub task_count: i32,
418    pub success_rate: f64,
419    pub average_rating: f64,
420}
421
422#[derive(Debug, Serialize, Deserialize, JsonSchema)]
423pub struct EnhancedReputationResponse {
424    pub score: i32,
425    pub rank: Option<i32>,
426    pub total_agents: i32,
427    pub task_count: i32,
428    pub success_count: i32,
429    pub dispute_count: i32,
430    pub success_rate: f64,
431    pub average_rating: f64,
432    pub verification_badge: Option<String>,
433    pub recent_logs: Vec<ReputationLog>,
434}
435
436#[derive(Debug, Serialize, Deserialize, JsonSchema)]
437pub struct VerifyAgentResponse {
438    pub verified: bool,
439    pub sekuire_id: String,
440    pub name: String,
441    pub verification_status: VerificationStatus,
442    pub reputation_score: i32,
443    pub badges: Vec<String>, // ["verified", "hipaa", "pci"]
444    pub success_rate: Option<f64>,
445    pub task_count: i32,
446    pub risk_level: String, // "low", "medium", "high"
447}
448
449#[derive(Debug, Serialize, Deserialize, JsonSchema)]
450pub struct BadgeRequest {
451    pub sekuire_id: String,
452    pub badge_type: String, // "hipaa", "pci", "soc2", "verified"
453    pub evidence: Option<String>,
454}
455
456// Quick Verification - Blue Checkmark API
457#[derive(Debug, Serialize, Deserialize, JsonSchema)]
458pub struct QuickVerifyRequest {
459    pub sekuire_id: String,
460    pub requesting_agent: Option<String>,
461}
462
463#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
464pub struct QuickVerifyResponse {
465    pub verified: bool,
466    pub sekuire_id: String,
467    pub name: String,
468    pub verification_status: VerificationStatus,
469    pub reputation_score: i32,
470    pub badges: Vec<String>,
471    pub success_rate: Option<f64>,
472    pub task_count: i32,
473    pub risk_level: String,
474}
475
476#[derive(Debug, Serialize, Deserialize, JsonSchema)]
477pub struct IssueBadgeRequest {
478    pub sekuire_id: String,
479    pub badge_type: String,
480    pub evidence: Option<String>,
481}
482
483// Header Verification
484#[derive(Debug, Serialize, Deserialize, JsonSchema)]
485pub struct VerifyHeadersRequest {
486    pub agent_id: String,
487    pub reputation: i32,
488    pub credentials: Vec<String>,
489}
490
491#[derive(Debug, Serialize, Deserialize, JsonSchema)]
492pub struct VerifyHeadersResponse {
493    pub valid: bool,
494    pub message: String,
495    pub discrepancies: Vec<String>,
496}
497
498// --- Agent Event Logging Types ---
499
500#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
501#[cfg_attr(feature = "backend", derive(sqlx::Type))]
502#[serde(rename_all = "snake_case")]
503#[cfg_attr(
504    feature = "backend",
505    sqlx(type_name = "text", rename_all = "snake_case")
506)]
507pub enum EventType {
508    ToolExecution,
509    ModelCall,
510    PolicyViolation,
511    PolicyCheck,
512    NetworkAccess,
513    FileAccess,
514    Health,
515}
516
517#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
518#[cfg_attr(feature = "backend", derive(sqlx::Type))]
519#[serde(rename_all = "lowercase")]
520#[cfg_attr(
521    feature = "backend",
522    sqlx(type_name = "text", rename_all = "lowercase")
523)]
524pub enum Severity {
525    Debug,
526    Info,
527    Warn,
528    Error,
529}
530
531#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
532pub struct AgentEventLog {
533    pub sekuire_id: String,
534    pub session_id: String,
535    pub workspace_id: Option<String>,
536    pub event_type: EventType,
537    pub severity: Severity,
538    pub event_timestamp: String, // ISO8601
539    pub event_data: serde_json::Value,
540    pub metadata: serde_json::Value,
541}
542
543#[derive(Debug, Serialize, Deserialize, JsonSchema)]
544pub struct LogEventRequest {
545    pub events: Vec<AgentEventLog>,
546}
547
548#[derive(Debug, Serialize, Deserialize, JsonSchema)]
549pub struct LogEventResponse {
550    pub success: bool,
551    pub events_logged: usize,
552    pub errors: Vec<String>,
553}
554
555#[derive(Debug, Serialize, Deserialize, JsonSchema)]
556pub struct AgentHealthRequest {
557    pub sekuire_id: String,
558    pub status: String,
559    pub session_id: String,
560    pub sdk_version: String,
561    pub environment: String,
562    pub metadata: serde_json::Value,
563}
564
565#[derive(Debug, Serialize, Deserialize, JsonSchema)]
566pub struct AgentHealthResponse {
567    pub success: bool,
568    pub message: String,
569}
570
571#[derive(Debug, Serialize, Deserialize, JsonSchema)]
572pub struct GetLogsQuery {
573    pub limit: Option<i64>,
574    pub offset: Option<i64>,
575    pub event_type: Option<EventType>,
576    pub severity: Option<Severity>,
577    pub session_id: Option<String>,
578    pub start_time: Option<String>, // ISO8601
579    pub end_time: Option<String>,   // ISO8601
580}
581
582#[derive(Debug, Serialize, Deserialize, JsonSchema)]
583pub struct GetLogsResponse {
584    pub logs: Vec<AgentEventLogResponse>,
585    pub total: i64,
586    pub limit: i64,
587    pub offset: i64,
588}
589
590#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
591pub struct AgentEventLogResponse {
592    pub id: i64,
593    pub sekuire_id: String,
594    pub session_id: String,
595    pub workspace_id: Option<String>,
596    pub event_type: EventType,
597    pub severity: Severity,
598    pub event_timestamp: String,
599    pub received_at: String,
600    pub event_data: serde_json::Value,
601    pub metadata: serde_json::Value,
602}