Secrets: Secret results
● Intermediate3 min
A function that returns a secret says so in its result: -> secret T. Its caller gets a secret, like the field it came from.
type Config {
shop: String
secret api_key: String
}
fn api_key(config: Config) -> secret String {
config.api_key
}
fn main() {
const config = Config(shop: "pens", api_key: "sk_test_4f9a2c")
const key = api_key(config)
print("{config.shop}: a key of {reveal(key).len()} characters")
}The program ran and printed:
kavach run secret-result.kav
pens: a key of 14 charactersReturning a secret from a function whose result isn't secret is refused:
type Config {
shop: String
secret api_key: String
}
fn api_key(config: Config) -> String {
config.api_key
}
fn main() {
print(api_key(Config(shop: "pens", api_key: "sk_test_4f9a2c")))
}The compiler refused the program:
kavach run secret-result-plain.kav
error: `api_key` is secret, so `api_key` can't return it: write `-> secret …` for its result (spec 8.7), or use `reveal(…)` if you really mean toAnd what the caller gets stays a secret:
type Config {
shop: String
secret api_key: String
}
fn api_key(config: Config) -> secret String {
config.api_key
}
fn main() {
const key = api_key(Config(shop: "pens", api_key: "sk_test_4f9a2c"))
print("using {key}")
}The compiler refused the program:
kavach run secret-result-print.kav
error: `key` is secret, so it can't go into text; use `reveal(…)` if you really mean toA lambda can't return a secret: a function type has no way to say so. Write a named function with -> secret T instead:
type Config {
shop: String
secret api_key: String
}
fn main() {
const config = Config(shop: "pens", api_key: "sk_test_4f9a2c")
const get_key = () => config.api_key
print(reveal(get_key()).len())
}The compiler refused the program:
kavach run secret-result-lambda.kav
error: `api_key` is secret, and a lambda can't return a secret: return it from a named function with `-> secret …` (spec 8.7), or use `reveal(…)` if you really mean toInterface methods and the methods that implement them agree on it.