GuardrailCredential.validate_kwargs is a plain JSON column. guardrail_credential_service splits constructor arguments by the catalog's secret flag and encrypts the secret half, but per-call arguments get no such split: whatever the operator sends is stored as it is. Only the response is protected, by redact_secret_like_values masking keys that look credential-shaped.
GuardrailParameterSpec.secret exists on validate parameters too, so the day a guardrail upstream declares one, it lands in cleartext in the database and in every backup, silently. Nothing fails, and the output mask may still hide it, so the write side would look fine.
Not reachable today
None of the ten guardrails the catalog lists marks a validate parameter secret. Checked against build_builtin_guardrail_catalog():
| guardrail |
validate parameters |
alinia |
output, context_documents |
any_llm |
policy, model_id, system_prompt, prompt_version |
azure_prompt_shields |
documents |
patronus |
output_text, retrieved_context |
azure_content_safety, bedrock_guardrails, lakera_guard, openai_moderation, susfactor, watsonx_guardian |
none |
Every one is content, not a credential. So this is a latent gap rather than a live exposure: there is no stored plaintext secret in this column today.
Why this is filed rather than fixed on #1211
Surfaced there: #1211 (comment)
#1209 specified this column deliberately, plain with masking on output, modeled on how organization_guardrails already treats its own validate_kwargs. Changing it means a second encrypted column, a migration, the same *** restore semantics on PATCH that create_kwargs has, and the four generated artifacts. That is a feature-sized change against a design the issue argued for, not a fix to slip into it.
Closing it properly also wants a guard, so the next guardrail with a secret validate parameter cannot reintroduce the gap by accident.
Scope
- An
encrypted_validate_secrets column beside encrypted_create_secrets, with the migration.
- Reuse
split_create_kwargs's shape for the validate stage, so the split stays read off the catalog rather than written down.
- The
*** restore path on PATCH, matching _merged_create_kwargs.
- A test that fails if any catalog guardrail declares a secret validate parameter while the column is still plain, so the latent case cannot land unnoticed.
Related
GuardrailCredential.validate_kwargsis a plain JSON column.guardrail_credential_servicesplits constructor arguments by the catalog'ssecretflag and encrypts the secret half, but per-call arguments get no such split: whatever the operator sends is stored as it is. Only the response is protected, byredact_secret_like_valuesmasking keys that look credential-shaped.GuardrailParameterSpec.secretexists on validate parameters too, so the day a guardrail upstream declares one, it lands in cleartext in the database and in every backup, silently. Nothing fails, and the output mask may still hide it, so the write side would look fine.Not reachable today
None of the ten guardrails the catalog lists marks a validate parameter secret. Checked against
build_builtin_guardrail_catalog():aliniaoutput,context_documentsany_llmpolicy,model_id,system_prompt,prompt_versionazure_prompt_shieldsdocumentspatronusoutput_text,retrieved_contextazure_content_safety,bedrock_guardrails,lakera_guard,openai_moderation,susfactor,watsonx_guardianEvery one is content, not a credential. So this is a latent gap rather than a live exposure: there is no stored plaintext secret in this column today.
Why this is filed rather than fixed on #1211
Surfaced there: #1211 (comment)
#1209 specified this column deliberately, plain with masking on output, modeled on how
organization_guardrailsalready treats its ownvalidate_kwargs. Changing it means a second encrypted column, a migration, the same***restore semantics on PATCH thatcreate_kwargshas, and the four generated artifacts. That is a feature-sized change against a design the issue argued for, not a fix to slip into it.Closing it properly also wants a guard, so the next guardrail with a secret validate parameter cannot reintroduce the gap by accident.
Scope
encrypted_validate_secretscolumn besideencrypted_create_secrets, with the migration.split_create_kwargs's shape for the validate stage, so the split stays read off the catalog rather than written down.***restore path on PATCH, matching_merged_create_kwargs.Related
redact_secret_like_valuesmasks only top-level keys, which this column's output mask inherits.validate_urlcheck.