Skip to content
Kavachकवच

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 characters
secret-result.kav: Kavach code, then what running it prints

Returning 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 to
secret-result-plain.kav: Kavach code, then what running it prints

And 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 to
secret-result-print.kav: Kavach code, then what running it prints

A 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 to
secret-result-lambda.kav: Kavach code, then what running it prints

Interface methods and the methods that implement them agree on it.