Repository: ory/kratos
Pull request #1082 (2021-02-18 13:00:30)

refactor: move to go 1.16 embed
This patch replaces packr and pkged with the Go 1.16 embed feature.

## Related issue

<!--
Please link the GitHub issue this pull request resolves in the format of `#1234`. If you discussed this change
with a maintainer, please mention her/him using the `@` syntax (e.g. `@aeneasr`).

If this change neither resolves an existing issue nor has sign-off from one of the maintainers, there is a
chance substantial changes will be requested or that the changes will be rejected.

You can discuss changes with maintainers either in the Github Discusssions in this repository or
join the [ORY Chat](https://www.ory.sh/chat).
-->

## Proposed changes

<!--
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
-->

## Checklist

<!--
Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of
them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.
-->

- [ ] I have read the [contributing guidelines](../blob/master/CONTRIBUTING.md).
- [ ] I have read the [security policy](../security/policy).
- [ ] I confirm that this pull request does not address a security
      vulnerability. If this pull request addresses a security. vulnerability, I
      confirm that I got green light (please contact
      [security@ory.sh](mailto:security@ory.sh)) from the maintainers to push
      the changes.
- [ ] I have added tests that prove my fix is effective or that my feature
      works.
- [ ] I have added or changed [the documentation](docs/docs).

## Further comments

<!--
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution
you did and what alternatives you considered, etc...
-->



Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index d26fd5e30..afbf1945f 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,7 +2,7 @@ version: 2.1
 
 orbs:
   changelog: ory/changelog@0.1.4
-  goreleaser: ory/goreleaser@0.1.21
+  goreleaser: ory/goreleaser@0.1.22
   slack: circleci/slack@3.4.2
   sdk: ory/sdk@0.1.40
   docs: ory/docs@0.0.10
@@ -86,6 +86,7 @@ jobs:
       - image: oryd/mailslurper:latest-smtps
     steps:
       - checkout
+      - run: sudo apt-get update && sudo apt-get install -y --no-install-recommends -y psmisc
       # core node_modules cache
       - restore_cache:
           keys:
@@ -165,6 +166,7 @@ workflows:
               only: /.*/
       - sdk/generate:
           appname: Ory_Kratos
+          swagpath: spec/api.json
           requires:
             - test
             - test-e2e-sqlite
@@ -181,6 +183,7 @@ workflows:
           requires:
             - validate
       - docs/build:
+          swag-spec-location: spec/api.json
           requires:
             - validate
           filters:
@@ -189,6 +192,7 @@ workflows:
             branches:
               only: master
       - sdk/release:
+          swagpath: spec/api.json
           requires:
             - test
             - test-e2e-sqlite
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 8d859e8a4..637ee28a6 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -3,12 +3,12 @@
 project_name: kratos
 
 env:
-  - GO111MODULE=on
+  - GOPROXY=https://proxy.golang.org,direct
 
 before:
   hooks:
     - go mod download
-    - make pack
+    - go mod tidy
 
 builds:
   -
@@ -196,10 +196,8 @@ checksum:
 
 dockers:
   - dockerfile: .docker/Dockerfile-sqlite
-    builds:
+    ids:
       - kratos-sqlite-linux-libmusl
-    binaries:
-      - kratos
     image_templates:
       - "oryd/kratos:v{{ .Major }}-sqlite"
       - "oryd/kratos:v{{ .Major }}.{{ .Minor }}-sqlite"
@@ -207,9 +205,7 @@ dockers:
       - "oryd/kratos:{{.Tag}}-sqlite"
       - "oryd/kratos:latest-sqlite"
   - dockerfile: .docker/Dockerfile
-    builds:
-      - kratos
-    binaries:
+    ids:
       - kratos
     image_templates:
       - "oryd/kratos:v{{ .Major }}"
diff --git a/Makefile b/Makefile
index 0b1dbe906..81316ffcf 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,6 @@ export PWD := $(shell pwd)
 
 GO_DEPENDENCIES = github.com/ory/go-acc \
 				  github.com/ory/x/tools/listx \
-				  github.com/markbates/pkger/cmd/pkger \
 				  github.com/golang/mock/mockgen \
 				  github.com/go-swagger/go-swagger/cmd/swagger \
 				  golang.org/x/tools/cmd/goimports \
@@ -68,7 +67,7 @@ mocks: .bin/mockgen
 		mockgen -mock_names Manager=MockLoginExecutorDependencies -package internal -destination internal/hook_login_executor_dependencies.go github.com/ory/kratos/selfservice loginExecutorDependencies
 
 .PHONY: install
-install: pack
+install:
 		GO111MODULE=on go install -tags sqlite .
 
 .PHONY: test-resetdb
@@ -87,14 +86,14 @@ test-coverage: .bin/go-acc .bin/goveralls
 # Generates the SDK
 .PHONY: sdk
 sdk: .bin/swagger .bin/cli
-		swagger generate spec -m -o .schema/api.swagger.json -x internal/httpclient
-		cli dev swagger sanitize ./.schema/api.swagger.json
-		swagger validate ./.schema/api.swagger.json
-		swagger flatten --with-flatten=remove-unused -o ./.schema/api.swagger.json ./.schema/api.swagger.json
-		swagger validate ./.schema/api.swagger.json
+		swagger generate spec -m -o spec/api.json -x internal/httpclient
+		cli dev swagger sanitize ./spec/api.json
+		swagger validate ./spec/api.json
+		swagger flatten --with-flatten=remove-unused -o ./spec/api.json ./spec/api.json
+		swagger validate ./spec/api.json
 		rm -rf internal/httpclient/models/* internal/httpclient/clients/*
 		mkdir -p internal/httpclient/
-		swagger generate client -f ./.schema/api.swagger.json -t internal/httpclient/ -A Ory_Kratos
+		swagger generate client -f ./spec/api.json -t internal/httpclient/ -A Ory_Kratos
 		make format
 
 .PHONY: quickstart
@@ -148,7 +147,3 @@ migrations-render-replace: .bin/cli
 .PHONY: migratest-refresh
 migratest-refresh:
 		cd persistence/sql/migratest; go test -tags sqlite,refresh -short .
-
-.PHONY: pack
-pack: .bin/pkger
-		pkger -exclude node_modules -exclude docs -exclude .git -exclude .github -exclude .bin -exclude test -exclude script -exclude contrib
diff --git a/cmd/daemon/serve.go b/cmd/daemon/serve.go
index 0c95c2ba0..6f9590817 100644
--- a/cmd/daemon/serve.go
+++ b/cmd/daemon/serve.go
@@ -65,6 +65,8 @@ func ServePublic(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
 	defer wg.Done()
 	modifiers := newOptions(opts)
 
+	ctx := cmd.Context()
+
 	c := r.Config(cmd.Context())
 	l := r.Logger()
 	n := negroni.New()
@@ -79,17 +81,17 @@ func ServePublic(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
 	r.WithCSRFHandler(csrf)
 	n.UseHandler(r.CSRFHandler())
 
-	r.RegisterPublicRoutes(router)
+	r.RegisterPublicRoutes(ctx, router)
 	n.Use(reqlog.NewMiddlewareFromLogger(l, "public#"+c.SelfPublicURL().String()))
 	n.Use(sqa(cmd, r))
 	n.Use(r.PrometheusManager())
 
-	if tracer := r.Tracer(cmd.Context()); tracer.IsLoaded() {
+	if tracer := r.Tracer(ctx); tracer.IsLoaded() {
 		n.Use(tracer)
 	}
 
 	var handler http.Handler = n
-	options, enabled := r.Config(cmd.Context()).CORS("public")
+	options, enabled := r.Config(ctx).CORS("public")
 	if enabled {
 		handler = cors.New(options).Handler(handler)
 	}
@@ -109,6 +111,7 @@ func ServePublic(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
 func ServeAdmin(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args []string, opts ...Option) {
 	defer wg.Done()
 	modifiers := newOptions(opts)
+	ctx := cmd.Context()
 
 	c := r.Config(cmd.Context())
 	l := r.Logger()
@@ -118,12 +121,12 @@ func ServeAdmin(r driver.Registry, wg *sync.WaitGroup, cmd *cobra.Command, args
 	}
 
 	router := x.NewRouterAdmin()
-	r.RegisterAdminRoutes(router)
+	r.RegisterAdminRoutes(ctx, router)
 	n.Use(reqlog.NewMiddlewareFromLogger(l, "admin#"+c.SelfPublicURL().String()))
 	n.Use(sqa(cmd, r))
 	n.Use(r.PrometheusManager())
 
-	if tracer := r.Tracer(cmd.Context()); tracer.IsLoaded() {
+	if tracer := r.Tracer(ctx); tracer.IsLoaded() {
 		n.Use(tracer)
 	}
 
diff --git a/cmd/identities/validate.go b/cmd/identities/validate.go
index 4395df87b..3516216ee 100644
--- a/cmd/identities/validate.go
+++ b/cmd/identities/validate.go
@@ -5,11 +5,12 @@ import (
 	"encoding/json"
 	"fmt"
 
+	"github.com/ory/kratos/spec"
+
 	"github.com/ory/x/jsonschemax"
 
 	"github.com/ory/x/cmdx"
 
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 	"github.com/tidwall/gjson"
@@ -49,7 +50,7 @@ Identities can be supplied via STD_IN or JSON files containing a single or an ar
 
 var schemas = make(map[string]*jsonschema.Schema)
 
-const createIdentityPath = "api.swagger.json#/definitions/CreateIdentity"
+const createIdentityPath = "api.json#/definitions/CreateIdentity"
 
 type schemaGetter = func(params *public.GetSchemaParams, opts ...public.ClientOption) (*public.GetSchemaOK, error)
 
@@ -59,15 +60,9 @@ type schemaGetter = func(params *public.GetSchemaParams, opts ...public.ClientOp
 func validateIdentity(cmd *cobra.Command, src, i string, getRemoteSchema schemaGetter) error {
 	swaggerSchema, ok := schemas[createIdentityPath]
 	if !ok {
-		// get swagger schema
-		sf, err := pkger.Open("github.com/ory/kratos:/.schema/api.swagger.json")
-		if err != nil {
-			return errors.Wrap(err, "Could not open swagger schema. This is an error with the binary you use and should be reported. Thanks ;)")
-		}
-
 		// add swagger schema
 		schemaCompiler := jsonschema.NewCompiler()
-		err = schemaCompiler.AddResource("api.swagger.json", sf)
+		err := schemaCompiler.AddResource("api.json", bytes.NewReader(spec.API))
 		if err != nil {
 			return errors.Wrap(err, "Could not add swagger schema to the schema compiler. This is an error with the binary you use and should be reported. Thanks ;)")
 		}
diff --git a/courier/template/templates/recovery/invalid/email.body.gotmpl b/courier/template/courier/builtin/templates/recovery/invalid/email.body.gotmpl
similarity index 100%
rename from courier/template/templates/recovery/invalid/email.body.gotmpl
rename to courier/template/courier/builtin/templates/recovery/invalid/email.body.gotmpl
diff --git a/courier/template/templates/recovery/invalid/email.subject.gotmpl b/courier/template/courier/builtin/templates/recovery/invalid/email.subject.gotmpl
similarity index 100%
rename from courier/template/templates/recovery/invalid/email.subject.gotmpl
rename to courier/template/courier/builtin/templates/recovery/invalid/email.subject.gotmpl
diff --git a/courier/template/templates/recovery/valid/email.body.gotmpl b/courier/template/courier/builtin/templates/recovery/valid/email.body.gotmpl
similarity index 100%
rename from courier/template/templates/recovery/valid/email.body.gotmpl
rename to courier/template/courier/builtin/templates/recovery/valid/email.body.gotmpl
diff --git a/courier/template/templates/recovery/valid/email.subject.gotmpl b/courier/template/courier/builtin/templates/recovery/valid/email.subject.gotmpl
similarity index 100%
rename from courier/template/templates/recovery/valid/email.subject.gotmpl
rename to courier/template/courier/builtin/templates/recovery/valid/email.subject.gotmpl
diff --git a/courier/template/templates/test_stub/email.body.gotmpl b/courier/template/courier/builtin/templates/test_stub/email.body.gotmpl
similarity index 100%
rename from courier/template/templates/test_stub/email.body.gotmpl
rename to courier/template/courier/builtin/templates/test_stub/email.body.gotmpl
diff --git a/courier/template/templates/test_stub/email.subject.gotmpl b/courier/template/courier/builtin/templates/test_stub/email.subject.gotmpl
similarity index 100%
rename from courier/template/templates/test_stub/email.subject.gotmpl
rename to courier/template/courier/builtin/templates/test_stub/email.subject.gotmpl
diff --git a/courier/template/templates/verification/invalid/email.body.gotmpl b/courier/template/courier/builtin/templates/verification/invalid/email.body.gotmpl
similarity index 100%
rename from courier/template/templates/verification/invalid/email.body.gotmpl
rename to courier/template/courier/builtin/templates/verification/invalid/email.body.gotmpl
diff --git a/courier/template/templates/verification/invalid/email.subject.gotmpl b/courier/template/courier/builtin/templates/verification/invalid/email.subject.gotmpl
similarity index 100%
rename from courier/template/templates/verification/invalid/email.subject.gotmpl
rename to courier/template/courier/builtin/templates/verification/invalid/email.subject.gotmpl
diff --git a/courier/template/templates/verification/valid/email.body.gotmpl b/courier/template/courier/builtin/templates/verification/valid/email.body.gotmpl
similarity index 100%
rename from courier/template/templates/verification/valid/email.body.gotmpl
rename to courier/template/courier/builtin/templates/verification/valid/email.body.gotmpl
diff --git a/courier/template/templates/verification/valid/email.subject.gotmpl b/courier/template/courier/builtin/templates/verification/valid/email.subject.gotmpl
similarity index 100%
rename from courier/template/templates/verification/valid/email.subject.gotmpl
rename to courier/template/courier/builtin/templates/verification/valid/email.subject.gotmpl
diff --git a/courier/template/load_template.go b/courier/template/load_template.go
index 1d34cbced..2eb4833c6 100644
--- a/courier/template/load_template.go
+++ b/courier/template/load_template.go
@@ -2,17 +2,20 @@ package template
 
 import (
 	"bytes"
+	"embed"
 	"io"
 	"os"
 	"text/template"
 
+	_ "embed"
+
 	"github.com/Masterminds/sprig/v3"
 	lru "github.com/hashicorp/golang-lru"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 )
 
-var _ = pkger.Dir("github.com/ory/kratos:/courier/template/templates")
+//go:embed courier/builtin/templates/*
+var templates embed.FS
 
 var cache, _ = lru.New(16)
 
@@ -27,7 +30,7 @@ func loadTextTemplate(path string, model interface{}) (string, error) {
 		return tb.String(), nil
 	}
 
-	if file, err := pkger.Open(path); err == nil {
+	if file, err := templates.Open(path); err == nil {
 		defer file.Close()
 		if _, err := io.Copy(&b, file); err != nil {
 			return "", errors.WithStack(err)
diff --git a/docs/config.js b/docs/config.js
index f6dbc11e5..eaecbfc4d 100644
--- a/docs/config.js
+++ b/docs/config.js
@@ -44,7 +44,7 @@ module.exports = {
     }
   ],
   updateConfig: {
-    src: '.schema/config.schema.json',
+    src: './driver/config/.schema/config.schema.json',
     dst: './docs/docs/reference/configuration.md'
   }
 }
diff --git a/docs/docs/concepts/email-sms.md b/docs/docs/concepts/email-sms.md
index a52d4afb3..abb0ebcb6 100644
--- a/docs/docs/concepts/email-sms.md
+++ b/docs/docs/concepts/email-sms.md
@@ -99,7 +99,7 @@ filling E-mail subject and body.
     invalidating a verification
 
 For example:
-[`/courier/template/templates/verification/valid/email.body.gotmpl`](https://github.com/ory/kratos/blob/master/courier/template/templates/verification/valid/email.body.gotmpl)
+[`/courier/template/courier/builtin/templates/verification/valid/email.body.gotmpl`](https://github.com/ory/kratos/blob/master/courier/template/templates/verification/valid/email.body.gotmpl)
 
 ```gotmpl title="courier/template/templates/verification/valid/email.body.gotmpl"
 Hi, please verify your account by clicking the following link:
diff --git a/docs/package.json b/docs/package.json
index 9cb2ac4d9..47c289412 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -9,7 +9,7 @@
   "scripts": {
     "gen": "npm run widdershins && cd .. && node ./docs/scripts/fix-api.js ./docs/docs/reference/api.mdx && node ./docs/scripts/config.js docs/config.js",
     "docusaurus": "docusaurus",
-    "widdershins": "widdershins -u .widdershins/templates -e .widdershins/config.json ../.schema/api.swagger.json -o ./docs/reference/api.mdx",
+    "widdershins": "widdershins -u .widdershins/templates -e .widdershins/config.json ../spec/api.json -o ./docs/reference/api.mdx",
     "start": "docusaurus start",
     "build": "docusaurus build",
     "swizzle": "docusaurus swizzle",
diff --git a/.schema/config.schema.json b/driver/config/.schema/config.schema.json
similarity index 98%
rename from .schema/config.schema.json
rename to driver/config/.schema/config.schema.json
index 67c761180..f6021cf29 100644
--- a/.schema/config.schema.json
+++ b/driver/config/.schema/config.schema.json
@@ -1,5 +1,5 @@
 {
-  "$id": "https://github.com/ory/kratos/.schema/config.schema.json",
+  "$id": "https://github.com/ory/kratos/driver/config/.schema/config.schema.json",
   "$schema": "http://json-schema.org/draft-07/schema#",
   "title": "ORY Kratos Configuration",
   "type": "object",
@@ -9,7 +9,10 @@
       "description": "ORY Kratos redirects to this URL per default on completion of self-service flows and other browser interaction. Read this [article for more information on browser redirects](https://www.ory.sh/kratos/docs/concepts/browser-redirect-flow-completion).",
       "type": "string",
       "format": "uri-reference",
-      "examples": ["https://my-app.com/dashboard", "/dashboard"]
+      "examples": [
+        "https://my-app.com/dashboard",
+        "/dashboard"
+      ]
     },
     "selfServiceSessionRevokerHook": {
       "type": "object",
@@ -1006,10 +1009,14 @@
       }
     },
     "log": {
+      "title": "Log",
+      "description": "Configure logging using the following options. Logging will always be sent to stdout and stderr.",
       "type": "object",
       "properties": {
         "level": {
+          "description": "Debug enables stack traces on errors. Can also be set using environment variable LOG_LEVEL.",
           "type": "string",
+          "default": "info",
           "enum": [
             "trace",
             "debug",
@@ -1026,8 +1033,12 @@
           "description": "If set will leak sensitive values (e.g. emails) in the logs."
         },
         "format": {
+          "description": "The log format can either be text or JSON.",
           "type": "string",
-          "enum": ["json", "text"]
+          "enum": [
+            "json",
+            "text"
+          ]
         }
       },
       "additionalProperties": false
diff --git a/driver/config/config.go b/driver/config/config.go
index ec21ea479..2aa735c4a 100644
--- a/driver/config/config.go
+++ b/driver/config/config.go
@@ -5,7 +5,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"os"
@@ -13,7 +12,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/markbates/pkger"
 	"github.com/rs/cors"
 	"github.com/tidwall/gjson"
 
@@ -152,16 +150,6 @@ func MustNew(l *logrusx.Logger, opts ...configx.OptionModifier) *Config {
 }
 
 func New(l *logrusx.Logger, opts ...configx.OptionModifier) (*Config, error) {
-	f, err := pkger.Open("github.com/ory/kratos:/.schema/config.schema.json")
-	if err != nil {
-		return nil, errors.Wrap(err, "unable to open config.schema.json")
-	}
-
-	schema, err := ioutil.ReadAll(f)
-	if err != nil {
-		return nil, errors.Wrapf(err, "unable to read config.schema.json")
-	}
-
 	opts = append([]configx.OptionModifier{
 		configx.WithStderrValidationReporter(),
 		configx.OmitKeysFromTracing("dsn", "secrets.default", "secrets.cookie", "client_secret"),
@@ -169,7 +157,7 @@ func New(l *logrusx.Logger, opts ...configx.OptionModifier) (*Config, error) {
 		configx.WithLogrusWatcher(l),
 	}, opts...)
 
-	p, err := configx.New(schema, opts...)
+	p, err := configx.New(ValidationSchema, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -559,7 +547,7 @@ func (p *Config) CourierSMTPFrom() string {
 }
 
 func (p *Config) CourierTemplatesRoot() string {
-	return p.p.StringF(ViperKeyCourierTemplatesPath, "/courier/template/templates")
+	return p.p.StringF(ViperKeyCourierTemplatesPath, "courier/builtin/templates")
 }
 
 func splitUrlAndFragment(s string) (string, string) {
diff --git a/driver/config/schema.go b/driver/config/schema.go
new file mode 100644
index 000000000..587ee0eb9
--- /dev/null
+++ b/driver/config/schema.go
@@ -0,0 +1,6 @@
+package config
+
+import _ "embed"
+
+//go:embed .schema/config.schema.json
+var ValidationSchema []byte
diff --git a/driver/registry.go b/driver/registry.go
index a509cc943..dadf48241 100644
--- a/driver/registry.go
+++ b/driver/registry.go
@@ -48,14 +48,14 @@ type Registry interface {
 	WithCSRFHandler(c x.CSRFHandler)
 	WithCSRFTokenGenerator(cg x.CSRFToken)
 
-	HealthHandler() *healthx.Handler
+	HealthHandler(ctx context.Context) *healthx.Handler
 	CookieManager(ctx context.Context) sessions.Store
 	MetricsHandler() *prometheus.Handler
 	ContinuityCookieManager(ctx context.Context) sessions.Store
 
-	RegisterRoutes(public *x.RouterPublic, admin *x.RouterAdmin)
-	RegisterPublicRoutes(public *x.RouterPublic)
-	RegisterAdminRoutes(admin *x.RouterAdmin)
+	RegisterRoutes(ctx context.Context, public *x.RouterPublic, admin *x.RouterAdmin)
+	RegisterPublicRoutes(ctx context.Context, public *x.RouterPublic)
+	RegisterAdminRoutes(ctx context.Context, admin *x.RouterAdmin)
 	PrometheusManager() *prometheus.MetricsManager
 	Tracer(context.Context) *tracing.Tracer
 
diff --git a/driver/registry_default.go b/driver/registry_default.go
index 2df90d25d..8b499a9cf 100644
--- a/driver/registry_default.go
+++ b/driver/registry_default.go
@@ -134,7 +134,7 @@ func (m *RegistryDefault) Audit() *logrusx.Logger {
 	return m.a
 }
 
-func (m *RegistryDefault) RegisterPublicRoutes(router *x.RouterPublic) {
+func (m *RegistryDefault) RegisterPublicRoutes(ctx context.Context, router *x.RouterPublic) {
 	m.LoginHandler().RegisterPublicRoutes(router)
 	m.RegistrationHandler().RegisterPublicRoutes(router)
 	m.LogoutHandler().RegisterPublicRoutes(router)
@@ -152,10 +152,10 @@ func (m *RegistryDefault) RegisterPublicRoutes(router *x.RouterPublic) {
 	m.VerificationHandler().RegisterPublicRoutes(router)
 	m.AllVerificationStrategies().RegisterPublicRoutes(router)
 
-	m.HealthHandler().SetRoutes(router.Router, false)
+	m.HealthHandler(ctx).SetRoutes(router.Router, false)
 }
 
-func (m *RegistryDefault) RegisterAdminRoutes(router *x.RouterAdmin) {
+func (m *RegistryDefault) RegisterAdminRoutes(ctx context.Context, router *x.RouterAdmin) {
 	m.RegistrationHandler().RegisterAdminRoutes(router)
 	m.LoginHandler().RegisterAdminRoutes(router)
 	m.SchemaHandler().RegisterAdminRoutes(router)
@@ -170,13 +170,13 @@ func (m *RegistryDefault) RegisterAdminRoutes(router *x.RouterAdmin) {
 	m.VerificationHandler().RegisterAdminRoutes(router)
 	m.AllVerificationStrategies().RegisterAdminRoutes(router)
 
-	m.HealthHandler().SetRoutes(router.Router, true)
+	m.HealthHandler(ctx).SetRoutes(router.Router, true)
 	m.MetricsHandler().SetRoutes(router.Router)
 }
 
-func (m *RegistryDefault) RegisterRoutes(public *x.RouterPublic, admin *x.RouterAdmin) {
-	m.RegisterAdminRoutes(admin)
-	m.RegisterPublicRoutes(public)
+func (m *RegistryDefault) RegisterRoutes(ctx context.Context, public *x.RouterPublic, admin *x.RouterAdmin) {
+	m.RegisterAdminRoutes(ctx, admin)
+	m.RegisterPublicRoutes(ctx, public)
 }
 
 func NewRegistryDefault() *RegistryDefault {
@@ -195,10 +195,26 @@ func (m *RegistryDefault) LogoutHandler() *logout.Handler {
 	return m.selfserviceLogoutHandler
 }
 
-func (m *RegistryDefault) HealthHandler() *healthx.Handler {
+func (m *RegistryDefault) HealthHandler(_ context.Context) *healthx.Handler {
 	if m.healthxHandler == nil {
 		m.healthxHandler = healthx.NewHandler(m.Writer(), config.Version,
-			healthx.ReadyCheckers{"database": m.Ping})
+			healthx.ReadyCheckers{
+				"database": func(_ *http.Request) error {
+					return m.Ping()
+				},
+				"migrations": func(r *http.Request) error {
+					status, err := m.Persister().MigrationStatus(r.Context())
+					if err != nil {
+						return err
+					}
+
+					if status.HasPending() {
+						return errors.Errorf("migrations have not yet been fully applied")
+					}
+
+					return nil
+				},
+			})
 	}
 
 	return m.healthxHandler
@@ -476,7 +492,7 @@ func (m *RegistryDefault) Init(ctx context.Context) error {
 				m.Logger().WithError(err).Warnf("Unable to open database, retrying.")
 				return errors.WithStack(err)
 			}
-			p, err := sql.NewPersister(m, c)
+			p, err := sql.NewPersister(ctx, m, c)
 			if err != nil {
 				m.Logger().WithError(err).Warnf("Unable to initialize persister, retrying.")
 				return err
diff --git a/go.mod b/go.mod
index f113197ca..73d81297b 100644
--- a/go.mod
+++ b/go.mod
@@ -2,9 +2,6 @@ module github.com/ory/kratos
 
 go 1.16
 
-// See https://github.com/markbates/pkger/pull/112
-replace github.com/markbates/pkger => github.com/falafeljan/pkger v0.17.1-0.20200722132747-95726f5b9b9b
-
 replace gopkg.in/DataDog/dd-trace-go.v1 => gopkg.in/DataDog/dd-trace-go.v1 v1.27.1-0.20201005154917-54b73b3e126a
 
 // Use the internal httpclient which can be generated in this codebase but mark it as the
@@ -51,7 +48,6 @@ require (
 	github.com/knadh/koanf v0.14.1-0.20201201075439-e0853799f9ec
 	github.com/luna-duclos/instrumentedsql v1.1.3
 	github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4
-	github.com/markbates/pkger v0.17.1
 	github.com/mattn/goveralls v0.0.7
 	github.com/mikefarah/yq v1.15.0
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
@@ -67,14 +63,14 @@ require (
 	github.com/ory/kratos/corp v0.0.0-00010101000000-000000000000
 	github.com/ory/mail/v3 v3.0.0
 	github.com/ory/nosurf v1.2.4
-	github.com/ory/x v0.0.189
+	github.com/ory/x v0.0.193
 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.4.0
 	github.com/prometheus/common v0.9.1
 	github.com/rs/cors v1.6.0
 	github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e
-	github.com/sirupsen/logrus v1.6.0
+	github.com/sirupsen/logrus v1.8.0
 	github.com/slack-go/slack v0.7.4
 	github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7
 	github.com/spf13/pflag v1.0.5
diff --git a/go.sum b/go.sum
index 6e08bd22c..95a4b7f6b 100644
--- a/go.sum
+++ b/go.sum
@@ -201,8 +201,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/falafeljan/pkger v0.17.1-0.20200722132747-95726f5b9b9b h1:6NU5UkilmBq093qzKE/rthGQfa8fElR5va1WaVtevxM=
-github.com/falafeljan/pkger v0.17.1-0.20200722132747-95726f5b9b9b/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
@@ -881,7 +879,6 @@ github.com/knadh/koanf v0.14.1-0.20201201075439-e0853799f9ec/go.mod h1:H5mEFsTeW
 github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -911,6 +908,8 @@ github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQ
 github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4 h1:b8Uu5JfweuhcXIqANFs9dOw5zanFj89GYOGlyys37ds=
 github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4/go.mod h1:YnZVBK+MxEr2sn1rbf4UMqsBd0uKaCOq52UtmbfDKNM=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
@@ -941,6 +940,8 @@ github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsI
 github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
 github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
 github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
+github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno=
+github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
 github.com/markbates/refresh v1.4.10/go.mod h1:NDPHvotuZmTmesXxr95C9bjlw1/0frJwtME2dzcVKhc=
 github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
@@ -1107,8 +1108,9 @@ github.com/ory/x v0.0.127/go.mod h1:FwUujfFuCj5d+xgLn4fGMYPnzriR5bdAIulFXMtnK0M=
 github.com/ory/x v0.0.166/go.mod h1:gT/3K0mSFaPllJgoFrvKYIBYI5W1Nz5RxQTJCGrIwDY=
 github.com/ory/x v0.0.179/go.mod h1:SGETCUk1DgQC30bb7y4hjhkKGQ1x0YOsldrmGmy6MNc=
 github.com/ory/x v0.0.181/go.mod h1:SGETCUk1DgQC30bb7y4hjhkKGQ1x0YOsldrmGmy6MNc=
-github.com/ory/x v0.0.189 h1:Zj+SE3zLPc7Ok8OqZvEZli6D8ZoK2vLbSr+qy+UtLAY=
 github.com/ory/x v0.0.189/go.mod h1:uJK3Re/AF6F3LCNnwqzeU/ftmexCpjqwfdyrDc6PbcM=
+github.com/ory/x v0.0.193 h1:hB947UOSNlHh32BrOn2gY+p9D/VGAzVMnElaCojgaSE=
+github.com/ory/x v0.0.193/go.mod h1:dJUOX7dn3nDp/pBR24DLC7mfp4AT1gxpBs7NP7fCSXc=
 github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -1228,8 +1230,9 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
-github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
+github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
 github.com/slack-go/slack v0.7.4 h1:Z+7CmUDV+ym4lYLA4NNLFIpr3+nDgViHrx8xsuXgrYs=
 github.com/slack-go/slack v0.7.4/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go
index 6cf7cb26f..bcf845525 100644
--- a/persistence/sql/persister.go
+++ b/persistence/sql/persister.go
@@ -2,9 +2,9 @@ package sql
 
 import (
 	"context"
+	"embed"
 
 	"github.com/gobuffalo/pop/v5"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/x/popx"
@@ -18,7 +18,8 @@ import (
 
 var _ persistence.Persister = new(Persister)
 
-var migrations = pkger.Dir("github.com/ory/kratos:/persistence/sql/migrations/sql") // do not remove this!
+//go:embed migrations/sql/*.sql
+var migrations embed.FS
 
 type (
 	persisterDependencies interface {
@@ -26,17 +27,18 @@ type (
 		identity.ValidationProvider
 		x.LoggingProvider
 		config.Provider
+		x.TracingProvider
 	}
 	Persister struct {
 		c        *pop.Connection
-		mb       *popx.MigrationBoxPkger
+		mb       *popx.MigrationBox
 		r        persisterDependencies
 		isSQLite bool
 	}
 )
 
-func NewPersister(r persisterDependencies, c *pop.Connection) (*Persister, error) {
-	m, err := popx.NewMigrationBoxPkger(migrations, c, r.Logger())
+func NewPersister(ctx context.Context, r persisterDependencies, c *pop.Connection) (*Persister, error) {
+	m, err := popx.NewMigrationBox(migrations, popx.NewMigrator(c, r.Logger(), r.Tracer(ctx), 0))
 	if err != nil {
 		return nil, err
 	}
@@ -66,7 +68,7 @@ func (p *Persister) MigrateUp(ctx context.Context) error {
 }
 
 func (p *Persister) Migrator() *popx.Migrator {
-	return &p.mb.Migrator
+	return p.mb.Migrator
 }
 
 func (p *Persister) Close(ctx context.Context) error {
diff --git a/schema/extension.go b/schema/extension.go
index 9b2429b82..37bcb39b1 100644
--- a/schema/extension.go
+++ b/schema/extension.go
@@ -2,21 +2,19 @@ package schema
 
 import (
 	"bytes"
+	"embed"
 	"encoding/json"
-	"path"
 
-	"github.com/ory/x/pkgerx"
-
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/jsonschema/v3"
 )
 
-var schemas = pkger.Dir("github.com/ory/kratos:/schema/.schema")
+//go:embed .schema/extension/*.json
+var extensionSchemas embed.FS
 
 const (
-	ExtensionRunnerIdentityMetaSchema ExtensionRunnerMetaSchema = "extension/identity.schema.json"
+	ExtensionRunnerIdentityMetaSchema ExtensionRunnerMetaSchema = ".schema/extension/identity.schema.json"
 	extensionName                     string                    = "ory.sh/kratos"
 )
 
@@ -59,7 +57,7 @@ type (
 
 func NewExtensionRunner(meta ExtensionRunnerMetaSchema, runners ...Extension) (*ExtensionRunner, error) {
 	var err error
-	schema, err := pkgerx.Read(pkger.Open(path.Join(string(schemas), string(meta))))
+	schema, err := extensionSchemas.ReadFile(string(meta))
 	if err != nil {
 		return nil, errors.WithStack(err)
 	}
diff --git a/selfservice/strategy/link/schema.go b/selfservice/strategy/link/schema.go
index 09b4c2ed0..6f768a7c8 100644
--- a/selfservice/strategy/link/schema.go
+++ b/selfservice/strategy/link/schema.go
@@ -1,7 +1,8 @@
 package link
 
 import (
-	"github.com/markbates/pkger"
+	_ "embed"
 )
 
-var _ = pkger.Dir("github.com/ory/kratos:/selfservice/strategy/link/.schema")
+//go:embed .schema/email.schema.json
+var emailSchema []byte
diff --git a/selfservice/strategy/link/strategy_recovery.go b/selfservice/strategy/link/strategy_recovery.go
index 1776ff017..391777b21 100644
--- a/selfservice/strategy/link/strategy_recovery.go
+++ b/selfservice/strategy/link/strategy_recovery.go
@@ -5,11 +5,8 @@ import (
 	"net/url"
 	"time"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/gofrs/uuid"
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/x/decoderx"
@@ -488,12 +485,9 @@ func (s *Strategy) handleRecoveryError(w http.ResponseWriter, r *http.Request, r
 
 func (s *Strategy) decodeRecovery(r *http.Request, decodeBody bool) (*completeSelfServiceRecoveryFlowWithLinkMethodParameters, error) {
 	var body completeSelfServiceRecoveryFlowWithLinkMethod
-
 	if decodeBody {
 		if err := s.dx.Decode(r, &body,
-			decoderx.MustHTTPRawJSONSchemaCompiler(
-				pkgerx.MustRead(pkger.Open("github.com/ory/kratos:/selfservice/strategy/link/.schema/email.schema.json")),
-			),
+			decoderx.MustHTTPRawJSONSchemaCompiler(emailSchema),
 			decoderx.HTTPDecoderSetValidatePayloads(false),
 			decoderx.HTTPDecoderJSONFollowsFormFormat()); err != nil {
 			return nil, err
diff --git a/selfservice/strategy/link/strategy_verification.go b/selfservice/strategy/link/strategy_verification.go
index 0d0a1466a..e388f43a4 100644
--- a/selfservice/strategy/link/strategy_verification.go
+++ b/selfservice/strategy/link/strategy_verification.go
@@ -7,11 +7,8 @@ import (
 
 	"github.com/ory/kratos/selfservice/strategy"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/gofrs/uuid"
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/x/decoderx"
@@ -63,9 +60,7 @@ func (s *Strategy) decodeVerification(r *http.Request, decodeBody bool) (*comple
 
 	if decodeBody {
 		if err := s.dx.Decode(r, &body,
-			decoderx.MustHTTPRawJSONSchemaCompiler(
-				pkgerx.MustRead(pkger.Open("github.com/ory/kratos:/selfservice/strategy/link/.schema/email.schema.json")),
-			),
+			decoderx.MustHTTPRawJSONSchemaCompiler(emailSchema),
 			decoderx.HTTPDecoderSetValidatePayloads(false),
 			decoderx.HTTPDecoderJSONFollowsFormFormat()); err != nil {
 			return nil, err
diff --git a/selfservice/strategy/password/login.go b/selfservice/strategy/password/login.go
index b786be597..2b802bc53 100644
--- a/selfservice/strategy/password/login.go
+++ b/selfservice/strategy/password/login.go
@@ -5,10 +5,7 @@ import (
 	"encoding/json"
 	"net/http"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/x/decoderx"
@@ -111,8 +108,7 @@ func (s *Strategy) handleLogin(w http.ResponseWriter, r *http.Request, _ httprou
 	}
 
 	var p CompleteSelfServiceLoginFlowWithPasswordMethod
-	if err := s.hd.Decode(r, &p, decoderx.MustHTTPRawJSONSchemaCompiler(pkgerx.MustRead(
-		pkger.Open("github.com/ory/kratos:/selfservice/strategy/password/.schema/login.schema.json")))); err != nil {
+	if err := s.hd.Decode(r, &p, decoderx.MustHTTPRawJSONSchemaCompiler(loginSchema)); err != nil {
 		s.handleLoginError(w, r, ar, &p, err)
 		return
 	}
diff --git a/selfservice/strategy/password/registration.go b/selfservice/strategy/password/registration.go
index 285ba03fb..e0d6b0a06 100644
--- a/selfservice/strategy/password/registration.go
+++ b/selfservice/strategy/password/registration.go
@@ -5,10 +5,7 @@ import (
 	"encoding/json"
 	"net/http"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 	"github.com/tidwall/sjson"
 
@@ -80,7 +77,7 @@ func (s *Strategy) handleRegistrationError(w http.ResponseWriter, r *http.Reques
 }
 
 func (s *Strategy) decode(p *RegistrationFormPayload, r *http.Request) error {
-	raw, err := sjson.SetBytes(pkgerx.MustRead(pkger.Open("github.com/ory/kratos:/selfservice/strategy/password/.schema/registration.schema.json")),
+	raw, err := sjson.SetBytes(registrationSchema,
 		"properties.traits.$ref", s.d.Config(r.Context()).DefaultIdentityTraitsSchemaURL().String()+"#/properties/traits")
 	if err != nil {
 		return errors.WithStack(err)
diff --git a/selfservice/strategy/password/schema.go b/selfservice/strategy/password/schema.go
index 5aeee5c35..11ef1165d 100644
--- a/selfservice/strategy/password/schema.go
+++ b/selfservice/strategy/password/schema.go
@@ -1,7 +1,14 @@
 package password
 
 import (
-	"github.com/markbates/pkger"
+	_ "embed"
 )
 
-var _ = pkger.Dir("github.com/ory/kratos:/selfservice/strategy/password/.schema")
+//go:embed .schema/login.schema.json
+var loginSchema []byte
+
+//go:embed .schema/registration.schema.json
+var registrationSchema []byte
+
+//go:embed .schema/settings.schema.json
+var settingsSchema []byte
diff --git a/selfservice/strategy/password/settings.go b/selfservice/strategy/password/settings.go
index ca1f7651a..98728af16 100644
--- a/selfservice/strategy/password/settings.go
+++ b/selfservice/strategy/password/settings.go
@@ -6,11 +6,8 @@ import (
 	"net/url"
 	"time"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/gofrs/uuid"
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 
 	"github.com/ory/herodot"
@@ -143,7 +140,7 @@ func (s *Strategy) submitSettingsFlow(w http.ResponseWriter, r *http.Request, ps
 }
 
 func (s *Strategy) decodeSettingsFlow(r *http.Request, dest interface{}) error {
-	compiler, err := decoderx.HTTPRawJSONSchemaCompiler(pkgerx.MustRead(pkger.Open("github.com/ory/kratos:/selfservice/strategy/password/.schema/settings.schema.json")))
+	compiler, err := decoderx.HTTPRawJSONSchemaCompiler(settingsSchema)
 	if err != nil {
 		return errors.WithStack(err)
 	}
diff --git a/selfservice/strategy/profile/schema.go b/selfservice/strategy/profile/schema.go
index cc2b80748..d31dc8276 100644
--- a/selfservice/strategy/profile/schema.go
+++ b/selfservice/strategy/profile/schema.go
@@ -1,7 +1,8 @@
 package profile
 
 import (
-	"github.com/markbates/pkger"
+	_ "embed"
 )
 
-var _ = pkger.Dir("github.com/ory/kratos:/selfservice/strategy/profile/.schema")
+//go:embed .schema/settings.schema.json
+var settingsSchema []byte
diff --git a/selfservice/strategy/profile/strategy.go b/selfservice/strategy/profile/strategy.go
index 5bf374641..f78b7d77d 100644
--- a/selfservice/strategy/profile/strategy.go
+++ b/selfservice/strategy/profile/strategy.go
@@ -6,11 +6,8 @@ import (
 	"net/http"
 	"net/url"
 
-	"github.com/ory/x/pkgerx"
-
 	"github.com/gofrs/uuid"
 	"github.com/julienschmidt/httprouter"
-	"github.com/markbates/pkger"
 	"github.com/pkg/errors"
 	"github.com/tidwall/sjson"
 
@@ -337,8 +334,7 @@ func (s *Strategy) newSettingsProfileDecoder(ctx context.Context, i *identity.Id
 	if err != nil {
 		return nil, err
 	}
-	raw, err := sjson.SetBytes(pkgerx.MustRead(pkger.Open(
-		"github.com/ory/kratos:/selfservice/strategy/password/.schema/settings.schema.json")),
+	raw, err := sjson.SetBytes(settingsSchema,
 		"properties.traits.$ref", ss.URL.String()+"#/properties/traits")
 	if err != nil {
 		return nil, errors.WithStack(err)
diff --git a/spec/api.go b/spec/api.go
new file mode 100644
index 000000000..27b9cb385
--- /dev/null
+++ b/spec/api.go
@@ -0,0 +1,6 @@
+package spec
+
+import _ "embed"
+
+//go:embed api.json
+var API []byte
diff --git a/x/provider.go b/x/provider.go
index e194b276b..0e666d008 100644
--- a/x/provider.go
+++ b/x/provider.go
@@ -3,6 +3,8 @@ package x
 import (
 	"context"
 
+	"github.com/ory/x/tracing"
+
 	"github.com/gorilla/sessions"
 
 	"github.com/ory/herodot"
@@ -22,3 +24,7 @@ type CookieProvider interface {
 	CookieManager(ctx context.Context) sessions.Store
 	ContinuityCookieManager(ctx context.Context) sessions.Store
 }
+
+type TracingProvider interface {
+	Tracer(ctx context.Context) *tracing.Tracer
+}


Test patch:
diff --git a/courier/template/load_template_test.go b/courier/template/load_template_test.go
index a2003d02c..02135b5e7 100644
--- a/courier/template/load_template_test.go
+++ b/courier/template/load_template_test.go
@@ -21,7 +21,7 @@ func TestLoadTextTemplate(t *testing.T) {
 	}
 
 	t.Run("method=from bundled", func(t *testing.T) {
-		actual := executeTemplate(t, "/courier/template/templates/test_stub/email.body.gotmpl")
+		actual := executeTemplate(t, "courier/builtin/templates/test_stub/email.body.gotmpl")
 		assert.Contains(t, actual, "stub email")
 	})
 
diff --git a/internal/testhelpers/server.go b/internal/testhelpers/server.go
index e22da8401..8037d3965 100644
--- a/internal/testhelpers/server.go
+++ b/internal/testhelpers/server.go
@@ -26,7 +26,7 @@ func NewKratosServerWithCSRF(t *testing.T, reg driver.Registry) (public, admin *
 	reg.Config(context.Background()).MustSet(config.ViperKeyPublicBaseURL, public.URL)
 	reg.Config(context.Background()).MustSet(config.ViperKeyAdminBaseURL, admin.URL)
 
-	reg.RegisterRoutes(rp, ra)
+	reg.RegisterRoutes(context.Background(), rp, ra)
 
 	t.Cleanup(public.Close)
 	t.Cleanup(admin.Close)
@@ -51,7 +51,7 @@ func InitKratosServers(t *testing.T, reg driver.Registry, public, admin *httptes
 	reg.Config(context.Background()).MustSet(config.ViperKeyPublicBaseURL, public.URL)
 	reg.Config(context.Background()).MustSet(config.ViperKeyAdminBaseURL, admin.URL)
 
-	reg.RegisterRoutes(public.Config.Handler.(*x.RouterPublic), admin.Config.Handler.(*x.RouterAdmin))
+	reg.RegisterRoutes(context.Background(), public.Config.Handler.(*x.RouterPublic), admin.Config.Handler.(*x.RouterAdmin))
 }
 
 func NewKratosServers(t *testing.T) (public, admin *httptest.Server) {
diff --git a/persistence/sql/persister_hmac_test.go b/persistence/sql/persister_hmac_test.go
index e87d45dab..9ae239c84 100644
--- a/persistence/sql/persister_hmac_test.go
+++ b/persistence/sql/persister_hmac_test.go
@@ -4,6 +4,8 @@ import (
 	"context"
 	"testing"
 
+	"github.com/ory/x/tracing"
+
 	"github.com/ory/x/configx"
 
 	"github.com/ory/kratos/identity"
@@ -46,6 +48,10 @@ func (l *logRegistryOnly) Audit() *logrusx.Logger {
 	panic("implement me")
 }
 
+func (l *logRegistryOnly) Tracer(ctx context.Context) *tracing.Tracer {
+	return nil
+}
+
 var _ persisterDependencies = &logRegistryOnly{}
 
 func TestPersisterHMAC(t *testing.T) {
@@ -53,7 +59,7 @@ func TestPersisterHMAC(t *testing.T) {
 	conf.MustSet(config.ViperKeySecretsDefault, []string{"foobarbaz"})
 	c, err := pop.NewConnection(&pop.ConnectionDetails{URL: "sqlite://foo?mode=memory"})
 	require.NoError(t, err)
-	p, err := NewPersister(&logRegistryOnly{c: conf}, c)
+	p, err := NewPersister(context.Background(), &logRegistryOnly{c: conf}, c)
 	require.NoError(t, err)
 
 	assert.True(t, p.hmacConstantCompare(context.Background(), "hashme", p.hmacValue(context.Background(), "hashme")))
diff --git a/session/manager_http_test.go b/session/manager_http_test.go
index faf7c3388..0d98852f8 100644
--- a/session/manager_http_test.go
+++ b/session/manager_http_test.go
@@ -80,7 +80,7 @@ func TestManagerHTTP(t *testing.T) {
 		pts := httptest.NewServer(x.NewTestCSRFHandler(rp, reg))
 		t.Cleanup(pts.Close)
 		conf.MustSet(config.ViperKeyPublicBaseURL, pts.URL)
-		reg.RegisterPublicRoutes(rp)
+		reg.RegisterPublicRoutes(context.Background(), rp)
 
 		t.Run("case=valid", func(t *testing.T) {
 			conf.MustSet(config.ViperKeySessionLifespan, "1m")
diff --git a/.schema/api.swagger.json b/spec/api.json
similarity index 100%
rename from .schema/api.swagger.json
rename to spec/api.json
diff --git a/test/e2e/proxy/package-lock.json b/test/e2e/proxy/package-lock.json
index 5f5e5b56d..8619fe5e7 100644
--- a/test/e2e/proxy/package-lock.json
+++ b/test/e2e/proxy/package-lock.json
@@ -331,7 +331,6 @@
       "dependencies": {
         "anymatch": "~3.1.1",
         "braces": "~3.0.2",
-        "fsevents": "~2.1.2",
         "glob-parent": "~5.1.0",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
diff --git a/test/schema/schema_test.go b/test/schema/schema_test.go
index d6ee29f8c..60bba8812 100644
--- a/test/schema/schema_test.go
+++ b/test/schema/schema_test.go
@@ -86,7 +86,7 @@ func (ss *schemas) getByName(n string) (*schema, error) {
 }
 
 func TestSchemas(t *testing.T) {
-	t.Run("test .schema/config.schema.json", SchemaTestRunner("../../.schema", "config"))
+	t.Run("test .schema/config.schema.json", SchemaTestRunner("../../driver/config/.schema", "config"))
 }
 
 func SchemaTestRunner(spath string, sname string) func(*testing.T) {