Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/renovate-tracked-deps.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"packageName": "owenlamont/ryl",
"datasource": "github-tags"
},
"kube-linter": {
"packageName": "stackrox/kube-linter",
"datasource": "github-tags"
},
"biome": {
"packageName": "biomejs/biome",
"datasource": "github-tags"
Expand Down Expand Up @@ -121,6 +125,7 @@
"google-java-format",
"hadolint",
"ktlint",
"kube-linter",
"lychee",
"node",
"npm:renovate",
Expand Down
1 change: 1 addition & 0 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"google-java-format",
"hadolint",
"ktlint",
"kube-linter",
"lychee",
"npm:renovate",
"ruff",
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,11 @@ For Flint contributor workflow and local testing tips, see

### Tooling / CI

| Name | Check |
| -------------- | ------------------------------------------------------------------------------- |
| Dockerfile | [`hadolint`](docs/linters/hadolint.md) |
| GitHub Actions | [`actionlint`](docs/linters/actionlint.md) / [`zizmor`](docs/linters/zizmor.md) |
| Name | Check |
| -------------------- | ------------------------------------------------------------------------------- |
| Dockerfile | [`hadolint`](docs/linters/hadolint.md) |
| GitHub Actions | [`actionlint`](docs/linters/actionlint.md) / [`zizmor`](docs/linters/zizmor.md) |
| Kubernetes manifests | [`kube-linter`](docs/linters/kube-linter.md) |

### General

Expand Down
1 change: 1 addition & 0 deletions default.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"google-java-format",
"hadolint",
"ktlint",
"kube-linter",
"lychee",
"npm:renovate",
"ruff",
Expand Down
9 changes: 5 additions & 4 deletions docs/linters.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ page with its behavior, configuration, and examples.

### Tooling / CI

| Name | Check |
| -------------- | --------------------------------------------------------------------- |
| Dockerfile | [`hadolint`](linters/hadolint.md) |
| GitHub Actions | [`actionlint`](linters/actionlint.md) / [`zizmor`](linters/zizmor.md) |
| Name | Check |
| -------------------- | --------------------------------------------------------------------- |
| Dockerfile | [`hadolint`](linters/hadolint.md) |
| GitHub Actions | [`actionlint`](linters/actionlint.md) / [`zizmor`](linters/zizmor.md) |
| Kubernetes manifests | [`kube-linter`](linters/kube-linter.md) |

### General

Expand Down
93 changes: 93 additions & 0 deletions docs/linters/kube-linter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# `kube-linter`

<!-- linter-metadata-start -->
<!-- Generated. Run `mise run generate` to regenerate. -->

| | |
| -------- | ------------------------------------------------------------------------------------------ |
| Project | [kube-linter](https://github.com/stackrox/kube-linter) |
| Fix | no |
| Binary | `kube-linter` |
| Scope | [native](../linters.md#scope-native) |
| Patterns | `k8s/*.yml k8s/*.yaml kubernetes/*.yml kubernetes/*.yaml manifests/*.yml manifests/*.yaml` |
| Config | [`kube-linter.yaml`](https://docs.kubelinter.io/) |

<!-- linter-metadata-end -->

Flint's `kube-linter` integration checks Kubernetes manifests for security and
production-readiness issues. It is report-only: Flint reports findings but does
not modify manifests.

## Which files are checked?

With no Flint configuration, the check recursively searches these directories
when they exist:

- `k8s/`
- `kubernetes/`
- `manifests/`

Only `.yaml` and `.yml` files are considered. Flint parses each file and selects
it when at least one YAML document has both top-level `apiVersion` and `kind`
keys. It then passes the whole file to KubeLinter. This avoids treating ordinary
YAML, such as a Compose file or an application's settings, as a Kubernetes
manifest.

To use different locations, add files or directories relative to the repository
root:

```toml
# flint.toml
[checks.kube-linter]
paths = ["deploy/kubernetes", "examples/demo.yaml"]
```

Explicit directories are searched recursively. Explicit `paths` replace the
conventional directories rather than extending them. Paths must stay within the
repository: absolute paths, empty paths, and paths containing `..` are ignored.

## Example configuration

This example checks manifests under `deploy/kubernetes/` and uses a
KubeLinter policy stored in Flint's config directory:

```toml
# flint.toml
[checks.kube-linter]
paths = ["deploy/kubernetes"]
config = "kube-linter.yaml"
```

```yaml
# kube-linter.yaml
checks:
addAllBuiltIn: true
exclude:
- unset-cpu-requirements
- unset-memory-requirements
```

`config` is relative to `FLINT_CONFIG_DIR`, which defaults to the repository
root. If `config` is omitted, Flint automatically uses `kube-linter.yaml` from
that directory when it exists. Config paths must stay within
`FLINT_CONFIG_DIR`.

Run the check explicitly while setting it up:

```bash
flint run --full kube-linter
```

See the upstream
[KubeLinter configuration guide](https://github.com/stackrox/kube-linter/blob/main/docs/configuring-kubelinter.md)
for built-in checks, per-object exclusions, and custom checks.

## Manifest selection details

- Multi-document YAML is selected when any document has `apiVersion` and
`kind`; KubeLinter receives the complete file.
- YAML files without those keys are skipped.
- Symlinks are not traversed.
- Missing configured paths produce a clean no-op.
- Helm and Kustomize rendering is not performed by Flint. Render those inputs
separately when generated manifests need linting.
1 change: 1 addition & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ golangci-lint = "2.12.2"
google-java-format = "1.35.0"
hadolint = "2.14.0"
ktlint = "1.8.0"
kube-linter = "0.8.3"
lychee = "0.24.2"
# @yarnpkg/libzip 3.2.2 is npm-signed and matches Yarn's release commit, but
# was published without provenance; mise's no-downgrade policy otherwise rejects Renovate.
Expand Down
17 changes: 17 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl Default for Settings {
#[serde(default)]
pub struct ChecksConfig {
pub lychee: LycheeConfig,
#[serde(rename = "kube-linter", alias = "kube_linter")]
pub kube_linter: KubeLinterConfig,
// The alias allows the underscore form used in env var keys alongside the
// hyphenated form used in flint.toml.
#[serde(rename = "renovate-deps", alias = "renovate_deps")]
Expand All @@ -44,6 +46,21 @@ pub struct ChecksConfig {
pub license_header: LicenseHeaderConfig,
}

/// Configuration for the report-only Kubernetes manifest check.
///
/// When `paths` is empty, Flint considers only conventional Kubernetes
/// directories that exist in the project. It deliberately does not discover
/// YAML files from the repository at large, which keeps Compose and unrelated
/// YAML out of kube-linter's input set.
#[derive(Debug, Default, Deserialize, Clone)]
#[serde(default)]
pub struct KubeLinterConfig {
/// Files or directories to inspect, relative to the project root.
pub paths: Vec<String>,
/// Optional kube-linter config filename, relative to `FLINT_CONFIG_DIR`.
pub config: Option<String>,
}

#[derive(Debug, Default, Deserialize, Clone)]
#[serde(default)]
pub struct LycheeConfig {
Expand Down
Loading
Loading