keep icon indicating copy to clipboard operation
keep copied to clipboard

[šŸ› Bug]: Secrets truncated in DB mode cause provider OAuth JSON parse errors

Open Aze331 opened this issue 4 months ago • 0 comments

Describe the bug When using MySQL DB secret manager (SECRET_MANAGER_TYPE=db), provider OAuth secrets (e.g., PagerDuty) were truncated due to the secret.value column being defined as VARCHAR(255).

As a result, long JSON tokens (access/refresh tokens from OAuth) were cut off at 255 characters. This caused JSON parsing to fail with errors such as: Unterminated string starting at: line 1 column 247 (char 246) and prevented provider installation (HTTP 400/500 during OAuth callback).

To Reproduce Steps to reproduce the behavior:

  1. Deploy Keep with: SECRET_MANAGER_TYPE=db and a MySQL database.
  2. Attempt to install an OAuth-based provider (e.g., PagerDuty).
  3. Observe the provider installation fail and backend logs show truncated JSON or an ā€œunterminated stringā€ error.
  4. Inspect the secret table: SELECT key, CHAR_LENGTH(value) FROM secret ORDER BY CHAR_LENGTH(value) DESC LIMIT 10;. Values are cut off at exactly 255 characters.

Expected behavior OAuth token JSON should be stored completely, and provider installation should succeed without data truncation or JSON parsing errors.

Impact

  • Affects all OAuth2 providers that store large credentials (PagerDuty, Flux, etc.) when using the DB secret manager.
  • Not reproducible when using Kubernetes or cloud secret managers.
  • Breaks new provider installations, but existing short secrets remain unaffected.

Root cause The database schema defines:

# keep/api/models/db/secret.py
value: str = Field()

which maps to a VARCHAR(255) column in MySQL by default, too small for JSON OAuth tokens.

Proposed resolution

  1. Change the column type for secret.value to TEXT in both the model and migrations.
  2. Ensure existing deployments migrate automatically via Alembic.
  3. After upgrade, verify with: SHOW COLUMNS FROM secret LIKE 'value'; Expected output: Type: text

Additional context

  • Moving to SECRET_MANAGER_TYPE=k8s resolves the issue completely since Kubernetes Secrets have no such size limitation.
  • The issue originates in the database secret manager setup.
  • I haven’t tested this proposed fix.

Suggested migration change

# In keep/api/models/db/secret.py
value: str = Field(sa_column=Column(Text))

# Alembic migration example
with op.batch_alter_table("secret") as batch_op:
    batch_op.alter_column("value", existing_type=sa.String(length=255), type_=sa.Text())

Aze331 avatar Oct 06 '25 06:10 Aze331