> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oasm.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Inputs & config

> How per-run inputs and the tool config profile reach your adapter

Connectors are never configured by flags or files. Inputs and config arrive on `Execute` and through environment variables injected by the worker.

## Reading inputs in `Execute`

Your adapter receives `inputs map[string]any` directly as an argument. Read values from it — do not read `INPUT_*` yourself unless you need the env defaults.

```go theme={null}
func (a *MyAdapter) Execute(ctx context.Context, inputs map[string]any, out chan<- connector.Finding) error {
    target, _ := inputs["target"].(string)
    // ...
}
```

## The `INPUT_*` defaults

`env.LoadInputs()` reads every `INPUT_*` environment variable and returns them as a map. Keys are lowercased with the prefix stripped.

| Env var | Becomes |
| - | - |
| `INPUT_TARGET` | `inputs["target"]` |
| `INPUT_SOME_KEY` | `inputs["some_key"]` |

```go theme={null}
import "github.com/oasm-platform/oasm-connectors/sdk/env"

defaults := env.LoadInputs()
```

**Precedence:** per-job inputs provided by the worker override `INPUT_*` environment defaults. The `inputs` map your adapter receives already has both merged, with the worker winning.

<Info>
  The runtime merges the two sources before calling your adapter, so you rarely need `env.LoadInputs()` in production code. It is useful when running the connector manually outside a worker.
</Info>

## The config profile (`OASM_CONFIG`)

`configSchema` values are delivered as a JSON string in the `OASM_CONFIG` environment variable. Read it **at execution time**, not at startup.

<Warning>
  A container reused for a second job gets its `OASM_CONFIG` replaced around each execution. Reading it in `main` or a package-level `init` gives you stale config — always read it inside `Execute`.
</Warning>

```go theme={null}
type Config struct {
    Severity []string `json:"severity"`
    RateLimit *int    `json:"rateLimit"`
}

func parseConfig(raw string) (Config, error) {
    if strings.TrimSpace(raw) == "" {
        return Config{}, nil
    }
    var cfg Config
    if err := json.Unmarshal([]byte(raw), &cfg); err != nil {
        return Config{}, err
    }
    return cfg, nil
}

func (a *MyAdapter) Execute(ctx context.Context, inputs map[string]any, out chan<- connector.Finding) error {
    cfg, err := parseConfig(os.Getenv("OASM_CONFIG"))
    if err != nil {
        return fmt.Errorf("fatal: invalid OASM_CONFIG: %w", err)
    }
    _ = cfg
    // ...
}
```

Use pointers for optional numeric or boolean fields so you can tell "absent" from a zero value, and fall back to the manifest's `default` when a field is nil.

## Environment variables

| Variable | Purpose |
| - | - |
| `INPUT_*` | Per-run input defaults. `INPUT_TARGET` → `inputs["target"]`. |
| `OASM_CONFIG` | The job's config profile as JSON. Read at execution time. |
| `LOG_LEVEL` / `OASM_LOG_LEVEL` | Set to `debug` for verbose traces (per-result lines, emitted-finding previews). INFO and above are always on. |
| `OASM_LOG_COLOR` | `always` forces ANSI colour, `never` strips it. Unset means colour only on a terminal. |

<Info>
  Connection variables (`WORKER_GRPC_ADDR`, `WORKER_TOKEN`, mTLS paths) are injected by the worker and consumed entirely by the SDK. Your adapter never reads or sets them.
</Info>

## Related

<CardGroup cols={2}>
  <Card title="manifest.yaml" icon="file-code" href="/connectors/manifest">
    Declare `inputsSchema` and `configSchema`.
  </Card>

  <Card title="Adapter" icon="plug" href="/connectors/adapter">
    Where inputs and config are consumed.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.