dilion

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

README

Dilion

한국어 · English

Dilion은 Go와 PostgreSQL로 만든 인증·개인정보 관리 서버입니다. Supabase Auth 호환 API로 회원가입과 로그인을 처리하고, 같은 사용자 ID를 기준으로 개인정보 보관, 동의 이력, 회원 탈퇴에 따른 삭제 작업을 관리합니다.

개인정보는 Vault에 암호화해 저장하고, 조회 권한에 따라 마스킹하거나 원문을 제공합니다. 동의와 철회는 이력으로 남기며, 삭제 요청은 유예 기간을 거쳐 비동기 작업으로 처리합니다. 외부 시스템의 삭제 처리는 커넥터로 연결할 수 있습니다. API 호출 예시와 처리 제약은 사용 사례에 정리되어 있습니다.

서버를 독립 프로세스로 실행하거나 dilion.NewServer(...)로 Go 애플리케이션에 넣을 수 있습니다. 메일·SMS, KMS, 훅, 삭제 커넥터는 Go 인터페이스로 교체할 수 있습니다.

로컬 실행

Go 1.26.8 이상, Docker Compose, GNU Make가 필요합니다.

make dev

PostgreSQL을 localhost:55432에 띄우고 마이그레이션을 적용한 뒤, API 서버를 http://localhost:8787에서 실행합니다.

curl http://localhost:8787/healthz

샘플 관리 화면은 다른 터미널에서 실행합니다. Node.js 22 이상이 필요합니다.

make web-install
make dev-web

화면 주소는 http://localhost:5173입니다. 관리 API용 개발 토큰 설정은 web/README.md를 참고하세요. service_role 토큰을 운영 브라우저에 노출하면 안 됩니다.

개발용 PII 암호화 키는 .dev/master.key에 보관됩니다. 이 파일을 잃으면 기존 Vault 데이터를 복호화할 수 없습니다. DB를 보존하며 중지하려면 docker compose stop을 사용하세요. make down은 DB 볼륨도 삭제합니다.

배포 이미지와 패키지

릴리스는 커밋 메시지로 시작합니다. js/packages/auth-js/package.json의 버전을 올리고 제목이 정확히 chore(release): v<버전>인 커밋을 기본 브랜치에 푸시하면, 워크플로가 v<버전> 태그를 만든 뒤 서버 이미지와 JS SDK를 같은 버전으로 함께 발행합니다.

# js/packages/auth-js/package.json 의 version 을 0.1.0-rc1 로 올린 뒤
git commit -am 'chore(release): v0.1.0-rc1'
git push

태그는 릴리스 봇(dilion-release[bot])이 만들며, 그 태그 푸시가 실제 발행 실행을 시작합니다. 따라서 릴리스 하나는 워크플로 실행 두 번으로 나뉩니다 — 커밋 푸시가 태그를 만들고, 태그 푸시가 게이트와 발행을 수행합니다. 발행은 항상 태그에서 실행되므로 npm provenance와 이미지 attestation에도 브랜치가 아닌 태그가 기록됩니다.

v* 태그를 직접 푸시해도 같은 릴리스가 실행되며, 이때는 태그 생성 실행만 없습니다. 커밋이 말하는 버전과 package.json 의 버전이 어긋나면 태그도 만들지 않고 아무것도 발행하지 않은 채 실패합니다. 제목이 위 형식과 정확히 일치하지 않는 커밋은 릴리스로 보지 않으며, 릴리스처럼 보이는 경우에만 경고를 남깁니다.

서버 이미지는 GitHub Container Registry에 linux/amd64와 linux/arm64로 올라갑니다.

docker run --rm -p 8787:8787 \
  -e DILION_DSN='postgres://dilion:dilion@host:5432/dilion' \
  ghcr.io/dilion-io/dilion:latest

마이그레이션은 서버가 시작할 때 직접 적용하므로 별도 단계가 필요하지 않습니다. DILION_JWT_SECRET과 DILION_MASTER_KEY를 주지 않으면 부팅마다 임시 키를 만들므로 운영에서는 반드시 지정해야 합니다. 재시작하면 발급한 토큰이 무효가 되고 저장된 개인정보를 복호화할 수 없습니다. 환경 변수 전체 목록은 cmd/dilion/main.go의 주석에 있습니다.

같은 이미지를 로컬에서 빌드하려면 make docker-build를 사용합니다.

JS SDK는 npm에 발행됩니다.

npm install @dilion-io/auth-js

사전 릴리스(v0.1.0-rc1 등)는 npm next 태그로만 올라가고 이미지의 latest도 갱신하지 않습니다.

인증과 SDK

인증 API의 기본 경로는 /auth/v1입니다. 이메일·비밀번호, OTP, OAuth/OIDC, Passkey, MFA, SAML SSO를 구현하며, 외부 제공자를 사용하는 방식은 별도 설정이 필요합니다. 개인정보 API는 /privacy/v1, 역할·권한·API 키 관리는 /iam/v1에서 제공합니다.

일반 인증에는 @supabase/supabase-js를 사용할 수 있습니다. OPAQUE를 사용하려면 저장소의 @dilion-io/auth-js를 사용하세요. 이 SDK는 Supabase 라이브러리를 의존성으로 가져오고, 기존 클라이언트에 auth.opaque를 추가합니다. 기존 auth.signUp()이나 auth.signInWithPassword()의 동작은 바꾸지 않습니다. 빌드 방법은 js/README.md에 있습니다.

OPAQUE 회원가입과 로그인

OPAQUE는 비밀번호를 서버에 보내지 않고 가입·로그인하는 인증 방식입니다. 서버에 DILION_AUTH_OPAQUE_MASTER_KEY를 설정하면 활성화됩니다. 값은 무작위 32바이트를 패딩 없는 base64url로 인코딩한 문자열이어야 합니다. 이 키는 PII 암호화 키와 별개이며, 재시작 후에도 유지하고 모든 서버 복제본에서 동일하게 사용해야 합니다. 명시적으로 끄려면 DILION_AUTH_OPAQUE_ENABLED=false를 설정하세요.

import { createClient } from '@dilion-io/auth-js'

const client = createClient('https://auth.example.com', 'your-anon-key')

const signup = await client.auth.opaque.signUp({
  email: 'user@example.com',
  password: 'user-supplied-password',
})
if (signup.error) throw signup.error

신규 가입에는 기존 로그인 세션이 필요하지 않으며, 서버에 일반 비밀번호 해시를 만들지 않습니다. 가입 응답의 session은 null입니다. confirmation_required가 true이면 이메일 확인을 마친 뒤 로그인합니다.

const login = await client.auth.opaque.signInWithPassword({
  email: 'user@example.com',
  password: 'user-supplied-password',
})
if (login.error) throw login.error

const { session, key_id, session_key, export_key } = login.data

session_key는 클라이언트와 서버가 각각 도출하는 공유 키입니다. 서버에서는 Server.WithOpaqueSessionKey(...)로 사용할 수 있습니다. export_key는 클라이언트만 보유하며, 두 키 모두 JWT나 SDK 세션 저장소에 넣지 않습니다. 가입 시 받은 export_key는 로그인 성공 전까지 데이터 암호화에 사용하면 안 됩니다.

기존 계정의 OPAQUE 등록, CAPTCHA, 키 파생·만료, 비밀번호 복구 제약은 OPAQUE 문서를 참고하세요. 이 구현과 암호 라이브러리는 독립 보안 감사를 받지 않았습니다.

호환 범위

Supabase Auth의 HTTP API와 auth.* 스키마 호환을 목표로 하지만, 모든 API가 완전히 호환되는 것은 아닙니다.

Parity 테스트는 실제 GoTrue와 응답을 비교합니다. GitHub Actions 실행 summary에는 테스트 결과로 생성한 지원표가 표시되며, 각 항목을 구현됨·부분 호환·미구현·미검증으로 구분합니다. 의도적인 차이는 deviations.yaml에 기록합니다. SDK와 최신 Supabase·TypeScript의 호환성은 매일 별도 workflow로 검사합니다.

개발

make test       # 빌드, 정적 검사, DB 없는 테스트
make test-db    # PostgreSQL 통합 테스트와 race 검사
make ci         # DB 테스트, OpenAPI 검사, 웹 빌드·검사
make parity     # GoTrue 비교 테스트

테스트는 전용 DB의 데이터를 초기화합니다. 운영 DB를 테스트에 연결하지 마세요. CI에서는 별도 job으로 govulncheck도 실행합니다.

한국어 README가 원본입니다. 수정 후 다음 스크립트로 영어 README를 생성합니다. Node.js 22 이상과 인증된 Claude Code CLI가 필요합니다.

node scripts/translate-readme.mjs

스크립트는 claude -p를 호출합니다. GitHub Actions도 같은 스크립트를 사용합니다. CLI 설치와 workflow secret 설정은 README 번역 자동화를 참고하세요.

문서

  • 사용 사례: 동의 수집, 개인정보 조회, 삭제 요청의 API 예시와 제약
  • OPAQUE: 서버 설정, 인증 흐름, 키 관리
  • SDK: Supabase 클라이언트 연결과 OPAQUE API
  • API 규약: API 변경과 OpenAPI 생성 절차
  • 설계 · 개발 계획: 설계 배경과 구현 계획

make dev의 고정 JWT 비밀과 삭제 유예 0일 정책은 로컬 개발용입니다. 운영 환경에서는 TLS, 영속 키, DB 백업, 메일·SMS 제공자와 접근 권한을 별도로 구성해야 합니다.

라이선스

Apache License 2.0

Documentation

Overview

Package dilion assembles the Dilion server: an embeddable, Supabase Auth compatible authentication engine with a built-in privacy/compliance plane.

Everything replaceable is injected through functional options (project.md §2.4). With no options beyond a database, every component falls back to a working default:

srv, err := dilion.NewServer(dilion.WithDSN(os.Getenv("DILION_DSN")))
if err != nil { ... }
if err := srv.Migrate(ctx); err != nil { ... }
log.Fatal(srv.Start(ctx))

API surfaces mounted by Handler:

/auth/v1/*      Supabase Auth compatible (chi, hand-written JSON contract)
/privacy/v1/*   compliance API (huma, OpenAPI 3.1 generated)
/iam/v1/*       management-plane RBAC API (huma)
/healthz        liveness; /readyz database readiness

Multiple database instances

A Dilion "instance" is a whole isolated database (auth.* + dilion_*). The built-in daemon runs exactly one. Embedders that need several inject a ports.InstanceResolver and select the instance per request themselves — Dilion ships no routing rule. Tokens are bound to their instance by key material: the resolver hands every instance its own JWT keys, so a token of one instance is rejected by every other (and by any PostgREST or resource server that trusts the other's JWKS):

srv, _ := dilion.NewServer(dilion.WithInstanceResolver(myResolver))
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	id := myTenantLookup(r) // subdomain, header, session, ...
	r = r.WithContext(ports.ContextWithInstance(r.Context(), id))
	srv.Handler().ServeHTTP(w, r)
})

Migrate then migrates every instance the resolver lists, and Start runs the compliance workers per instance.

Index

Constants

View Source
const (
	BeforeSignup      = ports.BeforeSignup
	AfterSignup       = ports.AfterSignup
	TokenClaims       = ports.TokenClaims
	BeforeUserDelete  = ports.BeforeUserDelete
	AfterUserDelete   = ports.AfterUserDelete
	BeforeErasureStep = ports.BeforeErasureStep
	AfterErasure      = ports.AfterErasure
	ConsentChanged    = ports.ConsentChanged
	ConsentReconfirm  = ports.ConsentReconfirm
	AuthHookSetting   = ports.AuthHookSetting
	PIIReveal         = ports.PIIReveal
)
View Source
const DefaultAddr = ":8787"

DefaultAddr is the listen address used when WithAddr is not given.

View Source
const LocalKMSKeySize = kmslocal.KeySize

LocalKMSKeySize is the key-encryption-key length NewLocalKMS requires, in bytes.

View Source
const Version = "0.1.0"

Version is reported in the generated OpenAPI document.

Variables

This section is empty.

Functions

func NewLocalKMS added in v0.0.5

func NewLocalKMS(pool *pgxpool.Pool, kek []byte) (ports.KMS, error)

NewLocalKMS builds the default ports.KMS over one database: AES-256-GCM envelope encryption with a data key per (subject, scope) stored in dilion_pii.subject_keys, wrapped by kek. It is the KMS a server builds for itself from WithMasterKey; this constructor exists so an embedder can build one per instance, for ports.InstanceResolver.KMS, without writing its own.

func (r *myResolver) KMS(ctx context.Context, id string) (ports.KMS, error) {
	return dilion.NewLocalKMS(r.pools[id], r.keks[id])
}

The kek never leaves this process, so the KMS is only as well protected as the host; a deployment with a real key manager should implement ports.KMS against it instead. Instances may share a kek or have their own — each one's data keys live in its own database either way — but a lost kek makes every data key it wrapped unreadable, and replacing it is not a key rotation (see docs/master-key.md).

A nil pool or a kek of the wrong length is reported here rather than on the first encryption, so a misconfigured instance fails where it is built.

Types

type AuthSettings added in v0.0.5

type AuthSettings = ports.AuthSettings

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type AuthSettingsSource added in v0.0.5

type AuthSettingsSource = ports.AuthSettingsSource

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type HookPoint

type HookPoint = ports.HookPoint

Hook points are re-exported so embedders need not import ports directly.

type OAuthClient added in v0.0.5

type OAuthClient = ports.OAuthClient

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type OAuthClientResolver added in v0.0.5

type OAuthClientResolver = ports.OAuthClientResolver

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type OIDCProvider added in v0.0.5

type OIDCProvider = ports.OIDCProvider

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type Option

type Option func(*config)

Option customises the server. Options are applied in order.

func WithAddr

func WithAddr(addr string) Option

WithAddr sets the listen address used by Start (default ":8787").

func WithAuditSink

func WithAuditSink(s ports.AuditSink) Option

WithAuditSink replaces the Postgres audit sink.

func WithAuthConfig

func WithAuthConfig(c *auth.Config) Option

WithAuthConfig pins the /auth/v1 configuration (internal/auth.Config). Without it the configuration is read from the environment with auth.LoadConfig — DILION_AUTH_* first, the upstream GOTRUE_* names as a fallback — and an invalid value fails NewServer.

func WithAuthSettingsSource added in v0.0.5

func WithAuthSettingsSource(fn ports.AuthSettingsSource) Option

WithAuthSettingsSource sets, per instance, the parts of the /auth/v1 configuration that name the instance's application — its site URL and redirect allow list — from embedder code, the way WithProviderSource does for providers. A platform that serves one workspace per instance already knows each workspace's address; fn returns it, and (nil, nil) keeps the server-wide DILION_AUTH_SITE_URL and URI_ALLOW_LIST.

dilion.WithAuthSettingsSource(func(ctx context.Context, instanceID string) (*dilion.AuthSettings, error) {
	ws, err := workspaces.Get(ctx, instanceID)
	if err != nil {
		return nil, err
	}
	return &dilion.AuthSettings{
		SiteURL:      "https://" + ws.Domain,
		URIAllowList: []string{"https://" + ws.Domain + "/**"},
	}, nil
})

func WithAuthorizer

func WithAuthorizer(a ports.Authorizer) Option

WithAuthorizer replaces the built-in management-plane RBAC decision point.

func WithClock

func WithClock(cl ports.Clock) Option

WithClock replaces the time source used by the compliance engine (tests).

func WithConnector

func WithConnector(name string, conn ports.Connector) Option

WithConnector registers an external-system connector under name; privacy destinations of type CONNECTOR reference it by that name (§3.1).

func WithDSN

func WithDSN(dsn string) Option

WithDSN connects a pool from a Postgres connection string. Ignored when WithPool is also given.

func WithHook

func WithHook(p ports.HookPoint, fn ports.HookFunc) Option

WithHook installs a lifecycle hook (§2.4). Hooks run in registration order.

func WithInstanceResolver

func WithInstanceResolver(r ports.InstanceResolver) Option

WithInstanceResolver turns the server multi-instance: every request resolves its database, KMS, JWT keys, policy and PII field definitions from r, keyed by the instance id the embedder puts on the context with ports.ContextWithInstance (typically in its own middleware). Dilion provides no HTTP routing — choosing the instance for a request is the embedder's responsibility — but it does bind tokens to instances: each instance signs and verifies with the keys r returns for it, so those keys must differ per instance (a shared key is logged as a warning).

Without this option the server is single-instance: WithPool/WithDSN, WithKMS, the JWT settings of the auth configuration, WithPolicyYAML and WithPIIFieldsYAML are wrapped in a static resolver under ports.DefaultInstanceID and nothing else changes.

A resolver must return stable results per instance id: constructed per-instance objects are cached for the lifetime of the server.

func WithJWTSecret

func WithJWTSecret(secret []byte) Option

WithJWTSecret sets the HS256 signing secret for the compat auth surface. Without it an ephemeral secret is generated and all tokens die on restart.

func WithKMS

func WithKMS(k ports.KMS) Option

WithKMS replaces the default AES-256-GCM local KMS (AWS KMS, Vault, HSM...).

func WithLogger

func WithLogger(l *slog.Logger) Option

WithLogger sets the base slog logger (default slog.Default()). Every component logs through it, and records whose context selects an instance (ports.ContextWithInstance) carry it as the "instance" attribute.

func WithMailer

func WithMailer(m ports.Mailer) Option

WithMailer replaces the dev logging mailer.

func WithMasterKey

func WithMasterKey(key []byte) Option

WithMasterKey sets the 32-byte KEK for the default local KMS. Without it an ephemeral key is generated and stored PII becomes unreadable on restart.

func WithOAuthClientResolver added in v0.0.5

func WithOAuthClientResolver(fn ports.OAuthClientResolver) Option

WithOAuthClientResolver decides the clients of each instance's OAuth 2.1 server in code. Every authorize, token and consent request asks fn first and falls back to auth.oauth_clients only when it returns (nil, nil). A returned client's redirect targets, secret and consent rule come from fn's answer, never from a stored row; a FirstParty client skips the consent screen:

dilion.WithOAuthClientResolver(func(ctx context.Context, instanceID, clientID string) (*dilion.OAuthClient, error) {
	if clientID != workspaceClientID {
		return nil, nil
	}
	return &dilion.OAuthClient{
		ID:           workspaceClientID,
		Name:         "Workspace",
		VerifySecret: func(s string) bool { return subtle.ConstantTimeCompare([]byte(s), secret) == 1 },
		AllowRedirectURI: func(uri string) bool {
			ref, ok := workspaceCallbackRef(uri) // exact https://{ref}.api.example.com/auth/v1/callback
			return ok && workspaces.Exists(ref)
		},
		FirstParty: true,
	}, nil
})

The client id must be a UUID. Such a client is kept out of the admin client API; see internal/auth/oauthserver_code_clients.go for how it satisfies the schema's foreign keys without becoming a stored client.

func WithOutboundNetworks added in v0.0.5

func WithOutboundNetworks(spec string) Option

WithOutboundNetworks lists the private networks that calls to URLs set by instance admins may reach — auth hooks, custom and SSO providers, privacy webhook destinations — in the same format as WithTrustedProxies. By default those calls reach only the public internet. Providers defined in code (WithProviderSource) are not restricted.

func WithPIIFieldsYAML

func WithPIIFieldsYAML(b []byte) Option

WithPIIFieldsYAML pins the PII vault's field definitions:

pii-fields:
  email:     {hint: EMAIL}
  full_name: {hint: NAME}

With definitions in place a profile write may only use the defined keys, its `hint` may be omitted, and a supplied hint must equal the defined one; the stored hint always comes from the definition. Without them (the default) fields stay free-form. Invalid definitions fail NewServer.

func WithPolicyYAML

func WithPolicyYAML(b []byte) Option

WithPolicyYAML supplies compliance policy overrides merged onto the built-in policies (§2.8). Invalid policy data fails NewServer.

func WithPool

func WithPool(p *pgxpool.Pool) Option

WithPool injects an existing pool. The caller keeps ownership: Close does not close a pool it did not create.

func WithPrivacyWorkerIntervals added in v0.0.5

func WithPrivacyWorkerIntervals(poll, retention time.Duration) Option

WithPrivacyWorkerIntervals sets how often every instance's privacy workers poll: poll for the outbox, erasure pipeline, delivery tasks and consent reconfirmation, retention for the retention scanner. Zero keeps a default (privacy.DefaultPollInterval, 30s, and privacy.DefaultRetentionInterval, 1h). Each instance's engine polls on its own in every process, so a short interval multiplies by instances and replicas.

func WithProviderSource added in v0.0.5

func WithProviderSource(src ports.ProviderSource) Option

WithProviderSource defines external OpenID Connect providers in code, per instance. A sign-in through GET /auth/v1/authorize?provider=<name> asks src first — before the built-in providers and before the instance's auth.custom_oauth_providers — and uses the provider it returns; (nil, nil) moves on to those. This is how a platform gives every tenant instance its own registration at a shared IdP without storing it in each tenant database:

dilion.WithProviderSource(func(ctx context.Context, instanceID, name string) (*dilion.OIDCProvider, error) {
	if name != "platform" {
		return nil, nil
	}
	t := tenants.Get(instanceID)
	return &dilion.OIDCProvider{
		Issuer:        "https://platform.example.com/auth/v1",
		ClientID:      t.ClientID,
		ClientSecret:  t.ClientSecret,
		LinkBySubject: true, // the platform's user ids ARE this instance's
	}, nil
})

With RedirectURI left empty the callback is derived from the request — the host the authorize request arrived on — so one definition serves every tenant host. See ports.OIDCProvider for LinkBySubject, which hands the provider authority over every account in the instance.

func WithSMS

func WithSMS(s ports.SMSSender) Option

WithSMS replaces the dev logging SMS sender.

func WithTrustedProxies added in v0.0.5

func WithTrustedProxies(spec string) Option

WithTrustedProxies names the proxies in front of the server whose X-Forwarded-For header is believed: a comma-separated list of IPs and CIDRs, or "*" to believe every hop (the previous behaviour). The header is whatever a client sends, so by default it is ignored and the peer address is the client — which a deployment behind a load balancer must change, or every client will share the balancer's rate limits.

dilion.WithTrustedProxies("10.0.0.0/8, 192.168.0.10")

func WithoutAdminMFA

func WithoutAdminMFA() Option

WithoutAdminMFA disables the MFA requirement on the management plane. Development only — it removes a control required by the security baselines in project.md §8; a warning is logged at startup whenever it is set.

type ProviderSource added in v0.0.5

type ProviderSource = ports.ProviderSource

The identity-federation contracts are re-exported for the same reason; see WithProviderSource and WithOAuthClientResolver.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a fully wired Dilion deployment. It serves one instance by default and any number of them when WithInstanceResolver is given.

func NewServer

func NewServer(opts ...Option) (*Server, error)

NewServer wires the server. It connects the database (unless WithPool was given), fills in defaults for every injectable component, validates the policy data and builds the HTTP surface.

func (*Server) Close

func (s *Server) Close() error

Close releases resources owned by the server (the pool, when NewServer created it). A pool passed with WithPool is left alone.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the HTTP handler, for embedding into an existing server.

func (*Server) Migrate

func (s *Server) Migrate(ctx context.Context) error

Migrate applies pending schema migrations to every instance the resolver lists. Safe to run concurrently with other processes and on every boot: each database's run is serialised by a Postgres advisory lock. Use MigrateInstance to provision a single instance without walking the others.

func (*Server) MigrateInstance added in v0.0.5

func (s *Server) MigrateInstance(ctx context.Context, id string) error

MigrateInstance applies pending schema migrations to ONE instance, which is what provisioning a newly added instance needs: Migrate would otherwise walk every instance the resolver lists just to reach the new one. Safe to run concurrently with other processes and with Migrate itself, because the run is serialised by a Postgres advisory lock on that database.

The instance does not have to appear in List yet — only Pool has to resolve it — so a resolver may publish an instance to List only once its schema is in place. Background workers need no separate step either: Start re-scans the instance list periodically and picks the instance up on its own.

func (*Server) Pool

func (s *Server) Pool() *pgxpool.Pool

Pool exposes the database pool for embedders sharing it with their app. It is the pool given with WithPool/WithDSN and is nil in a deployment configured with WithInstanceResolver alone — use PoolFor there.

func (*Server) PoolFor

func (s *Server) PoolFor(ctx context.Context) (*pgxpool.Pool, error)

PoolFor returns the pool of the instance selected on ctx.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start serves HTTP and runs the compliance background workers until ctx is cancelled, then shuts down gracefully. It returns nil on a clean shutdown.

func (*Server) WithOpaqueSessionKey

func (s *Server) WithOpaqueSessionKey(ctx context.Context, bearer, keyID string, fn func([]byte) error) error

WithOpaqueSessionKey lends the shared OPAQUE key to a short, synchronous operation after checking the bearer, live session, MFA and key lifetime. Select the trusted instance on ctx just as for HTTP requests. fn must not retain the slice, perform network I/O, or recursively update auth state: account/session locks remain held, and the slice is wiped on return.

Directories

Path Synopsis
cmd
dilion command
Command dilion runs the Dilion server: Supabase Auth compatible auth plus the privacy/compliance plane.
Command dilion runs the Dilion server: Supabase Auth compatible auth plus the privacy/compliance plane.
genkey command
Command genkey mints an ES256 (P-256) signing key for the /auth/v1 surface.
Command genkey mints an ES256 (P-256) signing key for the /auth/v1 surface.
openapi command
Command openapi generates web/openapi.yaml from the huma route definitions.
Command openapi generates web/openapi.yaml from the huma route definitions.
Package httpapi implements the API conventions from docs/api-conventions.md: resource IDs, cursor pagination envelope, and problem-details error codes.
Package httpapi implements the API conventions from docs/api-conventions.md: resource IDs, cursor pagination envelope, and problem-details error codes.
internal
api
Package api implements the Dilion management-plane HTTP surface (/privacy/v1 and /iam/v1) with huma v2, following docs/api-conventions.md.
Package api implements the Dilion management-plane HTTP surface (/privacy/v1 and /iam/v1) with huma v2, following docs/api-conventions.md.
audit
Package audit implements the default append-only audit sink (project.md §5).
Package audit implements the default append-only audit sink (project.md §5).
auth
Package auth implements the Supabase Auth (gotrue) compatible surface mounted at /auth/v1 (project.md §2.2, §2.3).
Package auth implements the Supabase Auth (gotrue) compatible surface mounted at /auth/v1 (project.md §2.2, §2.3).
auth/upstreamspec
Package upstreamspec holds Go types generated from the OpenAPI document that github.com/supabase/auth (GoTrue) publishes for its own REST API.
Package upstreamspec holds Go types generated from the OpenAPI document that github.com/supabase/auth (GoTrue) publishes for its own REST API.
devmail
Package devmail provides the development-default ports.Mailer and ports.SMSSender: they deliver nothing and log the message with log/slog.
Package devmail provides the development-default ports.Mailer and ports.SMSSender: they deliver nothing and log the message with log/slog.
hooks
Package hooks implements the hook registry (project.md §2.4).
Package hooks implements the hook registry (project.md §2.4).
iam
Package iam implements the management-plane RBAC of project.md §2.11: flat permission strings bundled into roles, history-preserving role assignments (grant/revoke rows are never deleted — 안전성 확보조치 기준 제5조), scoped API keys, and the default Authorizer.
Package iam implements the management-plane RBAC of project.md §2.11: flat permission strings bundled into roles, history-preserving role assignments (grant/revoke rows are never deleted — 안전성 확보조치 기준 제5조), scoped API keys, and the default Authorizer.
instances
Package instances resolves the per-request Dilion instance.
Package instances resolves the per-request Dilion instance.
kmslocal
Package kmslocal is Dilion's default ports.KMS: AES-256-GCM envelope encryption with per-(subject, scope) data keys stored in dilion_pii.subject_keys, wrapped by a master key held in process memory.
Package kmslocal is Dilion's default ports.KMS: AES-256-GCM envelope encryption with per-(subject, scope) data keys stored in dilion_pii.subject_keys, wrapped by a master key held in process memory.
logctx
Package logctx tags log records with the instance selected on their context.
Package logctx tags log records with the instance selected on their context.
netguard
Package netguard keeps outbound calls to URLs that instance admins configure — webhooks, custom OAuth/OIDC providers, SAML metadata, privacy destinations — off the server's own network, and parses the network lists (trusted proxies, allowed networks) the operator configures.
Package netguard keeps outbound calls to URLs that instance admins configure — webhooks, custom OAuth/OIDC providers, SAML metadata, privacy destinations — off the server's own network, and parses the network lists (trusted proxies, allowed networks) the operator configures.
privacy
Package privacy: engine implementation of the Service contract in service.go.
Package privacy: engine implementation of the Service contract in service.go.
store
Package store owns the Postgres connection pool and the migration runner.
Package store owns the Postgres connection pool and the migration runner.
Package migrations holds Dilion's forward-only SQL migrations as an embedded filesystem.
Package migrations holds Dilion's forward-only SQL migrations as an embedded filesystem.
Package ports defines the shared interfaces (contracts) between Dilion domains and embedder-injectable components.
Package ports defines the shared interfaces (contracts) between Dilion domains and embedder-injectable components.
scripts
check-compliance-policies command
Command check-compliance-policies loads internal/privacy/builtin_policies.yaml the way the server does at startup and exits non-zero if it is rejected.
Command check-compliance-policies loads internal/privacy/builtin_policies.yaml the way the server does at startup and exits non-zero if it is rejected.
test
parity
Package parity is Dilion's differential parity + coverage test harness: it runs the Dilion /auth/v1 surface side-by-side against the real upstream github.com/supabase/auth (GoTrue) and asserts behavioural equivalence, excluding the documented intentional deviations (deviations.yaml).
Package parity is Dilion's differential parity + coverage test harness: it runs the Dilion /auth/v1 surface side-by-side against the real upstream github.com/supabase/auth (GoTrue) and asserts behavioural equivalence, excluding the documented intentional deviations (deviations.yaml).
perf command
Command perf measures how many concurrent requests a running Dilion server sustains, and at what latency, with a given number of accounts in its database.
Command perf measures how many concurrent requests a running Dilion server sustains, and at what latency, with a given number of accounts in its database.

Jump to

Keyboard shortcuts

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