{"record":{"id":"aae02e6d5ba7f3fe","repo":"risingwavelabs/risingwave","slug":"key-is-enforced-to-be-a-secret-on-risingwave-clo","errorCode":null,"errorMessage":"{key} is enforced to be a SECRET on RisingWave Cloud, please use `CREATE SECRET` first","messagePattern":"(.+?) is enforced to be a SECRET on RisingWave Cloud, please use `CREATE SECRET` first","errorType":"exception","errorClass":"EnforceSecretError","httpStatus":null,"severity":"error","filePath":"src/connector/src/enforce_secret.rs","lineNumber":20,"sourceCode":"//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nuse phf::{Set, phf_set};\n\nuse crate::error::ConnectorResult as Result;\n\n#[derive(Debug, thiserror::Error)]\n#[error(\"{key} is enforced to be a SECRET on RisingWave Cloud, please use `CREATE SECRET` first\")]\npub struct EnforceSecretError {\n    pub key: String,\n}\n\npub trait EnforceSecret {\n    const ENFORCE_SECRET_PROPERTIES: Set<&'static str> = phf_set! {};\n\n    fn enforce_secret<'a>(prop_iter: impl Iterator<Item = &'a str>) -> Result<()> {\n        for prop in prop_iter {\n            if Self::ENFORCE_SECRET_PROPERTIES.contains(prop) {\n                return Err(EnforceSecretError {\n                    key: prop.to_owned(),\n                }\n                .into());\n            }\n        }\n        Ok(())\n    }","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/enforce_secret.rs#L2-L38","documentation":"When connecting to RisingWave Cloud, certain connector option keys (passwords, access keys, tokens) are mandatory secrets. If a user passes such a key as a plain-text option instead of referencing a secret created via CREATE SECRET, validation fails with EnforceSecretError naming the offending key.","triggerScenarios":"CREATE SINK/SOURCE with a connector option like 'password', 'aws.access_key_id', or a private key passed inline as a literal while running on RisingWave Cloud, where that key is in ENFORCE_SECRET_PROPERTIES.","commonSituations":"Deploying to RisingWave Cloud after testing locally with inline credentials; copying a local CREATE SOURCE statement to Cloud; following outdated documentation/examples that pass secrets inline.","solutions":["Create a secret: CREATE SECRET my_secret WITH (backend='meta');","Reference it in the connector options: password = SECRET my_secret","Remove the plain-text value for the enforced key from the statement"],"exampleFix":"// before\nCREATE SOURCE s WITH (connector='kafka', password='plaintext', ...);\n// after\nCREATE SECRET kafka_password WITH (backend='meta');\nCREATE SOURCE s WITH (connector='kafka', password=SECRET kafka_password, ...);","handlingStrategy":"validation","validationCode":"const ENFORCED_KEYS = ['password','aws.access_key_id','aws.secret_access_key','ssh_key','private_key'];\nfunction validateOptions(opts) {\n  for (const k of Object.keys(opts)) {\n    if (ENFORCED_KEYS.includes(k) && typeof opts[k] === 'string') {\n      throw new Error(`${k} must reference a secret: use CREATE SECRET then ${k}=SECRET name`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await rw.query(createSinkSql);\n} catch (e) {\n  if (/is enforced to be a SECRET/.test(e.message)) {\n    const key = e.message.split(' ')[0];\n    // create secret and rewrite statement with SECRET reference\n  } else throw e;\n}","preventionTips":["Never inline credentials in CREATE SOURCE/SINK statements on Cloud","Create secrets via CREATE SECRET before provisioning connectors","Keep local and Cloud deployment SQL templated so secrets are substituted consistently"],"tags":["security","secrets","risingwave-cloud","connector-options"],"backgroundTag":"missing-credentials","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}