# `configuration.secret_flow`

Your code reads a secret setting somewhere other than the few places where Jadpo keeps it on the server.

Area 10, [Configuration](/docs/configuration.md); not declinable; the next step is usually the agent's.

## Why Jadpo refuses it

A setting marked `secret: true`, such as a password or an API key, must
never leave the server. Jadpo takes a secret only where it uses the value
itself: a connection's `url:`, an integration's `credential:`, an
authentication `signing_key:` and a `crypto` call's `key:`.

Anywhere else, your code could leak it. Returning it, storing it, logging
it, putting it in a failure or building another value from it could all
show it to someone. Even comparing it is refused, because each yes-or-no
answer gives the secret away one guess at a time.

## What it looks like

main.jadpo:

```jadpo
type PartnerKey = Text {
    min_length: 8
}

config {
    api_key: PartnerKey {
        secret: true
    }
}

function expose_secret() -> PartnerKey {
    return config.api_key
}
```

```text
error: `config.api_key` is a secret
 --> main.jadpo:12:12
   |
12 |     return config.api_key
   |            ^^^^^^^^^^^^^^ a secret, read here
  reason: A secret never leaves the server, so it is accepted only where the compiler itself owns the place: a connection's `url:`, an integration's `credential:`, an authentication `signing_key:` and a `crypto` call's `key:`. Returning it, storing it, logging it, putting it in a failure, building another value from it or comparing it with something could leak it.
  next: Give `config.api_key` to the connection, integration or authentication that needs it in `app.jadpo` or `authentication.jadpo`, or as a `crypto` call's `key:`, or leave `secret: true` off `api_key` if its value is public (agent)
  rule: configuration.secret_flow
  help: https://jadpo.dev/docs/errors/configuration.secret_flow

check failed: 1 error, 1 file
```

`(agent)` at the end of the `next:` line means your coding agent can make
the fix itself.

## How to fix it

The question is what the secret is for.

**If it is the key for an outside API**, give it to the connection that
calls that API, as its `credential:`, and delete the function that read
it. In `app.jadpo`:

```jadpo
            credential: config.api_key
```







Jadpo sends the key with each call the `partner` connection makes, and
your code never holds it. A database address goes to a connection's
`url:` in the same way, and a signing or encryption key to a `crypto`
call's `key:`.

**If the value is public**, it isn't a secret, so delete `secret: true`.
The setting becomes:

```jadpo
    api_key: PartnerKey
```


Your code may now read, return and log `config.api_key` like any other
setting, so do this only for a value anyone may see.

## Related

- [Secrets](/docs/secrets.md)
- [Connecting in `app.jadpo`](/docs/connecting-in-app-jadpo.md)
- [Hashing and cryptography](/docs/hashing-and-cryptography.md)
