Skip to content
Open
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
4 changes: 2 additions & 2 deletions .agents/skills/generate-minty-config/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Create or update `.github/minty.yaml`.

**Template for Service Account**:
```yaml
version: 'minty.abcxyz.dev/v1'
version: 'minty.abcxyz.dev/v2'
rule:
if: 'assertion.email == "<EMAIL>"'
scope:
Expand All @@ -65,7 +65,7 @@ scope:

**Template for GitHub Action**:
```yaml
version: 'minty.abcxyz.dev/v1'
version: 'minty.abcxyz.dev/v2'
rule:
if: 'assertion.repository_id == "<REPO_ID>" && assertion.repository_owner_id == "<OWNER_ID>" && assertion.workflow == "<WORKFLOW>" && assertion.ref == "<REF>"'
scope:
Expand Down
27 changes: 23 additions & 4 deletions .agents/skills/validate-minty-config/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: validate-minty-config
description: Validates Minty configuration files using the `tools validate-cfg` command.
description: Validates Minty configuration files using the `tools validate` command.
---
# Validate Minty Configuration

Expand All @@ -11,18 +11,37 @@ This skill provides instructions for validating Minty configuration files using
To validate a configuration file, run:

```bash
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate-cfg --minty-file <path/to/config.yaml>
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate --minty-file <path/to/config.yaml>
```

### Optional Arguments


- `--scope <scope>`: Validate against a specific scope.
- `--token <token_json>`: Validate using a specific token (JSON string).
- `--policy <path>`: Path to a policy file or directory to validate.

> [!NOTE]
> If any required arguments (like the config file path) or optional arguments (like scope or token) are not provided or known from context, **ask the user for them** before running the command.

### Policy Validation

The command can also validate Rego policies.

**Syntax Check Only:**
```bash
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate --policy <path/to/policy.rego>
```
Output on success: `policy compiled`.

**Combined Validation:**
```bash
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate \
--minty-file <path/to/config.yaml> \
--policy <path/to/policy.rego>
```
You can also provide `--token` to simulate the token input for policy evaluation.

### Using Log Entries

If the user provides a server log entry (JSON), extract the following fields:
Expand All @@ -44,7 +63,7 @@ Given a log entry:

Run:
```bash
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate-cfg \
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate \
--minty-file <config> \
--scope "my-scope" \
--token '{"iss": "..."}'
Expand Down Expand Up @@ -73,7 +92,7 @@ If a log entry is provided, you can also fetch the configuration file directly f
### Example

```bash
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate-cfg --minty-file config.yaml --scope "my-scope" --token '{"iss":"..."}'
go run github.com/abcxyz/github-token-minter/cmd/minty@main tools validate --minty-file config.yaml --scope "my-scope" --token '{"iss":"..."}'
```

## Output Interpretation
Expand Down
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,34 @@ GITHUB_REQUEST_MAX_BACKOFF | The maximum backoff duration for GitHub API req
GITHUB_REQUEST_MULTIPLIER | The backoff multiplier for GitHub API requests. Defaults to 2.0.
GITHUB_REQUEST_RETRY_404 | Whether to retry GitHub API requests that return a 404 Not Found status. Defaults to true.
GITHUB_REQUEST_RETRY_422 | Whether to retry GitHub API requests that return a 422 Unprocessable Entity status. Defaults to true.
ENFORCE_READ_ONLY | Whether to enforce read-only permissions for all minted tokens. Defaults to false.
MINTY_POLICY_DIR | The directory containing Rego policies for validation. Defaults to `policy`.

## Policy Validation

Minty supports Rego-based policy validation using the Open Policy Agent (OPA) SDK. This allows service operators to enforce security guardrails at deployment time, independent of individual repository configurations.

Policies are loaded from the directory specified by `MINTY_POLICY_DIR` (defaults to `policy`). All `.rego` files in this directory are evaluated for every token request.

Policies should define rules in the `data.minty.policy` package and add denial messages to the `deny` set. For example:

```rego
package minty.policy

deny contains msg if {
input.config.source != "central"
# ... check for cross-repo access
msg := "cross-repo access only allowed in central config"
}
```

The policy evaluator receives an `input` object containing:
- `config`: The parsed `minty.yaml` configuration.
- `source`: The source type of the configuration (`local`, `repo`, or `central`).
- `repo`: The target repository for the token.
- `org`: The target organization.
- `token`: The OIDC token claims from the caller.

Example policies are provided in the [`policy`](./policy) directory.

### CLI Usage

Expand Down Expand Up @@ -126,17 +152,19 @@ This command starts the GitHub Token Minter server.
| `--github-request-multiplier` | `GITHUB_REQUEST_MULTIPLIER` | The backoff multiplier for GitHub API requests. Defaults to 2.0. |
| `--github-request-retry-404` | `GITHUB_REQUEST_RETRY_404` | Whether to retry GitHub API requests that return a 404 Not Found status. Defaults to true. |
| `--github-request-retry-422` | `GITHUB_REQUEST_RETRY_422` | Whether to retry GitHub API requests that return a 422 Unprocessable Entity status. Defaults to true. |
| `--enforce-read-only` | `ENFORCE_READ_ONLY` | Whether to enforce read-only permissions for all minted tokens. Defaults to false. |
| `--policy-dir` | `MINTY_POLICY_DIR` | The directory containing Rego policies for validation. Defaults to `policy`. |

#### `minty tools validate-cfg`
#### `minty tools validate`

This command validates a minty configuration file.
This command validates a minty configuration file or policy.

| Flag | Environment Variable | Description |
|---|---|---|
| `--minty-file` | `MINTY_FILE` | The minty config file to inspect. |
| `--scope` | `SCOPE` | The scope to test. |
| `--token` | `TOKEN` | The token to test with. |
| `--policy` | `POLICY_PATH` | The path to the policy file or directory to validate. |


#### `minty tools mint`

Expand Down
73 changes: 46 additions & 27 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,69 +1,88 @@
module github.com/abcxyz/github-token-minter

go 1.24

toolchain go1.24.0
go 1.25.0

require (
cloud.google.com/go/kms v1.20.5
github.com/abcxyz/pkg v1.4.0
github.com/google/cel-go v0.23.2
github.com/google/go-cmp v0.6.0
github.com/google/go-cmp v0.7.0
github.com/google/go-github/v64 v64.0.0
github.com/google/tink/go v1.7.0
github.com/lestrrat-go/jwx/v2 v2.1.3
github.com/open-policy-agent/opa v1.15.2
github.com/sethvargo/go-gcpkms v0.3.0
github.com/sethvargo/go-retry v0.3.0
google.golang.org/api v0.221.0
google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b
google.golang.org/grpc v1.70.0
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409
google.golang.org/grpc v1.79.3
gopkg.in/yaml.v3 v3.0.1
)

require (
cel.dev/expr v0.20.0 // indirect
cel.dev/expr v0.25.1 // indirect
cloud.google.com/go v0.118.2 // indirect
cloud.google.com/go/auth v0.14.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
cloud.google.com/go/iam v1.4.0 // indirect
cloud.google.com/go/longrunning v0.6.4 // indirect
github.com/agnivade/levenshtein v1.2.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/blackmagic v1.0.4 // indirect
github.com/lestrrat-go/dsig v1.0.0 // indirect
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.6 // indirect
github.com/lestrrat-go/httprc/v3 v3.0.2 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx/v3 v3.0.13 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/posener/complete/v2 v2.1.0 // indirect
github.com/posener/script v1.2.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
github.com/tchap/go-patricia/v2 v2.3.3 // indirect
github.com/valyala/fastjson v1.6.7 // indirect
github.com/vektah/gqlparser/v2 v2.5.32 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/yashtewari/glob-intersection v0.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
go.opentelemetry.io/otel v1.40.0 // indirect
go.opentelemetry.io/otel/metric v1.40.0 // indirect
go.opentelemetry.io/otel/trace v1.40.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/genproto v0.0.0-20250212204824-5a70512c5d8b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect
google.golang.org/protobuf v1.36.5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
google.golang.org/protobuf v1.36.11 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
Loading
Loading