zitadelgin

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 5 Imported by: 0

README

ZITADEL gin's middleware

Go Reference CI

Gin middleware for ZITADEL. It verifies the bearer token on incoming requests using the ZITADEL authorization SDK, optionally enforces role checks, and exposes the authorization context to your handlers.

Install

go get github.com/panapol-p/zitadel-gin

Usage

package main

import (
	"context"
	"log/slog"
	"os"

	"github.com/gin-gonic/gin"
	zitadelgin "github.com/panapol-p/zitadel-gin"
	"github.com/zitadel/zitadel-go/v3/pkg/authorization"
	"github.com/zitadel/zitadel-go/v3/pkg/authorization/oauth"
	"github.com/zitadel/zitadel-go/v3/pkg/zitadel"
)

func main() {
	ctx := context.Background()

	authZ, err := authorization.New(
		ctx,
		zitadel.New(os.Getenv("ZITADEL_DOMAIN")),
		oauth.DefaultAuthorization(os.Getenv("ZITADEL_KEY_PATH")),
	)
	if err != nil {
		slog.Error("zitadel sdk could not initialize", "error", err)
		os.Exit(1)
	}

	interceptor := zitadelgin.NewZitadelGin(authZ)

	r := gin.Default()

	// Any authenticated caller.
	protected := r.Group("/api/v1")
	protected.Use(interceptor.RequireAuthorization())
	protected.GET("/protected", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "protected route"})
	})

	// Requires the "admin" role.
	admin := r.Group("/api/v1")
	admin.Use(interceptor.RequireAuthorization(authorization.WithRole("admin")))
	admin.GET("/admin", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "admin route"})
	})

	if err := r.Run(); err != nil {
		slog.Error("gin server stopped", "error", err)
		os.Exit(1)
	}
}

A runnable version lives in example/.

API

Symbol Description
NewZitadelGin(authorizer) Creates an Interceptor from a configured *authorization.Authorizer[T].
(*Interceptor).RequireAuthorization(options ...authorization.CheckOption) Returns a gin.HandlerFunc that verifies the request and applies the given checks (e.g. authorization.WithRole("admin")).
(*Interceptor).Context(ctx) Returns the authorization context stored on the request by the middleware.
Responses

On failure the middleware aborts the request with a JSON body {"error": "..."}:

Status When
401 Unauthorized Token is missing, malformed, or invalid.
403 Forbidden Token is valid but lacks a required permission (e.g. role).
500 Internal Server Error Authorization could not be evaluated (e.g. ZITADEL unreachable). The underlying error is not exposed to the caller.
Accessing the authorized user

Inside a protected handler, retrieve the authorization context:

protected.GET("/me", func(c *gin.Context) {
	authCtx := interceptor.Context(c.Request.Context())
	c.JSON(200, gin.H{"user_id": authCtx.UserID()})
})

Configuration

The example reads two environment variables:

Variable Description
ZITADEL_DOMAIN Your ZITADEL instance domain.
ZITADEL_KEY_PATH Path to the API application key JSON file.

See example/.env.example.

License

Released under the MIT License.

Documentation

Overview

Package zitadelgin provides a Gin middleware that authorizes incoming requests using the ZITADEL authorization SDK. It verifies the bearer token found in the request, optionally enforces role checks, and makes the resulting authorization context available to downstream handlers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Interceptor

type Interceptor[T authorization.Ctx] struct {
	// contains filtered or unexported fields
}

Interceptor wraps a ZITADEL authorization.Authorizer and exposes Gin middleware for protecting routes. T is the concrete authorization context type used by the configured authorizer.

func NewZitadelGin

func NewZitadelGin[T authorization.Ctx](authorizer *authorization.Authorizer[T]) *Interceptor[T]

NewZitadelGin returns an Interceptor backed by the given authorizer.

func (*Interceptor[T]) Context

func (i *Interceptor[T]) Context(ctx context.Context) T

Context returns the authorization context stored on ctx by Interceptor.RequireAuthorization. If no authorization context is present the zero value of T is returned.

func (*Interceptor[T]) RequireAuthorization

func (i *Interceptor[T]) RequireAuthorization(options ...authorization.CheckOption) gin.HandlerFunc

RequireAuthorization returns a Gin middleware that verifies the request's authorization header before invoking the next handler. The optional authorization.CheckOption values (for example authorization.WithRole) impose additional requirements such as a granted role.

On success the verified authorization context is stored on the request context and can be retrieved with Interceptor.Context. On failure the request is aborted with an appropriate status code:

  • 401 Unauthorized: the token is missing, malformed, or invalid.
  • 403 Forbidden: the token is valid but lacks a required permission.
  • 500 Internal Server Error: authorization could not be evaluated (for example ZITADEL was unreachable). The underlying error is not exposed to the caller.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL