@1claw/openapi-spec 0.32.1 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +1 -1
  2. package/openapi.json +2722 -1183
  3. package/openapi.yaml +968 -1
  4. package/package.json +1 -1
package/openapi.yaml CHANGED
@@ -70,6 +70,10 @@ tags:
70
70
  description: Event webhook registration and management
71
71
  - name: Platform
72
72
  description: Platform API for developers building on 1Claw (plt_ keys, user provisioning, bootstrap templates)
73
+ - name: OAuth
74
+ description: OAuth 2.0 authorization server (PKCE, consent, token exchange, OIDC UserInfo)
75
+ - name: Risk Engine
76
+ description: Risk events, verdicts, and honeytoken management
73
77
 
74
78
  # =============================================================================
75
79
  # PATHS
@@ -2804,6 +2808,48 @@ paths:
2804
2808
  "404":
2805
2809
  description: Agent-keys vault not found
2806
2810
 
2811
+ /v1/org/bankr-config:
2812
+ get:
2813
+ tags: [Organization]
2814
+ summary: Get org Bankr partner configuration
2815
+ description: Returns whether the org has configured Bankr BYOK (partner key prefix and default wallet only — never the secret). Users only.
2816
+ operationId: getOrgBankrConfig
2817
+ responses:
2818
+ "200":
2819
+ description: Bankr configuration status
2820
+ content:
2821
+ application/json:
2822
+ schema:
2823
+ $ref: "#/components/schemas/OrgBankrConfigResponse"
2824
+ put:
2825
+ tags: [Organization]
2826
+ summary: Set org Bankr partner configuration
2827
+ description: Store or replace the org's Bankr partner key (`bk_ptr_...`) and optional default wallet (`wlt_...`). Owner/admin only. Partner key encrypted at rest.
2828
+ operationId: upsertOrgBankrConfig
2829
+ requestBody:
2830
+ required: true
2831
+ content:
2832
+ application/json:
2833
+ schema:
2834
+ $ref: "#/components/schemas/UpsertOrgBankrConfigRequest"
2835
+ responses:
2836
+ "200":
2837
+ description: Configuration saved
2838
+ content:
2839
+ application/json:
2840
+ schema:
2841
+ $ref: "#/components/schemas/OrgBankrConfigResponse"
2842
+ delete:
2843
+ tags: [Organization]
2844
+ summary: Remove org Bankr partner configuration
2845
+ description: Delete BYOK credentials for the org. Owner/admin only.
2846
+ operationId: deleteOrgBankrConfig
2847
+ responses:
2848
+ "204":
2849
+ description: Configuration removed
2850
+ "404":
2851
+ description: Configuration not found
2852
+
2807
2853
  /v1/org/invite:
2808
2854
  post:
2809
2855
  tags: [Organization]
@@ -3984,6 +4030,32 @@ paths:
3984
4030
  "404":
3985
4031
  $ref: "#/components/responses/NotFound"
3986
4032
 
4033
+ /v1/treasury/wallets/spend-policy:
4034
+ get:
4035
+ tags: [Treasury Wallets]
4036
+ summary: Get effective spend policy for current user
4037
+ description: |
4038
+ Returns the effective spend policy governing the authenticated user's
4039
+ wallet transactions. Resolves from per-user override (if set) or the
4040
+ app-wide default. Returns null if no policy is configured.
4041
+ operationId: getEffectiveSpendPolicy
4042
+ security:
4043
+ - BearerAuth: []
4044
+ responses:
4045
+ "200":
4046
+ description: Effective spend policy
4047
+ content:
4048
+ application/json:
4049
+ schema:
4050
+ type: object
4051
+ properties:
4052
+ policy:
4053
+ nullable: true
4054
+ allOf:
4055
+ - $ref: "#/components/schemas/SpendPolicyResponse"
4056
+ "401":
4057
+ $ref: "#/components/responses/Unauthorized"
4058
+
3987
4059
  # ---------------------------------------------------------------------------
3988
4060
  # Webhooks
3989
4061
  # ---------------------------------------------------------------------------
@@ -4929,6 +5001,132 @@ paths:
4929
5001
  "410":
4930
5002
  description: Claim token has expired
4931
5003
 
5004
+ # --- Spend Policies ---
5005
+
5006
+ /v1/platform/apps/{appId}/spend-policies:
5007
+ post:
5008
+ tags: [Platform]
5009
+ summary: Create wallet spend policy
5010
+ description: |
5011
+ Create an app-wide spend policy that governs what embedded wallet users
5012
+ can do with their wallets. Policies apply to all connected users by default
5013
+ and can be overridden per-user via connection-level policies.
5014
+ operationId: createSpendPolicy
5015
+ security:
5016
+ - BearerAuth: []
5017
+ parameters:
5018
+ - in: path
5019
+ name: appId
5020
+ required: true
5021
+ schema:
5022
+ type: string
5023
+ format: uuid
5024
+ requestBody:
5025
+ required: true
5026
+ content:
5027
+ application/json:
5028
+ schema:
5029
+ $ref: "#/components/schemas/CreateSpendPolicyRequest"
5030
+ responses:
5031
+ "201":
5032
+ description: Spend policy created
5033
+ content:
5034
+ application/json:
5035
+ schema:
5036
+ $ref: "#/components/schemas/SpendPolicyResponse"
5037
+ "400":
5038
+ $ref: "#/components/responses/BadRequest"
5039
+ "403":
5040
+ $ref: "#/components/responses/Forbidden"
5041
+ get:
5042
+ tags: [Platform]
5043
+ summary: List spend policies for app
5044
+ description: Returns all spend policies configured for the platform app.
5045
+ operationId: listSpendPolicies
5046
+ security:
5047
+ - BearerAuth: []
5048
+ parameters:
5049
+ - in: path
5050
+ name: appId
5051
+ required: true
5052
+ schema:
5053
+ type: string
5054
+ format: uuid
5055
+ responses:
5056
+ "200":
5057
+ description: Spend policies
5058
+ content:
5059
+ application/json:
5060
+ schema:
5061
+ type: object
5062
+ properties:
5063
+ policies:
5064
+ type: array
5065
+ items:
5066
+ $ref: "#/components/schemas/SpendPolicyResponse"
5067
+
5068
+ /v1/platform/apps/{appId}/spend-policies/{policyId}:
5069
+ delete:
5070
+ tags: [Platform]
5071
+ summary: Delete a spend policy
5072
+ operationId: deleteSpendPolicy
5073
+ security:
5074
+ - BearerAuth: []
5075
+ parameters:
5076
+ - in: path
5077
+ name: appId
5078
+ required: true
5079
+ schema:
5080
+ type: string
5081
+ format: uuid
5082
+ - in: path
5083
+ name: policyId
5084
+ required: true
5085
+ schema:
5086
+ type: string
5087
+ format: uuid
5088
+ responses:
5089
+ "204":
5090
+ description: Deleted
5091
+ "404":
5092
+ $ref: "#/components/responses/NotFound"
5093
+
5094
+ /v1/platform/connections/{connectionId}/spend-policy:
5095
+ put:
5096
+ tags: [Platform]
5097
+ summary: Set per-user spend policy override
5098
+ description: |
5099
+ Override the app-wide spend policy for a specific connected user. This
5100
+ policy takes precedence over the app default. Remove by deleting the
5101
+ connection-level policy.
5102
+ operationId: setUserSpendPolicy
5103
+ security:
5104
+ - BearerAuth: []
5105
+ parameters:
5106
+ - in: path
5107
+ name: connectionId
5108
+ required: true
5109
+ schema:
5110
+ type: string
5111
+ format: uuid
5112
+ requestBody:
5113
+ required: true
5114
+ content:
5115
+ application/json:
5116
+ schema:
5117
+ $ref: "#/components/schemas/CreateSpendPolicyRequest"
5118
+ responses:
5119
+ "200":
5120
+ description: Spend policy set
5121
+ content:
5122
+ application/json:
5123
+ schema:
5124
+ $ref: "#/components/schemas/SpendPolicyResponse"
5125
+ "400":
5126
+ $ref: "#/components/responses/BadRequest"
5127
+ "403":
5128
+ $ref: "#/components/responses/Forbidden"
5129
+
4932
5130
  # --- Approvals ---
4933
5131
 
4934
5132
  /v1/approvals:
@@ -5281,7 +5479,419 @@ paths:
5281
5479
  - BearerAuth: []
5282
5480
  responses:
5283
5481
  "200":
5284
- description: Passkey token for X-Passkey-Token header
5482
+ description: Passkey token for X-Passkey-Token header
5483
+
5484
+ # ---------------------------------------------------------------------------
5485
+ # Email OTP
5486
+ # ---------------------------------------------------------------------------
5487
+
5488
+ /v1/auth/email-otp/send:
5489
+ post:
5490
+ tags: [Authentication]
5491
+ summary: Send email OTP code
5492
+ description: |
5493
+ Sends a 6-digit one-time code to the specified email address.
5494
+ No authentication required. Rate-limited per IP and per email.
5495
+ operationId: sendEmailOtp
5496
+ security: []
5497
+ requestBody:
5498
+ required: true
5499
+ content:
5500
+ application/json:
5501
+ schema:
5502
+ type: object
5503
+ required: [email]
5504
+ properties:
5505
+ email:
5506
+ type: string
5507
+ format: email
5508
+ platform_app_id:
5509
+ type: string
5510
+ format: uuid
5511
+ description: Optional platform app context for embedded wallet flows
5512
+ responses:
5513
+ "200":
5514
+ description: OTP sent
5515
+ content:
5516
+ application/json:
5517
+ schema:
5518
+ type: object
5519
+ properties:
5520
+ status:
5521
+ type: string
5522
+ enum: [sent]
5523
+ "429":
5524
+ description: Rate limited
5525
+
5526
+ /v1/auth/email-otp/verify:
5527
+ post:
5528
+ tags: [Authentication]
5529
+ summary: Verify email OTP and get JWT
5530
+ description: |
5531
+ Verifies the 6-digit code sent to the user's email. If the user does not
5532
+ exist, a new account is created. Optionally auto-provisions treasury wallets
5533
+ for the specified chains. Returns a JWT for subsequent API calls.
5534
+ operationId: verifyEmailOtp
5535
+ security: []
5536
+ requestBody:
5537
+ required: true
5538
+ content:
5539
+ application/json:
5540
+ schema:
5541
+ type: object
5542
+ required: [email, code]
5543
+ properties:
5544
+ email:
5545
+ type: string
5546
+ format: email
5547
+ code:
5548
+ type: string
5549
+ description: 6-digit OTP code
5550
+ platform_app_id:
5551
+ type: string
5552
+ format: uuid
5553
+ auto_provision_chains:
5554
+ type: array
5555
+ items: { type: string }
5556
+ description: Chains to auto-generate wallets for (e.g. ["ethereum", "base"])
5557
+ responses:
5558
+ "200":
5559
+ description: Existing user authenticated
5560
+ content:
5561
+ application/json:
5562
+ schema:
5563
+ $ref: "#/components/schemas/EmailOtpVerifyResponse"
5564
+ "201":
5565
+ description: New user created and authenticated
5566
+ content:
5567
+ application/json:
5568
+ schema:
5569
+ $ref: "#/components/schemas/EmailOtpVerifyResponse"
5570
+ "400":
5571
+ description: Invalid or expired code
5572
+ "429":
5573
+ description: Rate limited
5574
+
5575
+ # ---------------------------------------------------------------------------
5576
+ # OAuth
5577
+ # ---------------------------------------------------------------------------
5578
+
5579
+ /v1/oauth/authorize:
5580
+ get:
5581
+ tags: [OAuth]
5582
+ summary: Get OAuth consent info
5583
+ description: |
5584
+ Returns information about the platform app requesting authorization so the
5585
+ UI can display a consent screen. Used by the 1Claw-hosted consent page.
5586
+ operationId: getOAuthConsent
5587
+ security:
5588
+ - BearerAuth: []
5589
+ parameters:
5590
+ - name: client_id
5591
+ in: query
5592
+ required: true
5593
+ schema: { type: string }
5594
+ description: Platform app slug
5595
+ - name: redirect_uri
5596
+ in: query
5597
+ required: true
5598
+ schema: { type: string, format: uri }
5599
+ - name: response_type
5600
+ in: query
5601
+ required: true
5602
+ schema: { type: string, enum: [code] }
5603
+ - name: scope
5604
+ in: query
5605
+ schema: { type: string }
5606
+ description: Space-delimited scopes (e.g. "openid email wallet")
5607
+ - name: state
5608
+ in: query
5609
+ schema: { type: string }
5610
+ - name: code_challenge
5611
+ in: query
5612
+ schema: { type: string }
5613
+ description: PKCE code challenge
5614
+ - name: code_challenge_method
5615
+ in: query
5616
+ schema: { type: string, enum: [S256, plain] }
5617
+ - name: nonce
5618
+ in: query
5619
+ schema: { type: string }
5620
+ description: OIDC nonce for ID token replay protection
5621
+ responses:
5622
+ "200":
5623
+ description: Consent screen data
5624
+ content:
5625
+ application/json:
5626
+ schema:
5627
+ $ref: "#/components/schemas/OAuthConsentResponse"
5628
+ "400":
5629
+ description: Invalid client_id, redirect_uri, or response_type
5630
+ post:
5631
+ tags: [OAuth]
5632
+ summary: Submit OAuth consent decision
5633
+ description: |
5634
+ The user approves or denies the authorization request. On approval, returns
5635
+ a redirect URL containing the authorization code. On denial, returns a
5636
+ redirect URL with an error parameter.
5637
+ operationId: submitOAuthConsent
5638
+ security:
5639
+ - BearerAuth: []
5640
+ requestBody:
5641
+ required: true
5642
+ content:
5643
+ application/json:
5644
+ schema:
5645
+ type: object
5646
+ required: [approve, client_id, redirect_uri]
5647
+ properties:
5648
+ approve: { type: boolean }
5649
+ client_id: { type: string }
5650
+ redirect_uri: { type: string, format: uri }
5651
+ scope: { type: string }
5652
+ state: { type: string }
5653
+ code_challenge: { type: string }
5654
+ code_challenge_method: { type: string, enum: [S256, plain] }
5655
+ nonce: { type: string }
5656
+ responses:
5657
+ "200":
5658
+ description: Redirect URL with authorization code or error
5659
+ content:
5660
+ application/json:
5661
+ schema:
5662
+ type: object
5663
+ required: [redirect_url]
5664
+ properties:
5665
+ redirect_url:
5666
+ type: string
5667
+ format: uri
5668
+ "400":
5669
+ description: Invalid request
5670
+
5671
+ /v1/oauth/token:
5672
+ post:
5673
+ tags: [OAuth]
5674
+ summary: Exchange authorization code for tokens
5675
+ description: |
5676
+ Standard OAuth 2.0 token endpoint. Exchanges an authorization code for an
5677
+ access token and optional OIDC ID token. Supports PKCE via `code_verifier`.
5678
+ operationId: exchangeOAuthToken
5679
+ security: []
5680
+ requestBody:
5681
+ required: true
5682
+ content:
5683
+ application/json:
5684
+ schema:
5685
+ type: object
5686
+ required: [grant_type, code, client_id, redirect_uri]
5687
+ properties:
5688
+ grant_type:
5689
+ type: string
5690
+ enum: [authorization_code]
5691
+ code: { type: string }
5692
+ client_id: { type: string }
5693
+ redirect_uri: { type: string, format: uri }
5694
+ code_verifier:
5695
+ type: string
5696
+ description: PKCE code verifier (required when code_challenge was used)
5697
+ responses:
5698
+ "200":
5699
+ description: Token response
5700
+ content:
5701
+ application/json:
5702
+ schema:
5703
+ $ref: "#/components/schemas/OAuthTokenResponse"
5704
+ "400":
5705
+ description: Invalid grant, code, or verifier
5706
+ "401":
5707
+ description: Invalid client credentials
5708
+
5709
+ /v1/oauth/userinfo:
5710
+ get:
5711
+ tags: [OAuth]
5712
+ summary: Get authenticated user info (OIDC UserInfo)
5713
+ description: |
5714
+ Standard OIDC UserInfo endpoint. Returns claims about the authenticated user
5715
+ based on the granted scopes.
5716
+ operationId: getOAuthUserInfo
5717
+ security:
5718
+ - BearerAuth: []
5719
+ responses:
5720
+ "200":
5721
+ description: User info
5722
+ content:
5723
+ application/json:
5724
+ schema:
5725
+ $ref: "#/components/schemas/OAuthUserInfoResponse"
5726
+ "401":
5727
+ $ref: "#/components/responses/Unauthorized"
5728
+
5729
+ # ---------------------------------------------------------------------------
5730
+ # Risk Engine
5731
+ # ---------------------------------------------------------------------------
5732
+
5733
+ /v1/risk/events:
5734
+ get:
5735
+ tags: [Risk Engine]
5736
+ summary: List risk events
5737
+ description: |
5738
+ Returns risk events detected by the risk engine, ordered by most recent first.
5739
+ Filter by severity or principal type.
5740
+ operationId: listRiskEvents
5741
+ parameters:
5742
+ - name: severity
5743
+ in: query
5744
+ schema:
5745
+ type: string
5746
+ enum: [low, medium, high, critical]
5747
+ description: Filter events by severity level
5748
+ - name: principal_type
5749
+ in: query
5750
+ schema:
5751
+ type: string
5752
+ enum: [user, agent]
5753
+ description: Filter events by principal type
5754
+ - name: limit
5755
+ in: query
5756
+ schema:
5757
+ type: integer
5758
+ default: 50
5759
+ - name: offset
5760
+ in: query
5761
+ schema:
5762
+ type: integer
5763
+ default: 0
5764
+ responses:
5765
+ "200":
5766
+ description: Risk event list
5767
+ content:
5768
+ application/json:
5769
+ schema:
5770
+ $ref: "#/components/schemas/RiskEventListResponse"
5771
+ "401":
5772
+ $ref: "#/components/responses/Unauthorized"
5773
+
5774
+ /v1/risk/verdicts:
5775
+ get:
5776
+ tags: [Risk Engine]
5777
+ summary: List risk verdicts
5778
+ description: Returns all active risk verdicts for the caller's organization.
5779
+ operationId: listRiskVerdicts
5780
+ responses:
5781
+ "200":
5782
+ description: Verdict list
5783
+ content:
5784
+ application/json:
5785
+ schema:
5786
+ $ref: "#/components/schemas/RiskVerdictListResponse"
5787
+ "401":
5788
+ $ref: "#/components/responses/Unauthorized"
5789
+
5790
+ /v1/risk/verdicts/{principal_type}/{principal_id}:
5791
+ get:
5792
+ tags: [Risk Engine]
5793
+ summary: Get risk verdict for a principal
5794
+ description: Returns the current risk verdict for a specific user or agent.
5795
+ operationId: getRiskVerdict
5796
+ parameters:
5797
+ - name: principal_type
5798
+ in: path
5799
+ required: true
5800
+ schema:
5801
+ type: string
5802
+ enum: [user, agent]
5803
+ - name: principal_id
5804
+ in: path
5805
+ required: true
5806
+ schema:
5807
+ type: string
5808
+ format: uuid
5809
+ responses:
5810
+ "200":
5811
+ description: Risk verdict (null if no verdict exists)
5812
+ content:
5813
+ application/json:
5814
+ schema:
5815
+ type: object
5816
+ properties:
5817
+ verdict:
5818
+ $ref: "#/components/schemas/RiskVerdict"
5819
+ nullable: true
5820
+ "401":
5821
+ $ref: "#/components/responses/Unauthorized"
5822
+ "404":
5823
+ $ref: "#/components/responses/NotFound"
5824
+
5825
+ /v1/risk/honeytokens:
5826
+ get:
5827
+ tags: [Risk Engine]
5828
+ summary: List honeytokens
5829
+ description: Returns all honeytokens (canary secrets) configured for the caller's organization.
5830
+ operationId: listHoneytokens
5831
+ responses:
5832
+ "200":
5833
+ description: Honeytoken list
5834
+ content:
5835
+ application/json:
5836
+ schema:
5837
+ $ref: "#/components/schemas/HoneytokenListResponse"
5838
+ "401":
5839
+ $ref: "#/components/responses/Unauthorized"
5840
+ post:
5841
+ tags: [Risk Engine]
5842
+ summary: Create a honeytoken
5843
+ description: |
5844
+ Register a secret path as a honeytoken (canary). Any access to this secret
5845
+ triggers a risk event and increments the trigger counter.
5846
+ operationId: createHoneytoken
5847
+ requestBody:
5848
+ required: true
5849
+ content:
5850
+ application/json:
5851
+ schema:
5852
+ $ref: "#/components/schemas/CreateHoneytokenRequest"
5853
+ responses:
5854
+ "201":
5855
+ description: Honeytoken created
5856
+ content:
5857
+ application/json:
5858
+ schema:
5859
+ type: object
5860
+ properties:
5861
+ honeytoken:
5862
+ $ref: "#/components/schemas/Honeytoken"
5863
+ "400":
5864
+ $ref: "#/components/responses/BadRequest"
5865
+ "401":
5866
+ $ref: "#/components/responses/Unauthorized"
5867
+
5868
+ /v1/risk/honeytokens/{id}:
5869
+ delete:
5870
+ tags: [Risk Engine]
5871
+ summary: Delete a honeytoken
5872
+ description: Remove a honeytoken registration. The underlying secret is not affected.
5873
+ operationId: deleteHoneytoken
5874
+ parameters:
5875
+ - name: id
5876
+ in: path
5877
+ required: true
5878
+ schema:
5879
+ type: string
5880
+ format: uuid
5881
+ responses:
5882
+ "200":
5883
+ description: Honeytoken deleted
5884
+ content:
5885
+ application/json:
5886
+ schema:
5887
+ type: object
5888
+ properties:
5889
+ deleted:
5890
+ type: boolean
5891
+ "401":
5892
+ $ref: "#/components/responses/Unauthorized"
5893
+ "404":
5894
+ $ref: "#/components/responses/NotFound"
5285
5895
 
5286
5896
  # =============================================================================
5287
5897
  # COMPONENTS
@@ -7644,6 +8254,32 @@ components:
7644
8254
  type: string
7645
8255
  format: uuid
7646
8256
 
8257
+ OrgBankrConfigResponse:
8258
+ type: object
8259
+ properties:
8260
+ configured:
8261
+ type: boolean
8262
+ partner_key_prefix:
8263
+ type: string
8264
+ default_wallet_id:
8265
+ type: string
8266
+ updated_at:
8267
+ type: string
8268
+ format: date-time
8269
+ using_platform_fallback:
8270
+ type: boolean
8271
+
8272
+ UpsertOrgBankrConfigRequest:
8273
+ type: object
8274
+ required: [partner_key]
8275
+ properties:
8276
+ partner_key:
8277
+ type: string
8278
+ description: Bankr partner API key (bk_ptr_...)
8279
+ default_wallet_id:
8280
+ type: string
8281
+ description: Default provisioned wallet (wlt_...)
8282
+
7647
8283
  # --- Billing ---
7648
8284
 
7649
8285
  UsageSummaryResponse:
@@ -9459,3 +10095,334 @@ components:
9459
10095
  created_at:
9460
10096
  type: string
9461
10097
  format: date-time
10098
+
10099
+ # --- Email OTP ---
10100
+
10101
+ EmailOtpVerifyResponse:
10102
+ type: object
10103
+ required: [token, user_id, org_id, is_new_user, email]
10104
+ properties:
10105
+ token:
10106
+ type: string
10107
+ description: JWT access token
10108
+ user_id:
10109
+ type: string
10110
+ format: uuid
10111
+ org_id:
10112
+ type: string
10113
+ format: uuid
10114
+ is_new_user:
10115
+ type: boolean
10116
+ email:
10117
+ type: string
10118
+ format: email
10119
+ wallet_address:
10120
+ type: string
10121
+ nullable: true
10122
+ description: Ethereum address if auto_provision_chains included an EVM chain
10123
+
10124
+ # --- OAuth ---
10125
+
10126
+ OAuthConsentResponse:
10127
+ type: object
10128
+ required: [app_name, app_slug, scopes, redirect_uri, already_consented]
10129
+ properties:
10130
+ app_name:
10131
+ type: string
10132
+ app_slug:
10133
+ type: string
10134
+ app_logo_url:
10135
+ type: string
10136
+ format: uri
10137
+ nullable: true
10138
+ scopes:
10139
+ type: array
10140
+ items: { type: string }
10141
+ redirect_uri:
10142
+ type: string
10143
+ format: uri
10144
+ already_consented:
10145
+ type: boolean
10146
+
10147
+ OAuthTokenResponse:
10148
+ type: object
10149
+ required: [access_token, token_type, expires_in, scope]
10150
+ properties:
10151
+ access_token:
10152
+ type: string
10153
+ token_type:
10154
+ type: string
10155
+ enum: [Bearer]
10156
+ expires_in:
10157
+ type: integer
10158
+ description: Token lifetime in seconds
10159
+ id_token:
10160
+ type: string
10161
+ nullable: true
10162
+ description: OIDC ID token (when openid scope was granted)
10163
+ scope:
10164
+ type: string
10165
+
10166
+ OAuthUserInfoResponse:
10167
+ type: object
10168
+ required: [sub, email]
10169
+ properties:
10170
+ sub:
10171
+ type: string
10172
+ format: uuid
10173
+ email:
10174
+ type: string
10175
+ format: email
10176
+ name:
10177
+ type: string
10178
+ nullable: true
10179
+ wallet_address:
10180
+ type: string
10181
+ nullable: true
10182
+
10183
+ # --- Spend Policies ---
10184
+
10185
+ CreateSpendPolicyRequest:
10186
+ type: object
10187
+ properties:
10188
+ user_id:
10189
+ type: string
10190
+ format: uuid
10191
+ description: Scope to a specific user (app-level policies only)
10192
+ to_allowlist:
10193
+ type: array
10194
+ items: { type: string }
10195
+ description: Permitted destination addresses (empty = unrestricted)
10196
+ to_denylist:
10197
+ type: array
10198
+ items: { type: string }
10199
+ description: Blocked destination addresses
10200
+ max_value_per_tx_eth:
10201
+ type: string
10202
+ description: Maximum value per transaction in ETH (decimal string)
10203
+ daily_limit_eth:
10204
+ type: string
10205
+ description: Rolling 24h spend cap in ETH (decimal string)
10206
+ allowed_chains:
10207
+ type: array
10208
+ items: { type: string }
10209
+ description: Chains the user may transact on (empty = all enabled)
10210
+ allowed_tokens:
10211
+ type: array
10212
+ items: { type: string }
10213
+ description: Permitted ERC-20 token contract addresses
10214
+ max_transactions_per_day:
10215
+ type: integer
10216
+ description: Maximum number of transactions per 24h window
10217
+
10218
+ SpendPolicyResponse:
10219
+ type: object
10220
+ required: [id, platform_app_id, created_at]
10221
+ properties:
10222
+ id:
10223
+ type: string
10224
+ format: uuid
10225
+ platform_app_id:
10226
+ type: string
10227
+ format: uuid
10228
+ user_id:
10229
+ type: string
10230
+ format: uuid
10231
+ nullable: true
10232
+ to_allowlist:
10233
+ type: array
10234
+ items: { type: string }
10235
+ to_denylist:
10236
+ type: array
10237
+ items: { type: string }
10238
+ max_value_per_tx_eth:
10239
+ type: string
10240
+ nullable: true
10241
+ daily_limit_eth:
10242
+ type: string
10243
+ nullable: true
10244
+ allowed_chains:
10245
+ type: array
10246
+ items: { type: string }
10247
+ allowed_tokens:
10248
+ type: array
10249
+ items: { type: string }
10250
+ max_transactions_per_day:
10251
+ type: integer
10252
+ nullable: true
10253
+ created_at:
10254
+ type: string
10255
+ format: date-time
10256
+
10257
+ # --- Risk Engine ---
10258
+
10259
+ RiskEvent:
10260
+ type: object
10261
+ required: [id, occurred_at, principal_type, principal_id, org_id, event_type, payload, created_at]
10262
+ properties:
10263
+ id:
10264
+ type: string
10265
+ format: uuid
10266
+ occurred_at:
10267
+ type: string
10268
+ format: date-time
10269
+ principal_type:
10270
+ type: string
10271
+ enum: [user, agent]
10272
+ principal_id:
10273
+ type: string
10274
+ format: uuid
10275
+ org_id:
10276
+ type: string
10277
+ format: uuid
10278
+ event_type:
10279
+ type: string
10280
+ description: "Risk event type (e.g. first_seen, geo_velocity, honeytoken_access)"
10281
+ ip:
10282
+ type: string
10283
+ nullable: true
10284
+ asn:
10285
+ type: integer
10286
+ nullable: true
10287
+ asn_org:
10288
+ type: string
10289
+ nullable: true
10290
+ country_code:
10291
+ type: string
10292
+ nullable: true
10293
+ region:
10294
+ type: string
10295
+ nullable: true
10296
+ city:
10297
+ type: string
10298
+ nullable: true
10299
+ latitude:
10300
+ type: number
10301
+ nullable: true
10302
+ longitude:
10303
+ type: number
10304
+ nullable: true
10305
+ user_agent:
10306
+ type: string
10307
+ nullable: true
10308
+ payload:
10309
+ type: object
10310
+ additionalProperties: true
10311
+ created_at:
10312
+ type: string
10313
+ format: date-time
10314
+
10315
+ RiskEventListResponse:
10316
+ type: object
10317
+ required: [events]
10318
+ properties:
10319
+ events:
10320
+ type: array
10321
+ items:
10322
+ $ref: "#/components/schemas/RiskEvent"
10323
+
10324
+ RiskVerdictReason:
10325
+ type: object
10326
+ required: [detector, severity, description]
10327
+ properties:
10328
+ detector:
10329
+ type: string
10330
+ severity:
10331
+ type: string
10332
+ description:
10333
+ type: string
10334
+ metadata:
10335
+ type: object
10336
+ additionalProperties: true
10337
+
10338
+ RiskVerdict:
10339
+ type: object
10340
+ required: [principal_type, principal_id, org_id, score, severity, reasons, computed_at, expires_at]
10341
+ properties:
10342
+ principal_type:
10343
+ type: string
10344
+ principal_id:
10345
+ type: string
10346
+ format: uuid
10347
+ org_id:
10348
+ type: string
10349
+ format: uuid
10350
+ score:
10351
+ type: number
10352
+ description: Composite risk score (0.0 – 100.0)
10353
+ severity:
10354
+ type: string
10355
+ enum: [low, medium, high, critical]
10356
+ reasons:
10357
+ type: array
10358
+ items:
10359
+ $ref: "#/components/schemas/RiskVerdictReason"
10360
+ computed_at:
10361
+ type: string
10362
+ format: date-time
10363
+ expires_at:
10364
+ type: string
10365
+ format: date-time
10366
+
10367
+ RiskVerdictListResponse:
10368
+ type: object
10369
+ required: [verdicts]
10370
+ properties:
10371
+ verdicts:
10372
+ type: array
10373
+ items:
10374
+ $ref: "#/components/schemas/RiskVerdict"
10375
+
10376
+ Honeytoken:
10377
+ type: object
10378
+ required: [id, vault_id, org_id, secret_path, created_by, created_at, triggered_count]
10379
+ properties:
10380
+ id:
10381
+ type: string
10382
+ format: uuid
10383
+ vault_id:
10384
+ type: string
10385
+ format: uuid
10386
+ org_id:
10387
+ type: string
10388
+ format: uuid
10389
+ secret_path:
10390
+ type: string
10391
+ created_by:
10392
+ type: string
10393
+ format: uuid
10394
+ created_at:
10395
+ type: string
10396
+ format: date-time
10397
+ notes:
10398
+ type: string
10399
+ nullable: true
10400
+ triggered_count:
10401
+ type: integer
10402
+ last_triggered_at:
10403
+ type: string
10404
+ format: date-time
10405
+ nullable: true
10406
+
10407
+ CreateHoneytokenRequest:
10408
+ type: object
10409
+ required: [vault_id, secret_path]
10410
+ properties:
10411
+ vault_id:
10412
+ type: string
10413
+ format: uuid
10414
+ secret_path:
10415
+ type: string
10416
+ description: Vault secret path to monitor as a canary
10417
+ notes:
10418
+ type: string
10419
+ description: Optional human-readable notes about this honeytoken
10420
+
10421
+ HoneytokenListResponse:
10422
+ type: object
10423
+ required: [honeytokens]
10424
+ properties:
10425
+ honeytokens:
10426
+ type: array
10427
+ items:
10428
+ $ref: "#/components/schemas/Honeytoken"