Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VAULT 11 - Proxy Ollama Requests For Authentication #13

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
48 changes: 48 additions & 0 deletions .github/workflows/cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Create and publish Vault Proxy Docker image

on:
push:
branches:
- main
tags:
- "v*"
paths:
- ".github/workflows/cd.yaml"
- "proxy/**"

workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Fetch tags for the build
run: |
git fetch --prune --unshallow --tags

- name: Set up Docker Build
uses: docker/setup-buildx-action@v3

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
run: |
cd proxy
make latest
43 changes: 43 additions & 0 deletions .github/workflows/proxy-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Continuous Integration

on:
pull_request:
branches:
- main
paths:
- ".github/workflows/cd.yaml"
- "proxy/**"

push:
branches:
- main
paths:
- ".github/workflows/cd.yaml"
- "proxy/**"

workflow_dispatch:

jobs:
lint-and-build: # Linting and building are combined to save time for setting up Go
name: Lint and Build
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: 1.23.x
cache-dependency-path: "go.sum"

- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
working-directory: proxy
version: v1.60.1

- name: Build proxy
run: |
cd proxy && make all
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ cloud-init/meta-data

# Traefik files
acme.json

# Proxy Build
proxy/build
11 changes: 10 additions & 1 deletion docker-compose/.env
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ MG_SPICEDB_DB_PORT=5432
### SpiceDB config
MG_SPICEDB_PRE_SHARED_KEY="yejaTYpqgwqn8ACsnt4qzUso9z5auY"
MG_SPICEDB_SCHEMA_FILE="/schema.zed"
MG_SPICEDB_HOST=magistrala-spicedb
MG_SPICEDB_HOST=spicedb
MG_SPICEDB_PORT=50051
MG_SPICEDB_DATASTORE_ENGINE=postgres

Expand Down Expand Up @@ -142,3 +142,12 @@ MG_GOOGLE_STATE=

# Docker image tag
MG_RELEASE_TAG=latest

# Proxy
UV_VAULT_PROXY_LOG_LEVEL=info
UV_VAULT_PROXY_HOST=0.0.0.0
UV_VAULT_PROXY_PORT=8900
UV_VAULT_PROXY_SERVER_CERT=
UV_VAULT_PROXY_SERVER_KEY=
UV_VAULT_PROXY_TARGET_URL=http://ollama:11434
UV_VAULT_PROXY_INSTANCE_ID=
2 changes: 2 additions & 0 deletions docker-compose/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ include:
env_file: .env
- path: ./magistrala-compose.yaml
env_file: .env
- path: ./proxy-compose.yaml
env_file: .env

services:
traefik:
Expand Down
42 changes: 42 additions & 0 deletions docker-compose/proxy-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
services:
vault-proxy:
container_name: vault-proxy
image: ghcr.io/ultravioletrs/vault/proxy:latest
restart: on-failure
networks:
- vault-network
depends_on:
- auth
environment:
UV_VAULT_PROXY_LOG_LEVEL: ${UV_VAULT_PROXY_LOG_LEVEL}
UV_VAULT_PROXY_TARGET_URL: ${UV_VAULT_PROXY_TARGET_URL}
UV_VAULT_PROXY_HOST: ${UV_VAULT_PROXY_HOST}
UV_VAULT_PROXY_PORT: ${UV_VAULT_PROXY_PORT}
UV_VAULT_PROXY_SERVER_CERT: ${UV_VAULT_PROXY_SERVER_CERT}
UV_VAULT_PROXY_SERVER_KEY: ${UV_VAULT_PROXY_SERVER_KEY}
MG_AUTH_GRPC_URL: ${MG_AUTH_GRPC_URL}
MG_AUTH_GRPC_TIMEOUT: ${MG_AUTH_GRPC_TIMEOUT}
MG_AUTH_GRPC_CLIENT_CERT: ${MG_AUTH_GRPC_CLIENT_CERT:+/auth-grpc-client.crt}
MG_AUTH_GRPC_CLIENT_KEY: ${MG_AUTH_GRPC_CLIENT_KEY:+/auth-grpc-client.key}
MG_AUTH_GRPC_SERVER_CA_CERTS: ${MG_AUTH_GRPC_SERVER_CA_CERTS:+/auth-grpc-server-ca.crt}
MG_SEND_TELEMETRY: ${MG_SEND_TELEMETRY}
UV_VAULT_PROXY_INSTANCE_ID: ${UV_VAULT_PROXY_INSTANCE_ID}
MG_JAEGER_URL: ${MG_JAEGER_URL}
MG_JAEGER_TRACE_RATIO: ${MG_JAEGER_TRACE_RATIO}
volumes:
# Auth gRPC client certificates
- type: bind
source: ${MG_AUTH_GRPC_CLIENT_CERT:-ssl/certs/dummy/client_cert}
target: /auth-grpc-client${MG_AUTH_GRPC_CLIENT_CERT:+.crt}
bind:
create_host_path: true
- type: bind
source: ${MG_AUTH_GRPC_CLIENT_KEY:-ssl/certs/dummy/client_key}
target: /auth-grpc-client${MG_AUTH_GRPC_CLIENT_KEY:+.key}
bind:
create_host_path: true
- type: bind
source: ${MG_AUTH_GRPC_SERVER_CA_CERTS:-ssl/certs/dummy/server_ca}
target: /auth-grpc-server-ca${MG_AUTH_GRPC_SERVER_CA_CERTS:+.crt}
bind:
create_host_path: true
4 changes: 4 additions & 0 deletions docker-compose/traefik/dynamic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ http:
stripPrefix:
prefixes:
- "/ollama"
forward-auth-middleware:
forwardAuth:
address: http://vault-proxy:8900

services:
users:
Expand Down Expand Up @@ -107,6 +110,7 @@ http:
service: ollama
middlewares:
- strip-ollama-prefix-middleware
- forward-auth-middleware
- retry-middleware
- headers-middleware
priority: 10
Expand Down
7 changes: 6 additions & 1 deletion docker-compose/traefik/traefik.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ global:
sendAnonymousUsage: false

log:
compress:
compress: true
format: json
level: ERROR

accessLog:
format: json

tracing:
otlp:
http:
endpoint: http://jaeger:4318/v1/traces

api:
dashboard: false # Change to true for development
debug: true
Expand Down
60 changes: 60 additions & 0 deletions proxy/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
VAULT_DOCKER_IMAGE_NAME ?= ghcr.io/ultravioletrs/vault/proxy
CGO_ENABLED ?= 0
GOOS ?= linux
GOARCH ?= amd64
BUILD_DIR = build
TIME=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
VERSION ?= $(shell git describe --abbrev=0 --tags 2>/dev/null || echo 'v0.0.0')
COMMIT ?= $(shell git rev-parse HEAD)

define compile_service
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) \
go build -ldflags "-s -w \
-X 'github.com/absmach/magistrala.BuildTime=$(TIME)' \
-X 'github.com/absmach/magistrala.Version=$(VERSION)' \
-X 'github.com/absmach/magistrala.Commit=$(COMMIT)'" \
-o ${BUILD_DIR}/vault-proxy cmd/main.go
endef

define make_docker
docker build \
--no-cache \
--build-arg GOOS=$(GOOS) \
--build-arg GOARCH=$(GOARCH) \
--tag=$(VAULT_DOCKER_IMAGE_NAME):$(VERSION) \
--tag=$(VAULT_DOCKER_IMAGE_NAME):latest \
-f docker/Dockerfile .
endef

define make_docker_dev
docker build \
--no-cache \
--tag=$(VAULT_DOCKER_IMAGE_NAME):$(VERSION) \
--tag=$(VAULT_DOCKER_IMAGE_NAME):latest \
-f docker/Dockerfile.dev ./build
endef

define docker_push
docker push $(VAULT_DOCKER_IMAGE_NAME):$(VERSION)
docker push $(VAULT_DOCKER_IMAGE_NAME):latest
endef

.PHONY: build
build:
$(call compile_service)

.PHONY: docker
docker:
$(call make_docker)

.PHONY: docker-dev
docker-dev:
$(call make_docker_dev)

all: build docker-dev

clean:
rm -rf build

latest: docker
$(call docker_push)
25 changes: 25 additions & 0 deletions proxy/api/endpoint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package api

import (
"context"

"github.com/absmach/magistrala/pkg/apiutil"
"github.com/absmach/magistrala/pkg/errors"
"github.com/go-kit/kit/endpoint"
proxy "github.com/ultraviolet/vault-proxy"
)

func identifyEndpoint(svc proxy.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(identifyRequest)
if err := req.Validate(); err != nil {
return identifyResponse{identified: false}, errors.Wrap(apiutil.ErrValidation, err)
}

if err := svc.Identify(ctx, req.Token); err != nil {
return identifyResponse{identified: false}, err
}

return identifyResponse{identified: true}, nil
}
}
15 changes: 15 additions & 0 deletions proxy/api/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package api

import "github.com/absmach/magistrala/pkg/apiutil"

type identifyRequest struct {
Token string `json:"token"`
}

func (i *identifyRequest) Validate() error {
if i.Token == "" {
return apiutil.ErrBearerToken
}

return nil
}
29 changes: 29 additions & 0 deletions proxy/api/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package api

import (
"net/http"

"github.com/absmach/magistrala"
)

var _ magistrala.Response = (*identifyResponse)(nil)

type identifyResponse struct {
identified bool
}

func (i *identifyResponse) Code() int {
if i.identified {
return http.StatusOK
}

return http.StatusUnauthorized
}

func (i *identifyResponse) Headers() map[string]string {
return map[string]string{}
}

func (i identifyResponse) Empty() bool {
return true
}
Loading
Loading