fortress-api-server 1.0.0

REST API server for Fortress secure database system
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
//! GraphQL type definitions
//!
//! Contains all GraphQL types, enums, and scalars used in the Fortress GraphQL API.

use async_graphql::{SimpleObject, InputObject, Enum};
use chrono::{DateTime, Utc};
use std::collections::HashMap;
use serde::{Serialize, Deserialize};

// ==================== Enums ====================

/// Database status
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum DatabaseStatus {
    /// Database is active and ready
    Active,
    /// Database is being created
    Creating,
    /// Database is being deleted
    Deleting,
    /// Database is in maintenance mode
    Maintenance,
    /// Database is archived
    Archived,
}

/// Encryption algorithm
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum EncryptionAlgorithm {
    /// AEGIS-256 (recommended)
    Aegis256,
    /// ChaCha20-Poly1305
    ChaCha20Poly1305,
    /// AES-256-GCM
    Aes256Gcm,
    /// RSA-2048
    Rsa2048,
    /// RSA-4096
    Rsa4096,
    /// ECDSA-P256
    EcdsaP256,
    /// ECDSA-P384
    EcdsaP384,
}

/// Field type
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum FieldType {
    /// Text field
    Text,
    /// Integer field
    Integer,
    /// Float field
    Float,
    /// Boolean field
    Boolean,
    /// Date/time field
    DateTime,
    /// UUID field
    Uuid,
    /// JSON field
    Json,
    /// Binary field
    Binary,
    /// Encrypted field
    Encrypted,
}

/// Sort order
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum SortOrder {
    /// Ascending order
    Asc,
    /// Descending order
    Desc,
}

/// Query operator
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum QueryOperator {
    /// Equals
    Eq,
    /// Not equals
    Ne,
    /// Greater than
    Gt,
    /// Greater than or equal
    Gte,
    /// Less than
    Lt,
    /// Less than or equal
    Lte,
    /// Like (pattern matching)
    Like,
    /// In list
    In,
    /// Not in list
    NotIn,
    /// Is null
    IsNull,
    /// Is not null
    IsNotNull,
}

// ==================== Input Objects ====================

/// Input for creating a database
#[derive(InputObject)]
pub struct CreateDatabaseInput {
    /// Database name
    pub name: String,
    /// Description
    pub description: Option<String>,
    /// Default encryption algorithm
    pub encryption_algorithm: Option<EncryptionAlgorithm>,
    /// Tags
    pub tags: Option<Vec<String>>,
}

/// Input for creating a table
#[derive(InputObject)]
pub struct CreateTableInput {
    /// Table name
    pub name: String,
    /// Database name
    pub database: String,
    /// Table fields
    pub fields: Vec<CreateFieldInput>,
    /// Primary key fields
    pub primary_key: Vec<String>,
    /// Table description
    pub description: Option<String>,
}

/// Input for creating a field
#[derive(async_graphql::InputObject, Clone, Debug)]
pub struct CreateFieldInput {
    /// Field name
    pub name: String,
    /// Field type
    pub field_type: FieldType,
    /// Whether the field is required
    pub required: bool,
    /// Whether the field is encrypted
    pub encrypted: bool,
    /// Default value (if any)
    pub default_value: Option<String>,
    /// Field description
    pub description: Option<String>,
    /// Encryption algorithm for encrypted fields
    pub encryption_algorithm: Option<EncryptionAlgorithm>,
}

/// Input for inserting data
#[derive(InputObject)]
pub struct InsertDataInput {
    /// Database name
    pub database: String,
    /// Table name
    pub table: String,
    /// Data to insert
    pub data: async_graphql::Json<serde_json::Value>,
}

/// Input for updating data
#[derive(InputObject)]
pub struct UpdateDataInput {
    /// Database name
    pub database: String,
    /// Table name
    pub table: String,
    /// Record ID
    pub id: String,
    /// Data to update
    pub data: async_graphql::Json<serde_json::Value>,
}

/// Input for querying table data
#[derive(InputObject)]
pub struct TableQueryInput {
    /// Database name
    pub database: String,
    /// Table name
    pub table: String,
    /// Filter conditions
    pub filter: Option<Vec<FilterConditionInput>>,
    /// Sort conditions
    pub sort: Option<Vec<SortConditionInput>>,
    /// Pagination
    pub pagination: Option<PaginationInput>,
}

/// Input for querying data
#[derive(InputObject)]
pub struct QueryDataInput {
    /// Database name
    pub database: String,
    /// Table name
    pub table: String,
    /// Filter conditions
    pub filter: Option<Vec<FilterConditionInput>>,
    /// Sort conditions
    pub sort: Option<Vec<SortConditionInput>>,
    /// Pagination
    pub pagination: Option<PaginationInput>,
}

/// Input for filter conditions
#[derive(InputObject)]
pub struct FilterConditionInput {
    /// Field name
    pub field: String,
    /// Operator
    pub operator: QueryOperator,
    /// Value (for comparison operators)
    pub value: Option<async_graphql::Json<serde_json::Value>>,
    /// Values (for IN/NOT IN operators)
    pub values: Option<Vec<async_graphql::Json<serde_json::Value>>>,
}

/// Input for sort conditions
#[derive(InputObject)]
pub struct SortConditionInput {
    /// Field name
    pub field: String,
    /// Sort order
    pub order: SortOrder,
}

/// Input for pagination
#[derive(InputObject)]
pub struct PaginationInput {
    /// Page number (0-based)
    pub page: Option<i32>,
    /// Page size
    pub page_size: Option<i32>,
    /// Offset (alternative to page)
    pub offset: Option<i32>,
    /// Limit (alternative to page_size)
    pub limit: Option<i32>,
}

/// Input for key rotation
#[derive(InputObject)]
pub struct RotateKeysInput {
    /// Database name
    pub database: String,
    /// Table name
    pub table: String,
    /// New encryption algorithm
    pub algorithm: Option<EncryptionAlgorithm>,
    /// Whether to perform zero-downtime rotation
    pub zero_downtime: Option<bool>,
}

// ==================== Output Objects ====================

/// Database information
#[derive(SimpleObject, Clone, Debug)]
pub struct Database {
    /// Database ID
    pub id: String,
    /// Database name
    pub name: String,
    /// Description
    pub description: Option<String>,
    /// Status
    pub status: DatabaseStatus,
    /// Default encryption algorithm
    pub encryption_algorithm: EncryptionAlgorithm,
    /// Creation timestamp
    pub created_at: DateTime<Utc>,
    /// Last updated timestamp
    pub updated_at: DateTime<Utc>,
    /// Tags
    pub tags: Vec<String>,
    /// Number of tables
    pub table_count: i32,
    /// Storage size in bytes
    pub storage_size_bytes: i64,
}

/// Table information
#[derive(SimpleObject, Clone, Debug)]
pub struct Table {
    /// Table ID
    pub id: String,
    /// Table name
    pub name: String,
    /// Database name
    pub database: String,
    /// Description
    pub description: Option<String>,
    /// Table fields
    pub fields: Vec<Field>,
    /// Primary key fields
    pub primary_key: Vec<String>,
    /// Creation timestamp
    pub created_at: DateTime<Utc>,
    /// Last updated timestamp
    pub updated_at: DateTime<Utc>,
    /// Number of records
    pub record_count: i32,
    /// Whether encryption is enabled
    pub encryption_enabled: bool,
}

/// Field information
#[derive(SimpleObject, Clone, Debug)]
pub struct Field {
    /// Field name
    pub name: String,
    /// Field type
    pub field_type: FieldType,
    /// Whether the field is required
    pub required: bool,
    /// Description
    pub description: Option<String>,
    /// Default value
    pub default_value: Option<String>,
    /// Encryption algorithm (if encrypted)
    pub encryption_algorithm: Option<EncryptionAlgorithm>,
    /// Whether the field is encrypted
    pub encrypted: bool,
}

/// Data record
#[derive(SimpleObject, Clone, Debug, Serialize, Deserialize)]
pub struct DataRecord {
    /// Record ID
    pub id: String,
    /// Field data
    pub data: async_graphql::Json<serde_json::Value>,
    /// Creation timestamp
    pub created_at: DateTime<Utc>,
    /// Last updated timestamp
    pub updated_at: DateTime<Utc>,
    /// Encryption metadata for encrypted fields
    pub encryption_metadata: Option<async_graphql::Json<serde_json::Value>>,
}

/// Query result
#[derive(SimpleObject, Clone, Debug, Serialize, Deserialize)]
pub struct QueryResult {
    /// Records returned
    pub records: Vec<DataRecord>,
    /// Total number of records matching the query
    pub total_count: i32,
    /// Whether there are more records
    pub has_more: bool,
    /// Pagination information
    pub pagination: Option<PaginationInfo>,
}

/// Pagination information
#[derive(SimpleObject, Clone, Debug, Serialize, Deserialize)]
pub struct PaginationInfo {
    /// Current page number
    pub page: i32,
    /// Page size
    pub page_size: i32,
    /// Total number of pages
    pub total_pages: i32,
    /// Total number of records
    pub total_records: i32,
    /// Has next page
    pub has_next: bool,
    /// Has previous page
    pub has_previous: bool,
}

/// Key rotation status
#[derive(SimpleObject, Clone, Debug)]
pub struct KeyRotationStatus {
    /// Rotation ID
    pub id: String,
    /// Status
    pub status: String,
    /// Progress percentage
    pub progress_percentage: f64,
    /// Started at
    pub started_at: Option<DateTime<Utc>>,
    /// Completed at
    pub completed_at: Option<DateTime<Utc>>,
    /// Error message (if any)
    pub error_message: Option<String>,
    /// Records processed
    pub records_processed: i32,
    /// Total records to process
    pub total_records: i32,
}

/// Encryption metadata
#[derive(SimpleObject, Clone, Debug)]
pub struct EncryptionMetadata {
    /// Field name
    pub field_name: String,
    /// Encryption algorithm
    pub algorithm: EncryptionAlgorithm,
    /// Key ID
    pub key_id: String,
    /// Key version
    pub key_version: i32,
    /// Encryption timestamp
    pub encrypted_at: DateTime<Utc>,
}

/// API response wrapper
#[derive(SimpleObject, Clone, Debug)]
pub struct ApiResponse<T: async_graphql::OutputType + Send + Sync> {
    /// Whether the operation was successful
    pub success: bool,
    /// Response data (if successful)
    pub data: Option<T>,
    /// Error message (if failed)
    pub error_message: Option<String>,
    /// Error code (if any)
    pub error_code: Option<String>,
}

/// Health status
#[derive(SimpleObject, Clone, Debug)]
pub struct HealthStatus {
    /// Overall health
    pub healthy: bool,
    /// Service status
    pub services: HashMap<String, ServiceHealth>,
    /// Last check timestamp
    pub last_check: DateTime<Utc>,
}

/// Individual service health
#[derive(SimpleObject, Clone, Debug, serde::Serialize)]
pub struct ServiceHealth {
    /// Service name
    pub name: String,
    /// Whether the service is healthy
    pub healthy: bool,
    /// Response time in milliseconds
    pub response_time_ms: i32,
    /// Additional details
    pub details: HashMap<String, String>,
}

// ==================== Dynamic Secrets Types ====================

/// Database type for dynamic credentials
#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq)]
pub enum DynamicDatabaseType {
    /// PostgreSQL
    Postgresql,
    /// MySQL
    Mysql,
    /// SQL Server
    Sqlserver,
}

/// AWS IAM credential response
#[derive(SimpleObject, Clone, Debug)]
pub struct AwsCredential {
    /// Access key ID
    pub access_key_id: String,
    /// Secret access key (masked)
    pub secret_access_key: String,
    /// Session token (if any)
    pub session_token: Option<String>,
    /// Expiration time
    pub expires_at: DateTime<Utc>,
    /// IAM policy applied
    pub policy: serde_json::Value,
    /// Role assumed (if any)
    pub role: Option<String>,
    /// Lease ID for renewal/revocation
    pub lease_id: String,
    /// Time to live in seconds
    pub ttl: u64,
}

/// Database credential response
#[derive(SimpleObject, Clone, Debug)]
pub struct DatabaseCredential {
    /// Generated username
    pub username: String,
    /// Generated password (masked)
    pub password: String,
    /// Database type
    pub database_type: DynamicDatabaseType,
    /// Database name
    pub database: String,
    /// Connection string (password masked)
    pub connection_string: String,
    /// Granted permissions
    pub permissions: Vec<String>,
    /// Expiration time
    pub expires_at: DateTime<Utc>,
    /// Lease ID for renewal/revocation
    pub lease_id: String,
    /// Time to live in seconds
    pub ttl: u64,
    /// Database-specific metadata
    pub metadata: HashMap<String, String>,
}

/// Input for generating AWS IAM credentials
#[derive(InputObject)]
pub struct GenerateAwsCredentialInput {
    /// Path for the credential
    pub path: String,
    /// IAM policy document
    pub policy: serde_json::Value,
    /// Role to assume (optional)
    pub role: Option<String>,
    /// Time to live in seconds
    pub ttl: Option<u64>,
}

/// Input for generating database credentials
#[derive(InputObject)]
pub struct GenerateDatabaseCredentialInput {
    /// Path for the credential
    pub path: String,
    /// Database type
    pub database_type: DynamicDatabaseType,
    /// Database connection URL (admin)
    pub database_url: String,
    /// Permissions to grant
    pub permissions: Vec<String>,
    /// Time to live in seconds
    pub ttl: Option<u64>,
}

/// Input for configuring AWS integration
#[derive(InputObject)]
pub struct ConfigureAwsInput {
    /// AWS access key ID
    pub access_key_id: String,
    /// AWS secret access key
    pub secret_access_key: String,
    /// AWS region
    pub region: Option<String>,
    /// Default IAM role
    pub default_role: Option<String>,
}

/// Input for renewing a credential lease
#[derive(InputObject)]
pub struct RenewLeaseInput {
    /// Lease ID to renew
    pub lease_id: String,
    /// TTL increment in seconds
    pub increment: Option<u64>,
}

/// Dynamic secrets engine status
#[derive(SimpleObject, Clone, Debug)]
pub struct DynamicSecretsStatus {
    /// Engine name
    pub name: String,
    /// Whether the engine is initialized
    pub initialized: bool,
    /// Total active secrets
    pub total_secrets: u64,
    /// Active leases
    pub active_leases: u64,
    /// AWS configuration status
    pub aws_configured: bool,
    /// Supported database types
    pub supported_databases: Vec<DynamicDatabaseType>,
    /// Default TTL
    pub default_ttl: u64,
    /// Maximum TTL
    pub max_ttl: u64,
    /// Auto cleanup enabled
    pub auto_cleanup: bool,
}

/// Secret data response
#[derive(SimpleObject, Clone, Debug)]
pub struct SecretData {
    /// Secret data
    pub data: serde_json::Value,
    /// Creation timestamp
    pub created_at: DateTime<Utc>,
    /// Last update timestamp
    pub updated_at: Option<DateTime<Utc>>,
    /// Secret version
    pub version: i32,
    /// Lease information (if applicable)
    pub lease: Option<LeaseInfo>,
}

/// Lease information
#[derive(SimpleObject, Clone, Debug)]
pub struct LeaseInfo {
    /// Lease ID
    pub lease_id: String,
    /// Time to live in seconds
    pub ttl: u64,
    /// Creation timestamp
    pub created_at: DateTime<Utc>,
    /// Whether the lease is renewable
    pub renewable: bool,
    /// Maximum TTL
    pub max_ttl: Option<u64>,
}