bitcain docs

Exchange & Vault

Exchange & Vault

Encrypted API key storage, exchange connections, and secure credential management.

15 tables in this group.

api_keys

Encrypted exchange API keys with user-level RLS. Keys encrypted with per-user encryption keys (zero-friction UX - no master password required).

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
user_iduuidNo
exchangetextNo
encrypted_api_keytextNo
encrypted_secrettextNo
encrypted_passphrasetextYes
key_ivtextNo
secret_ivtextNo
passphrase_ivtextYes
salttextYes
is_activeboolYestrue
last_usedtimestamptzYes
created_attimestamptzYesnow()
updated_attimestamptzYesnow()
environmenttextYes'production'::text
nametextYes
permissions_textYesARRAY['read'::text]
rotation_generationint4Yes1
is_rotation_activeboolYestrue
rotated_from_key_iduuidYes
rotation_grace_period_ends_attimestamptzYes
auto_rotation_enabledboolYestrue

RLS Policies:

  • Users can delete own API keys — DELETE for {public}
  • Users can insert own API keys — INSERT for {public}
  • Users can update own API keys — UPDATE for {public}
  • Users can view own API keys — SELECT for {public}

Indexes:

  • api_keys_pkey
  • idx_api_keys_auto_rotation
  • idx_api_keys_exchange
  • idx_api_keys_grace_period
  • idx_api_keys_rotated_from_key_id
  • idx_api_keys_user_id

encrypted_api_keys

ColumnTypeNullableDefault
iduuidNouuid_generate_v4()
user_iduuidNo
exchangetextNo
key_nametextNo
encrypted_api_keytextNo
encrypted_secrettextNo
encrypted_passphrasetextYes
permissionsjsonbYes'{}'::jsonb
is_activeboolYestrue
is_testnetboolYesfalse
created_attimestamptzYesnow()
updated_attimestamptzYesnow()
last_used_attimestamptzYes

RLS Policies:

  • Users can manage their own API keys — ALL for {public}

Indexes:

  • encrypted_api_keys_pkey
  • encrypted_api_keys_user_id_exchange_key_name_key

encrypted_exchange_credentials

ColumnTypeNullableDefault
iduuidNouuid_generate_v4()
user_iduuidNo
exchange_namevarchar(100)No
exchange_account_labelvarchar(255)Yes'Primary Account'::character varying
is_testnetboolYesfalse
encrypted_api_keytextNo
encrypted_api_secrettextNo
encrypted_passphrasetextYes
ivtextNo
encryption_algorithmvarchar(50)No'AES-256-GCM'::character varying
auth_tagtextYes
permissionsjsonbNo'{"read": true, "trade": false, "withdraw": false}'::jsonb
rate_limitsjsonbYes'{}'::jsonb
activeboolNotrue
key_versionint4No1
rotated_from_iduuidYes
rotation_scheduled_attimestamptzYes
expires_attimestamptzYes
last_used_attimestamptzYes
usage_countint4Yes0
created_attimestamptzNonow()
updated_attimestamptzNonow()

RLS Policies:

  • rls_exchange_credentials_delete — DELETE for {public}
  • rls_exchange_credentials_insert — INSERT for {public}
  • rls_exchange_credentials_select — SELECT for {public}
  • rls_exchange_credentials_update — UPDATE for {public}

Indexes:

  • encrypted_exchange_credential_user_id_exchange_name_exchang_key
  • encrypted_exchange_credentials_pkey
  • idx_encrypted_exchange_credentials_rotated_from_id

user_encryption_keys

Per-user encryption keys for API credentials. Each user gets a unique key derived from user_id + PLATFORM_MASTER_KEY. Keys are encrypted with platform master key. Protects against single-user breaches.

ColumnTypeNullableDefault
user_iduuidNo
encrypted_keytextNo
key_ivtextNo
versionint4Yes1
created_attimestamptzYesnow()
updated_attimestamptzYesnow()

RLS Policies:

  • Users can access own encryption key — SELECT for {public}

Indexes:

  • user_encryption_keys_pkey

vault_metadata

ColumnTypeNullableDefault
iduuidNouuid_generate_v4()
user_iduuidNo
salttextNo
kdf_algorithmvarchar(50)No'PBKDF2-SHA256'::character varying
kdf_iterationsint4No100000
kdf_memoryint4Yes
kdf_parallelismint4Yes
auto_lock_timeout_minutesint4Yes15
require_password_on_decryptboolYestrue
biometric_unlock_enabledboolYesfalse
created_attimestamptzNonow()
updated_attimestamptzNonow()
last_unlocked_attimestamptzYes
failed_unlock_attemptsint4Yes0
last_failed_unlock_attimestamptzYes

RLS Policies:

  • rls_vault_metadata_insert — INSERT for {public}
  • rls_vault_metadata_select — SELECT for {public}
  • rls_vault_metadata_update — UPDATE for {public}

Indexes:

  • vault_metadata_pkey
  • vault_metadata_user_id_key

vault_access_log

ColumnTypeNullableDefault
iduuidNouuid_generate_v4()
user_iduuidNo
event_typevarchar(50)No
exchange_credential_iduuidYes
successboolNotrue
failure_reasontextYes
ip_addressinetYes
user_agenttextYes
session_iduuidYes
device_fingerprinttextYes
geo_countryvarchar(2)Yes
geo_cityvarchar(100)Yes
metadatajsonbYes'{}'::jsonb
created_attimestamptzNonow()

RLS Policies:

  • rls_vault_access_log_insert — INSERT for {public}
  • rls_vault_access_log_select — SELECT for {public}

Indexes:

  • idx_vault_access_log_exchange_credential_id
  • idx_vault_access_log_user_id
  • vault_access_log_pkey

exchange_connections

ColumnTypeNullableDefault
iduuidNo
user_iduuidNo
namevarchar(100)No
exchange_typevarchar(50)No
environmentvarchar(20)Yes
statusvarchar(20)Yes
is_defaultboolYes
is_enabledboolYes
encrypted_api_keybyteaNo
encrypted_secret_keybyteaNo
encrypted_passphrasebyteaYes
key_encryption_saltbyteaNo
api_key_labelvarchar(100)Yes
api_key_permissionsjsonYes
api_key_created_attimestampYes
api_key_expires_attimestampYes
api_key_last_usedtimestampYes
base_urlvarchar(500)Yes
rate_limitint4Yes
timeout_secondsint4Yes
retry_attemptsint4Yes
daily_withdraw_limitnumericYes
monthly_withdraw_limitnumericYes
max_position_sizenumericYes
allowed_symbolsjsonYes
blocked_symbolsjsonYes
max_daily_lossnumericYes
stop_loss_percentagenumericYes
max_leveragenumericYes
last_successful_pingtimestampYes
last_error_messagetextYes
error_countint4Yes
connection_warningsjsonYes
created_attimestampNo
updated_attimestampYes
last_verified_attimestampYes
verification_statusvarchar(20)Yes
connection_metadatajsonYes
tagsjsonYes

RLS Policies:

  • exchange_connections_delete_own — DELETE for {public}
  • exchange_connections_insert_own — INSERT for {public}
  • exchange_connections_select_own — SELECT for {public}
  • exchange_connections_update_own — UPDATE for {public}

Indexes:

  • exchange_connections_pkey
  • ix_exchange_connections_exchange_type
  • ix_exchange_connections_status
  • ix_exchange_connections_user_id

exchange_balances

ColumnTypeNullableDefault
iduuidNo
connection_iduuidNo
user_iduuidNo
symbolvarchar(20)No
total_balancenumericNo
available_balancenumericNo
locked_balancenumericNo
account_typevarchar(20)Yes
usd_valuenumericYes
last_pricenumericYes
last_updatedtimestampYes
synced_attimestampNo

RLS Policies:

  • exchange_balances_delete_own — DELETE for {public}
  • exchange_balances_insert_own — INSERT for {public}
  • exchange_balances_select_own — SELECT for {public}
  • exchange_balances_update_own — UPDATE for {public}

Indexes:

  • exchange_balances_pkey
  • idx_exchange_balances_connection_id
  • idx_exchange_balances_user_id
  • ix_exchange_balances_symbol
  • ix_exchange_balances_synced_at

exchange_api_calls

ColumnTypeNullableDefault
iduuidNo
connection_iduuidNo
user_iduuidNo
endpointvarchar(500)No
methodvarchar(10)No
parametersjsonYes
status_codeint4Yes
response_time_msint4Yes
successboolYes
error_messagetextYes
rate_limit_remainingint4Yes
rate_limit_resettimestampYes
ip_addressvarchar(45)Yes
user_agentvarchar(500)Yes
session_iduuidYes
created_attimestampNo

RLS Policies:

  • exchange_api_calls_delete_own — DELETE for {public}
  • exchange_api_calls_insert_own — INSERT for {public}
  • exchange_api_calls_select_own — SELECT for {public}
  • exchange_api_calls_update_own — UPDATE for {public}

Indexes:

  • exchange_api_calls_pkey
  • idx_exchange_api_calls_connection_id
  • idx_exchange_api_calls_user_id
  • ix_exchange_api_calls_created_at

site_api_keys

Encrypted API keys for third-party AI providers. Admin-only access via RLS. Keys encrypted with GCP KMS before storage.

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
providervarchar(50)No
encrypted_keytextNo
key_prefixvarchar(20)Yes
is_activeboolNotrue
last_used_attimestamptzYes
usage_countint4No0
last_rotated_attimestamptzYes
rotation_reminder_daysint4No90
next_rotation_datetimestamptzYes
notestextYes
created_attimestamptzNonow()
updated_attimestamptzNonow()
created_byuuidYes
updated_byuuidYes

RLS Policies:

  • Admin full access to site_api_keys — ALL for {authenticated}

Indexes:

  • idx_site_api_keys_active
  • idx_site_api_keys_provider
  • idx_site_api_keys_provider_active
  • idx_site_api_keys_provider_unique_active
  • idx_site_api_keys_rotation
  • site_api_keys_pkey

api_key_permissions

Defines permission scopes and rate limits for each API key

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
api_key_iduuidNo
can_readboolYestrue
can_tradeboolYesfalse
can_withdrawboolYesfalse
can_transferboolYesfalse
can_manage_sub_accountsboolYesfalse
max_requests_per_minuteint4Yes60
max_requests_per_hourint4Yes3600
max_requests_per_dayint4Yes100000
max_trade_amount_usdnumericYes
max_daily_trade_volume_usdnumericYes
max_withdrawal_amount_usdnumericYes
max_daily_withdrawal_usdnumericYes
allowed_ip_addresses_inetYes
created_attimestamptzNonow()
updated_attimestamptzNonow()

RLS Policies:

  • Service role can insert api key permissions — INSERT for {public}
  • Users can update own api key permissions — UPDATE for {public}
  • Users can view own api key permissions — SELECT for {public}

Indexes:

  • api_key_permissions_pkey
  • idx_api_key_permissions_key_id
  • unique_api_key_permissions

api_key_rotation_schedule

Tracks API key rotation schedules and sends proactive reminders

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
api_key_iduuidNo
user_iduuidNo
rotation_interval_daysint4No90
last_rotated_attimestamptzNonow()
next_rotation_duetimestamptzNo
reminder_sent_30_daysboolYesfalse
reminder_sent_14_daysboolYesfalse
reminder_sent_7_daysboolYesfalse
reminder_sent_1_dayboolYesfalse
is_overdueboolYesfalse
days_overdueint4Yes0
created_attimestamptzNonow()
updated_attimestamptzNonow()

RLS Policies:

  • Service role can manage rotation schedules — ALL for {public}
  • Users can update own rotation schedules — UPDATE for {public}
  • Users can view own rotation schedules — SELECT for {public}

Indexes:

  • api_key_rotation_schedule_pkey
  • idx_api_key_rotation_due
  • idx_api_key_rotation_overdue
  • idx_api_key_rotation_schedule_api_key_id

api_key_usage_audit

Comprehensive audit log of all API key operations for security monitoring

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
api_key_iduuidNo
user_iduuidNo
operation_typetextNo
endpointtextNo
http_methodtextYes
ip_addressinetYes
user_agenttextYes
device_fingerprinttextYes
status_codeint4Yes
successboolYestrue
error_messagetextYes
daily_usage_countint4Yes0
monthly_usage_countint4Yes0
is_suspiciousboolYesfalse
suspicious_reasons_textYes
risk_scoreint4Yes0
created_attimestamptzNonow()

RLS Policies:

  • Service role can insert usage logs — INSERT for {public}
  • Users can view own api key usage — SELECT for {public}

Indexes:

  • api_key_usage_audit_pkey
  • idx_api_key_usage_audit_key_id
  • idx_api_key_usage_audit_operation
  • idx_api_key_usage_audit_suspicious
  • idx_api_key_usage_audit_user_id

integration_tokens

Stores encrypted OAuth tokens for third-party integrations

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
user_iduuidNo
integration_typevarchar(50)No
access_tokentextNo
refresh_tokentextYes
token_typevarchar(20)Yes'Bearer'::character varying
expires_attimestamptzYes
scopes_textYes
metadatajsonbYes'{}'::jsonb
created_attimestamptzYesnow()
updated_attimestamptzYesnow()

RLS Policies:

  • Service role can manage all integration tokens — ALL for {service_role}
  • Users can delete their own integration tokens — DELETE for {public}
  • Users can insert their own integration tokens — INSERT for {public}
  • Users can update their own integration tokens — UPDATE for {public}
  • Users can view their own integration tokens — SELECT for {public}

Indexes:

  • idx_integration_tokens_expires
  • idx_integration_tokens_type
  • idx_integration_tokens_user_id
  • integration_tokens_pkey
  • integration_tokens_user_id_integration_type_key

integrations

User integration configuration and enablement status

ColumnTypeNullableDefault
iduuidNogen_random_uuid()
user_iduuidNo
integration_typevarchar(50)No
enabledboolYesfalse
configurationjsonbYes'{}'::jsonb
last_sync_attimestamptzYes
created_attimestamptzYesnow()
updated_attimestamptzYesnow()

RLS Policies:

  • Service role can manage all integrations — ALL for {service_role}
  • Users can delete their own integrations — DELETE for {public}
  • Users can insert their own integrations — INSERT for {public}
  • Users can update their own integrations — UPDATE for {public}
  • Users can view their own integrations — SELECT for {public}

Indexes:

  • idx_integrations_type
  • idx_integrations_user_enabled
  • integrations_pkey
  • integrations_user_id_integration_type_key

On this page