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
51 changes: 51 additions & 0 deletions .github/workflows/ko-build-branch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright The Linux Foundation and each contributor to LFX.
# SPDX-License-Identifier: MIT
---
name: Publish Container Branch

"on":
pull_request:
branches:
- main

permissions:
contents: read

jobs:
publish:
name: Publish Container
if: ${{ github.event.pull_request.head.repo.fork == false }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
with:
version: v0.17.1
- name: Prepare container tag
id: container_tag
env:
HEAD_REF: "${{ github.head_ref }}"
run: |
container_tag=$(echo "$HEAD_REF" | sed 's/[^_0-9a-zA-Z]/-/g' | cut -c -127)
echo tag="$container_tag" >> "$GITHUB_OUTPUT"
- name: Build lfx-access-check for PR
env:
VERSION: ${{ steps.container_tag.outputs.tag }}
GIT_COMMIT: ${{ github.sha }}
run: |
BUILD_TIME=$(date -u '+%Y-%m-%d_%H:%M:%S')
export BUILD_TIME
GIT_COMMIT=${GIT_COMMIT:0:7}
export GIT_COMMIT
ko build github.com/linuxfoundation/lfx-v2-access-check/cmd/lfx-access-check \
-B \
--platform linux/amd64,linux/arm64 \
-t ${{ github.sha }} \
-t ${{ steps.container_tag.outputs.tag }} \
--sbom spdx
6 changes: 3 additions & 3 deletions .github/workflows/ko-build-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ jobs:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod
- uses: ko-build/setup-ko@v0.8
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
with:
version: v0.17.1
- name: Build and publish service image
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ko-build-tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
chart_version: ${{ steps.prepare.outputs.chart_version }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Prepare versions and chart name
id: prepare
Expand All @@ -44,12 +44,12 @@ jobs:
} >> "$GITHUB_OUTPUT"

- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version-file: go.mod

- name: Setup Ko
uses: ko-build/setup-ko@v0.8
uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
with:
version: v0.17.1

Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
image_name: ${{ steps.publish-ghcr.outputs.image_name }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Publish Chart to GHCR
id: publish-ghcr
Expand All @@ -97,12 +97,12 @@ jobs:
registry_password: ${{ secrets.GITHUB_TOKEN }}

- name: Install Cosign
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
with:
cosign-release: "${{ env.COSIGN_VERSION }}"

- name: Login to GitHub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,6 @@ yarn-error.log*

# MegaLinter reports
megalinter-reports/

# Local Helm chart values files
charts/lfx-v2-access-check/values.local.yaml
108 changes: 41 additions & 67 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# LFX v2 Access Check Service
# LFX Access Check Service

## Quick Overview

- **Purpose**: Bulk access checks for resource-action pairs
- **Framework**: Go with GOA v3 (API-first design)
- **Framework**: Go with Goa v3 (API-first design)
- **Authentication**: JWT tokens from Heimdall
- **Message Queue**: NATS for async processing
- **Message Queue**: NATS for async processing; fga-sync evaluates permissions
- **Deployment**: Kubernetes with Helm charts

## Architecture

```
Client → Traefik → Heimdall → Access Check Service → NATS
```text
Client → Traefik → Heimdall → Access Check Service → NATS → fga-sync
```

## Project Structure
Expand All @@ -22,11 +22,11 @@ lfx-v2-access-check/
│ ├── main.go # Application bootstrap
│ └── server.go # HTTP server setup
├── design/ # GOA API design definitions
├── design/ # Goa API design definitions
│ ├── access-svc.go # Service design & endpoints
│ └── types.go # Shared type definitions
├── gen/ # Generated code (GOA)
├── gen/ # Generated code (Goa) — do not edit
│ ├── access_svc/ # Service interfaces
│ └── http/ # HTTP transport layer
Expand All @@ -45,12 +45,16 @@ lfx-v2-access-check/
│ ├── constants/ # Application constants
│ └── log/ # Logging utilities
└── charts/ # Helm deployment charts
```

## Development Setup

### Prerequisites
- Go 1.24.0+
- Docker
- NATS server
- fga-sync (evaluates permissions from NATS messages)
- Heimdall (JWT provider)

### Quick Start
Expand All @@ -69,9 +73,9 @@ Available development and build targets:
**Development:**
```bash
make setup-dev # Install development tools (golangci-lint)
make setup # Setup development environment
make setup # Setup development environment
make deps # Install Go dependencies
make apigen # Generate API code using GOA
make apigen # Generate API code using Goa
make fmt # Format Go code
make vet # Run go vet
make lint # Run golangci-lint
Expand Down Expand Up @@ -100,11 +104,12 @@ make docker-run # Run container locally

**Helm/Kubernetes:**
```bash
make helm-install # Install Helm chart
make helm-upgrade # Upgrade Helm release
make helm-templates # Generate Helm templates
make helm-uninstall # Uninstall Helm release
make helm-lint # Lint Helm chart
make helm-install # Install Helm chart using values.yaml
make helm-install-local # Install Helm chart using values.local.yaml
make helm-templates # Render Helm templates
make helm-templates-local # Render Helm templates using values.local.yaml
make helm-uninstall # Uninstall Helm release
make helm-lint # Lint Helm chart
```

**Utility:**
Expand All @@ -115,40 +120,53 @@ make help # Show all available targets
## API

### Access Check
```

Version is passed as a query parameter (`?v=1`), not in the request body.

```http
POST /access-check?v=1
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

{
"version": "1",
"requests": ["project:123#read", "committee:456#write"]
}
```

Response (results correspond 1:1 with the input `requests` array):

```json
{
"results": ["allow", "deny"]
}
```

### Health Checks
- `GET /livez` - Liveness probe
- `GET /readyz` - Readiness probe

### OpenAPI Spec
Available at `/_access-check/openapi.json`, `openapi.yaml`, `openapi3.json`, `openapi3.yaml`.

## Deployment

### Docker
```bash
make docker-build
docker run -p 8080:8080 -e JWKS_URL=... -e NATS_URL=... lfx-access-check
docker run -p 8080:8080 ghcr.io/linuxfoundation/lfx-v2-access-check/lfx-access-check:latest
```

### Kubernetes
```bash
helm upgrade --install lfx-v2-access-check ./charts/lfx-v2-access-check
make helm-install
```

## Service Architecture

### Core Components

1. **HTTP Server** (`cmd/lfx-access-check/`)
- GOA-based REST API server
- Goa-based REST API server
- JWT authentication middleware
- Request ID tracking
- Structured logging
Expand All @@ -173,15 +191,14 @@ helm upgrade --install lfx-v2-access-check ./charts/lfx-v2-access-check

### Test Structure
- **Unit Tests**: Service layer, infrastructure, configuration, middleware
- **Integration Tests**: API endpoints, NATS integration, JWT authentication
- **Benchmark Tests**: Performance testing for critical paths
- **Integration Tests**: API endpoints with mock dependencies — no external services required

### Running Tests
```bash
# Unit tests
make test

# Integration tests (requires NATS and mock services)
# Integration tests (uses mocks — no external services needed)
go test -v ./test/integration/

# Specific package tests
Expand All @@ -191,54 +208,11 @@ go test ./internal/service/
make test-coverage
```

### Integration Tests
Integration tests are located in `test/integration/` and test the complete API endpoints with real dependencies:

**Test Files:**
### Integration Test Files
- `access_check_test.go` - Tests access check endpoint with JWT validation
- `health_test.go` - Tests health check endpoints (/livez, /readyz)
- `plaintext_test.go` - Tests plaintext response handling
- `mocks.go` - Mock services for testing

**Running Integration Tests:**
```bash
# Run all integration tests
go test -v ./test/integration/

# Run specific test
go test -v ./test/integration/ -run TestAccessCheck

# Run with race detection
go test -v -race ./test/integration/
```

**Prerequisites for Integration Tests:**
- NATS server running (for messaging tests)
- Mock JWT validation service
- Test environment variables configured

## Deployment

### Docker Deployment
```bash
# Build image
make docker-build

# Run container
docker run -p 8080:8080 \
-e JWKS_URL=http://heimdall:4457/.well-known/jwks \
-e NATS_URL=nats://nats:4222 \
linuxfoundation/lfx-access-check:latest
```

### Kubernetes Deployment
```bash
helm upgrade --install lfx-v2-access-check ./charts/lfx-v2-access-check \
--set image.tag=v1.0.0 \
--set config.jwksUrl=http://heimdall:4457/.well-known/jwks \
--set config.natsUrl=nats://nats:4222 \
--namespace lfx
```
- `mocks.go` - Mock auth and messaging repositories

## Security

Expand Down
21 changes: 16 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ DOCKER_TAG := $(VERSION)
HELM_CHART_PATH=./charts/lfx-v2-access-check
HELM_RELEASE_NAME=lfx-v2-access-check
HELM_NAMESPACE=lfx
HELM_VALUES_FILE=$(HELM_CHART_PATH)/values.local.yaml

# Go
GO_VERSION := 1.24.2
Expand Down Expand Up @@ -138,18 +139,28 @@ helm-install: ## Install Helm chart
helm upgrade --install $(HELM_RELEASE_NAME) $(HELM_CHART_PATH) --namespace $(HELM_NAMESPACE) --create-namespace --set image.tag=$(DOCKER_TAG)
@echo "==> Helm chart installed: $(HELM_RELEASE_NAME)"

.PHONY: helm-upgrade
helm-upgrade: ## Upgrade Helm release
@echo "==> Upgrading Helm chart..."
helm upgrade $(HELM_RELEASE_NAME) $(HELM_CHART_PATH) --namespace $(HELM_NAMESPACE) --set image.tag=$(DOCKER_TAG)
@echo "==> Helm chart upgraded: $(HELM_RELEASE_NAME)"
.PHONY: helm-install-local
helm-install-local: ## Install Helm chart with local values file
@echo "==> Installing Helm chart with local values..."
helm upgrade --force --install $(HELM_RELEASE_NAME) $(HELM_CHART_PATH) \
--namespace $(HELM_NAMESPACE) --create-namespace \
--values $(HELM_VALUES_FILE)
@echo "==> Helm chart installed: $(HELM_RELEASE_NAME)"

.PHONY: helm-templates
helm-templates: ## Generate Helm templates
@echo "==> Printing templates for Helm chart..."
helm template $(HELM_RELEASE_NAME) $(HELM_CHART_PATH) --namespace $(HELM_NAMESPACE) --set image.tag=$(DOCKER_TAG)
@echo "==> Templates printed for Helm chart: $(HELM_RELEASE_NAME)"

.PHONY: helm-templates-local
helm-templates-local: ## Generate Helm templates with local values file
@echo "==> Rendering Helm templates with local values..."
helm template $(HELM_RELEASE_NAME) $(HELM_CHART_PATH) \
--namespace $(HELM_NAMESPACE) \
--values $(HELM_VALUES_FILE)
@echo "==> Templates printed for Helm chart: $(HELM_RELEASE_NAME)"

.PHONY: helm-uninstall
helm-uninstall: ## Uninstall Helm release
@echo "==> Uninstalling Helm chart..."
Expand Down
Loading
Loading