diff --git a/api/auth.go b/api/auth.go
index 20b6741ea6ec3715319b1d4e479a4730ba9a8ec5..5d271b8e54b5ecd2c3f14dcd6edd89dbabf9b318 100644
--- a/api/auth.go
+++ b/api/auth.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/sirupsen/logrus"
 	"github.com/turt2live/matrix-media-repo/common"
+	"github.com/turt2live/matrix-media-repo/common/config"
 	"github.com/turt2live/matrix-media-repo/common/rcontext"
 	"github.com/turt2live/matrix-media-repo/matrix"
 	"github.com/turt2live/matrix-media-repo/util"
@@ -28,7 +29,7 @@ func AccessTokenRequiredRoute(next func(r *http.Request, rctx rcontext.RequestCo
 			rctx.Log.Error("Error: no token provided (required)")
 			return &ErrorResponse{common.ErrCodeMissingToken, "no token provided (required)", common.ErrCodeUnknownToken}
 		}
-		if rctx.Config.SharedSecret.Enabled && accessToken == rctx.Config.SharedSecret.Token {
+		if config.Get().SharedSecret.Enabled && accessToken == config.Get().SharedSecret.Token {
 			log := rctx.Log.WithFields(logrus.Fields{"isRepoAdmin": true})
 			log.Info("User authed using shared secret")
 			return callUserNext(next, r, rctx, UserInfo{UserId: "@sharedsecret", AccessToken: accessToken, IsShared: true})
@@ -56,7 +57,7 @@ func AccessTokenOptionalRoute(next func(r *http.Request, rctx rcontext.RequestCo
 		if accessToken == "" {
 			return callUserNext(next, r, rctx, UserInfo{"", "", false})
 		}
-		if rctx.Config.SharedSecret.Enabled && accessToken == rctx.Config.SharedSecret.Token {
+		if config.Get().SharedSecret.Enabled && accessToken == config.Get().SharedSecret.Token {
 			rctx = rctx.LogWithFields(logrus.Fields{"isRepoAdmin": true})
 			rctx.Log.Info("User authed using shared secret")
 			return callUserNext(next, r, rctx, UserInfo{UserId: "@sharedsecret", AccessToken: accessToken, IsShared: true})
@@ -94,9 +95,9 @@ func RepoAdminRoute(next func(r *http.Request, rctx rcontext.RequestContext, use
 	})
 
 	return func(r *http.Request, rctx rcontext.RequestContext) interface{} {
-		if rctx.Config.SharedSecret.Enabled {
+		if config.Get().SharedSecret.Enabled {
 			accessToken := util.GetAccessTokenFromRequest(r)
-			if accessToken == rctx.Config.SharedSecret.Token {
+			if accessToken == config.Get().SharedSecret.Token {
 				rctx = rctx.LogWithFields(logrus.Fields{"isRepoAdmin": true})
 				rctx.Log.Info("User authed using shared secret")
 				return callUserNext(next, r, rctx, UserInfo{UserId: "@sharedsecret", AccessToken: accessToken, IsShared: true})
diff --git a/common/config/config.go b/common/config/access.go
similarity index 90%
rename from common/config/config.go
rename to common/config/access.go
index c5e333c4ee91687f415e73a344f142426c04239d..4afa9fa9a5e40605d0d1291107b6d02e461588d9 100644
--- a/common/config/config.go
+++ b/common/config/access.go
@@ -18,13 +18,14 @@ type runtimeConfig struct {
 }
 
 var Runtime = &runtimeConfig{}
+var Path = "media-repo.yaml"
 
-var instance *MediaRepoConfig
+var instance *MainRepoConfig
 var singletonLock = &sync.Once{}
-var Path = "media-repo.yaml"
+var domains = make(map[string]DomainRepoConfig)
 
-func reloadConfig() (*MediaRepoConfig, error) {
-	c := NewDefaultConfig()
+func reloadConfig() (*MainRepoConfig, error) {
+	c := NewDefaultMainConfig()
 
 	// Write a default config if the one given doesn't exist
 	info, err := os.Stat(Path)
@@ -93,10 +94,10 @@ func reloadConfig() (*MediaRepoConfig, error) {
 		}
 	}
 
-	return c, nil
+	return &c, nil
 }
 
-func Get() *MediaRepoConfig {
+func Get() *MainRepoConfig {
 	if instance == nil {
 		singletonLock.Do(func() {
 			c, err := reloadConfig()
diff --git a/common/config/conf_domain.go b/common/config/conf_domain.go
new file mode 100644
index 0000000000000000000000000000000000000000..45af7772a04004d2582df3423df19222022e68fc
--- /dev/null
+++ b/common/config/conf_domain.go
@@ -0,0 +1,63 @@
+package config
+
+type DomainRepoConfig struct {
+	MinimumRepoConfig `yaml:",inline"`
+	Downloads         DownloadsConfig   `yaml:"downloads"`
+	Thumbnails        ThumbnailsConfig  `yaml:"thumbnails"`
+	UrlPreviews       UrlPreviewsConfig `yaml:"urlPreviews"`
+}
+
+func NewDefaultDomainConfig() DomainRepoConfig {
+	return DomainRepoConfig{
+		MinimumRepoConfig: NewDefaultMinimumRepoConfig(),
+		Downloads: DownloadsConfig{
+			MaxSizeBytes:        104857600, // 100mb
+			FailureCacheMinutes: 15,
+		},
+		UrlPreviews: UrlPreviewsConfig{
+			Enabled:          true,
+			NumWords:         50,
+			NumTitleWords:    30,
+			MaxLength:        200,
+			MaxTitleLength:   150,
+			MaxPageSizeBytes: 10485760, // 10mb
+			FilePreviewTypes: []string{
+				"image/*",
+			},
+			DisallowedNetworks: []string{
+				"127.0.0.1/8",
+				"10.0.0.0/8",
+				"172.16.0.0/12",
+				"192.168.0.0/16",
+				"100.64.0.0/10",
+				"169.254.0.0/16",
+				"::1/128",
+				"fe80::/64",
+				"fc00::/7",
+			},
+			AllowedNetworks: []string{
+				"0.0.0.0/0", // "Everything"
+			},
+		},
+		Thumbnails: ThumbnailsConfig{
+			MaxSourceBytes:      10485760, // 10mb
+			MaxAnimateSizeBytes: 10485760, // 10mb
+			AllowAnimated:       true,
+			DefaultAnimated:     false,
+			StillFrame:          0.5,
+			Sizes: []ThumbnailSize{
+				{32, 32},
+				{96, 96},
+				{320, 240},
+				{640, 480},
+				{800, 600},
+			},
+			Types: []string{
+				"image/jpeg",
+				"image/jpg",
+				"image/png",
+				"image/gif",
+			},
+		},
+	}
+}
diff --git a/common/config/conf_main.go b/common/config/conf_main.go
new file mode 100644
index 0000000000000000000000000000000000000000..2f2e63c6ff6afaa7cf3a122748c36341fd212035
--- /dev/null
+++ b/common/config/conf_main.go
@@ -0,0 +1,119 @@
+package config
+
+type MainRepoConfig struct {
+	MinimumRepoConfig `yaml:",inline"`
+	General           GeneralConfig         `yaml:"repo"`
+	Homeservers       []HomeserverConfig    `yaml:"homeservers,flow"`
+	Admins            []string              `yaml:"admins,flow"`
+	Database          DatabaseConfig        `yaml:"database"`
+	Downloads         MainDownloadsConfig   `yaml:"downloads"`
+	Thumbnails        MainThumbnailsConfig  `yaml:"thumbnails"`
+	UrlPreviews       MainUrlPreviewsConfig `yaml:"urlPreviews"`
+	RateLimit         RateLimitConfig       `yaml:"rateLimit"`
+	Metrics           MetricsConfig         `yaml:"metrics"`
+	SharedSecret      SharedSecretConfig    `yaml:"sharedSecretAuth"`
+}
+
+func NewDefaultMainConfig() MainRepoConfig {
+	return MainRepoConfig{
+		MinimumRepoConfig: NewDefaultMinimumRepoConfig(),
+		General: GeneralConfig{
+			BindAddress:      "127.0.0.1",
+			Port:             8000,
+			LogDirectory:     "logs",
+			TrustAnyForward:  false,
+			UseForwardedHost: true,
+		},
+		Database: DatabaseConfig{
+			Postgres: "postgres://your_username:your_password@localhost/database_name?sslmode=disable",
+			Pool: &DbPoolConfig{
+				MaxConnections: 25,
+				MaxIdle:        5,
+			},
+		},
+		Homeservers: []HomeserverConfig{},
+		Admins:      []string{},
+		Downloads: MainDownloadsConfig{
+			DownloadsConfig: DownloadsConfig{
+				MaxSizeBytes:        104857600, // 100mb
+				FailureCacheMinutes: 15,
+			},
+			NumWorkers: 10,
+			Cache: CacheConfig{
+				Enabled:               true,
+				MaxSizeBytes:          1048576000, // 1gb
+				MaxFileSizeBytes:      104857600,  // 100mb
+				TrackedMinutes:        30,
+				MinDownloads:          5,
+				MinCacheTimeSeconds:   300, // 5min
+				MinEvictedTimeSeconds: 60,
+			},
+		},
+		UrlPreviews: MainUrlPreviewsConfig{
+			UrlPreviewsConfig: UrlPreviewsConfig{
+				Enabled:          true,
+				NumWords:         50,
+				NumTitleWords:    30,
+				MaxLength:        200,
+				MaxTitleLength:   150,
+				MaxPageSizeBytes: 10485760, // 10mb
+				FilePreviewTypes: []string{
+					"image/*",
+				},
+				DisallowedNetworks: []string{
+					"127.0.0.1/8",
+					"10.0.0.0/8",
+					"172.16.0.0/12",
+					"192.168.0.0/16",
+					"100.64.0.0/10",
+					"169.254.0.0/16",
+					"::1/128",
+					"fe80::/64",
+					"fc00::/7",
+				},
+				AllowedNetworks: []string{
+					"0.0.0.0/0", // "Everything"
+				},
+			},
+
+			NumWorkers: 10,
+		},
+		Thumbnails: MainThumbnailsConfig{
+			ThumbnailsConfig: ThumbnailsConfig{
+				MaxSourceBytes:      10485760, // 10mb
+				MaxAnimateSizeBytes: 10485760, // 10mb
+				AllowAnimated:       true,
+				DefaultAnimated:     false,
+				StillFrame:          0.5,
+				Sizes: []ThumbnailSize{
+					{32, 32},
+					{96, 96},
+					{320, 240},
+					{640, 480},
+					{800, 600},
+				},
+				Types: []string{
+					"image/jpeg",
+					"image/jpg",
+					"image/png",
+					"image/gif",
+				},
+			},
+			NumWorkers: 10,
+		},
+		RateLimit: RateLimitConfig{
+			Enabled:           true,
+			RequestsPerSecond: 5,
+			BurstCount:        10,
+		},
+		Metrics: MetricsConfig{
+			Enabled:     false,
+			BindAddress: "localhost",
+			Port:        9000,
+		},
+		SharedSecret: SharedSecretConfig{
+			Enabled: false,
+			Token:   "ReplaceMe",
+		},
+	}
+}
diff --git a/common/config/conf_min_shared.go b/common/config/conf_min_shared.go
new file mode 100644
index 0000000000000000000000000000000000000000..44ef3fcd3a292c834df28ba3b4365422aed8c5e2
--- /dev/null
+++ b/common/config/conf_min_shared.go
@@ -0,0 +1,42 @@
+package config
+
+type MinimumRepoConfig struct {
+	DataStores     []DatastoreConfig `yaml:"datastores"`
+	Archiving      ArchivingConfig   `yaml:"archiving"`
+	Uploads        UploadsConfig     `yaml:"uploads"`
+	Identicons     IdenticonsConfig  `yaml:"identicons"`
+	Quarantine     QuarantineConfig  `yaml:"quarantine"`
+	TimeoutSeconds TimeoutsConfig    `yaml:"timeouts"`
+}
+
+func NewDefaultMinimumRepoConfig() MinimumRepoConfig {
+	return MinimumRepoConfig{
+		DataStores: []DatastoreConfig{},
+		Archiving: ArchivingConfig{
+			Enabled:            true,
+			SelfService:        false,
+			TargetBytesPerPart: 209715200, // 200mb
+		},
+		Uploads: UploadsConfig{
+			MaxSizeBytes:         104857600, // 100mb
+			MinSizeBytes:         100,
+			ReportedMaxSizeBytes: 0,
+			StoragePaths:         []string{},
+			AllowedTypes:         []string{"*/*"},
+		},
+		Identicons: IdenticonsConfig{
+			Enabled: true,
+		},
+		Quarantine: QuarantineConfig{
+			ReplaceThumbnails: true,
+			ReplaceDownloads:  false,
+			ThumbnailPath:     "",
+			AllowLocalAdmins:  true,
+		},
+		TimeoutSeconds: TimeoutsConfig{
+			UrlPreviews:  10,
+			ClientServer: 30,
+			Federation:   120,
+		},
+	}
+}
diff --git a/common/config/defaults.go b/common/config/defaults.go
deleted file mode 100644
index c19345d140647dbc6f63fdd53f4430239b050602..0000000000000000000000000000000000000000
--- a/common/config/defaults.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package config
-
-func NewDefaultConfig() *MediaRepoConfig {
-	return &MediaRepoConfig{
-		General: &GeneralConfig{
-			BindAddress:      "127.0.0.1",
-			Port:             8000,
-			LogDirectory:     "logs",
-			TrustAnyForward:  false,
-			UseForwardedHost: true,
-		},
-		Database: &DatabaseConfig{
-			Postgres: "postgres://your_username:your_password@localhost/database_name?sslmode=disable",
-			Pool: &DbPoolConfig{
-				MaxConnections: 25,
-				MaxIdle:        5,
-			},
-		},
-		Homeservers: []*HomeserverConfig{},
-		Admins:      []string{},
-		DataStores:  []DatastoreConfig{},
-		Archiving: &ArchivingConfig{
-			Enabled:            true,
-			SelfService:        false,
-			TargetBytesPerPart: 209715200, // 200mb
-		},
-		Uploads: &UploadsConfig{
-			MaxSizeBytes:         104857600, // 100mb
-			MinSizeBytes:         100,
-			ReportedMaxSizeBytes: 0,
-			StoragePaths:         []string{},
-			AllowedTypes:         []string{"*/*"},
-		},
-		Downloads: &DownloadsConfig{
-			MaxSizeBytes:        104857600, // 100mb
-			NumWorkers:          10,
-			FailureCacheMinutes: 15,
-			Cache: &CacheConfig{
-				Enabled:               true,
-				MaxSizeBytes:          1048576000, // 1gb
-				MaxFileSizeBytes:      104857600,  // 100mb
-				TrackedMinutes:        30,
-				MinDownloads:          5,
-				MinCacheTimeSeconds:   300, // 5min
-				MinEvictedTimeSeconds: 60,
-			},
-		},
-		UrlPreviews: &UrlPreviewsConfig{
-			Enabled:          true,
-			NumWords:         50,
-			NumTitleWords:    30,
-			MaxLength:        200,
-			MaxTitleLength:   150,
-			MaxPageSizeBytes: 10485760, // 10mb
-			NumWorkers:       10,
-			FilePreviewTypes: []string{
-				"image/*",
-			},
-			DisallowedNetworks: []string{
-				"127.0.0.1/8",
-				"10.0.0.0/8",
-				"172.16.0.0/12",
-				"192.168.0.0/16",
-				"100.64.0.0/10",
-				"169.254.0.0/16",
-				"::1/128",
-				"fe80::/64",
-				"fc00::/7",
-			},
-			AllowedNetworks: []string{
-				"0.0.0.0/0", // "Everything"
-			},
-		},
-		Thumbnails: &ThumbnailsConfig{
-			MaxSourceBytes:      10485760, // 10mb
-			MaxAnimateSizeBytes: 10485760, // 10mb
-			NumWorkers:          10,
-			AllowAnimated:       true,
-			DefaultAnimated:     false,
-			StillFrame:          0.5,
-			Sizes: []*ThumbnailSize{
-				{32, 32},
-				{96, 96},
-				{320, 240},
-				{640, 480},
-				{800, 600},
-			},
-			Types: []string{
-				"image/jpeg",
-				"image/jpg",
-				"image/png",
-				"image/gif",
-			},
-		},
-		RateLimit: &RateLimitConfig{
-			Enabled:           true,
-			RequestsPerSecond: 5,
-			BurstCount:        10,
-		},
-		Identicons: &IdenticonsConfig{
-			Enabled: true,
-		},
-		Quarantine: &QuarantineConfig{
-			ReplaceThumbnails: true,
-			ReplaceDownloads:  false,
-			ThumbnailPath:     "",
-			AllowLocalAdmins:  true,
-		},
-		TimeoutSeconds: &TimeoutsConfig{
-			UrlPreviews:  10,
-			ClientServer: 30,
-			Federation:   120,
-		},
-		Metrics: &MetricsConfig{
-			Enabled:     false,
-			BindAddress: "localhost",
-			Port:        9000,
-		},
-		SharedSecret: &SharedSecretConfig{
-			Enabled: false,
-			Token:   "ReplaceMe",
-		},
-	}
-}
diff --git a/common/config/main_models.go b/common/config/main_models.go
new file mode 100644
index 0000000000000000000000000000000000000000..b71ac90f4ca44b5aec44a3633d3409f3527726a7
--- /dev/null
+++ b/common/config/main_models.go
@@ -0,0 +1,69 @@
+package config
+
+type GeneralConfig struct {
+	BindAddress      string `yaml:"bindAddress"`
+	Port             int    `yaml:"port"`
+	LogDirectory     string `yaml:"logDirectory"`
+	TrustAnyForward  bool   `yaml:"trustAnyForwardedAddress"`
+	UseForwardedHost bool   `yaml:"useForwardedHost"`
+}
+
+type HomeserverConfig struct {
+	Name            string `yaml:"name"`
+	ClientServerApi string `yaml:"csApi"`
+	BackoffAt       int    `yaml:"backoffAt"`
+	AdminApiKind    string `yaml:"adminApiKind"`
+}
+
+type DatabaseConfig struct {
+	Postgres string        `yaml:"postgres"`
+	Pool     *DbPoolConfig `yaml:"pool"`
+}
+
+type DbPoolConfig struct {
+	MaxConnections int `yaml:"maxConnections"`
+	MaxIdle        int `yaml:"maxIdleConnections"`
+}
+
+type MainDownloadsConfig struct {
+	DownloadsConfig `yaml:",inline"`
+	NumWorkers      int         `yaml:"numWorkers"`
+	Cache           CacheConfig `yaml:"cache"`
+}
+
+type CacheConfig struct {
+	Enabled               bool  `yaml:"enabled"`
+	MaxSizeBytes          int64 `yaml:"maxSizeBytes"`
+	MaxFileSizeBytes      int64 `yaml:"maxFileSizeBytes"`
+	TrackedMinutes        int   `yaml:"trackedMinutes"`
+	MinCacheTimeSeconds   int   `yaml:"minCacheTimeSeconds"`
+	MinEvictedTimeSeconds int   `yaml:"minEvictedTimeSeconds"`
+	MinDownloads          int   `yaml:"minDownloads"`
+}
+
+type MainThumbnailsConfig struct {
+	ThumbnailsConfig `yaml:",inline"`
+	NumWorkers       int `yaml:"numWorkers"`
+}
+
+type MainUrlPreviewsConfig struct {
+	UrlPreviewsConfig `yaml:",inline"`
+	NumWorkers        int `yaml:"numWorkers"`
+}
+
+type RateLimitConfig struct {
+	RequestsPerSecond float64 `yaml:"requestsPerSecond"`
+	Enabled           bool    `yaml:"enabled"`
+	BurstCount        int     `yaml:"burst"`
+}
+
+type MetricsConfig struct {
+	Enabled     bool   `yaml:"enabled"`
+	BindAddress string `yaml:"bindAddress"`
+	Port        int    `yaml:"port"`
+}
+
+type SharedSecretConfig struct {
+	Enabled bool   `yaml:"enabled"`
+	Token   string `yaml:"token"`
+}
diff --git a/common/config/models.go b/common/config/models.go
deleted file mode 100644
index 1ed2defa7c84bd5bfbc782877917928aeda6e2ca..0000000000000000000000000000000000000000
--- a/common/config/models.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package config
-
-type HomeserverConfig struct {
-	Name            string `yaml:"name"`
-	ClientServerApi string `yaml:"csApi"`
-	BackoffAt       int    `yaml:"backoffAt"`
-	AdminApiKind    string `yaml:"adminApiKind"`
-}
-
-type GeneralConfig struct {
-	BindAddress      string `yaml:"bindAddress"`
-	Port             int    `yaml:"port"`
-	LogDirectory     string `yaml:"logDirectory"`
-	TrustAnyForward  bool   `yaml:"trustAnyForwardedAddress"`
-	UseForwardedHost bool   `yaml:"useForwardedHost"`
-}
-
-type DbPoolConfig struct {
-	MaxConnections int `yaml:"maxConnections"`
-	MaxIdle        int `yaml:"maxIdleConnections"`
-}
-
-type DatabaseConfig struct {
-	Postgres string        `yaml:"postgres"`
-	Pool     *DbPoolConfig `yaml:"pool"`
-}
-
-type ArchivingConfig struct {
-	Enabled            bool  `yaml:"enabled"`
-	SelfService        bool  `yaml:"selfService"`
-	TargetBytesPerPart int64 `yaml:"targetBytesPerPart"`
-}
-
-type UploadsConfig struct {
-	StoragePaths         []string            `yaml:"storagePaths,flow"` // deprecated
-	MaxSizeBytes         int64               `yaml:"maxBytes"`
-	MinSizeBytes         int64               `yaml:"minBytes"`
-	AllowedTypes         []string            `yaml:"allowedTypes,flow"`
-	PerUserExclusions    map[string][]string `yaml:"exclusions,flow"`
-	ReportedMaxSizeBytes int64               `yaml:"reportedMaxBytes"`
-}
-
-type DatastoreConfig struct {
-	Type       string            `yaml:"type"`
-	Enabled    bool              `yaml:"enabled"`
-	ForUploads bool              `yaml:"forUploads"` // deprecated
-	MediaKinds []string          `yaml:"forKinds,flow"`
-	Options    map[string]string `yaml:"opts,flow"`
-}
-
-type DownloadsConfig struct {
-	MaxSizeBytes        int64        `yaml:"maxBytes"`
-	NumWorkers          int          `yaml:"numWorkers"`
-	FailureCacheMinutes int          `yaml:"failureCacheMinutes"`
-	Cache               *CacheConfig `yaml:"cache"`
-}
-
-type ThumbnailsConfig struct {
-	MaxSourceBytes      int64            `yaml:"maxSourceBytes"`
-	NumWorkers          int              `yaml:"numWorkers"`
-	Types               []string         `yaml:"types,flow"`
-	MaxAnimateSizeBytes int64            `yaml:"maxAnimateSizeBytes"`
-	Sizes               []*ThumbnailSize `yaml:"sizes,flow"`
-	AllowAnimated       bool             `yaml:"allowAnimated"`
-	DefaultAnimated     bool             `yaml:"defaultAnimated"`
-	StillFrame          float32          `yaml:"stillFrame"`
-}
-
-type ThumbnailSize struct {
-	Width  int `yaml:"width"`
-	Height int `yaml:"height"`
-}
-
-type UrlPreviewsConfig struct {
-	Enabled            bool     `yaml:"enabled"`
-	NumWords           int      `yaml:"numWords"`
-	NumTitleWords      int      `yaml:"numTitleWords"`
-	MaxLength          int      `yaml:"maxLength"`
-	MaxTitleLength     int      `yaml:"maxTitleLength"`
-	MaxPageSizeBytes   int64    `yaml:"maxPageSizeBytes"`
-	NumWorkers         int      `yaml:"numWorkers"`
-	FilePreviewTypes   []string `yaml:"filePreviewTypes,flow"`
-	DisallowedNetworks []string `yaml:"disallowedNetworks,flow"`
-	AllowedNetworks    []string `yaml:"allowedNetworks,flow"`
-	UnsafeCertificates bool     `yaml:"previewUnsafeCertificates"`
-}
-
-type RateLimitConfig struct {
-	RequestsPerSecond float64 `yaml:"requestsPerSecond"`
-	Enabled           bool    `yaml:"enabled"`
-	BurstCount        int     `yaml:"burst"`
-}
-
-type IdenticonsConfig struct {
-	Enabled bool `yaml:"enabled"`
-}
-
-type CacheConfig struct {
-	Enabled               bool  `yaml:"enabled"`
-	MaxSizeBytes          int64 `yaml:"maxSizeBytes"`
-	MaxFileSizeBytes      int64 `yaml:"maxFileSizeBytes"`
-	TrackedMinutes        int   `yaml:"trackedMinutes"`
-	MinCacheTimeSeconds   int   `yaml:"minCacheTimeSeconds"`
-	MinEvictedTimeSeconds int   `yaml:"minEvictedTimeSeconds"`
-	MinDownloads          int   `yaml:"minDownloads"`
-}
-
-type QuarantineConfig struct {
-	ReplaceThumbnails bool   `yaml:"replaceThumbnails"`
-	ReplaceDownloads  bool   `yaml:"replaceDownloads"`
-	ThumbnailPath     string `yaml:"thumbnailPath"`
-	AllowLocalAdmins  bool   `yaml:"allowLocalAdmins"`
-}
-
-type TimeoutsConfig struct {
-	UrlPreviews  int `yaml:"urlPreviewTimeoutSeconds"`
-	Federation   int `yaml:"federationTimeoutSeconds"`
-	ClientServer int `yaml:"clientServerTimeoutSeconds"`
-}
-
-type MetricsConfig struct {
-	Enabled     bool   `yaml:"enabled"`
-	BindAddress string `yaml:"bindAddress"`
-	Port        int    `yaml:"port"`
-}
-
-type SharedSecretConfig struct {
-	Enabled bool   `yaml:"enabled"`
-	Token   string `yaml:"token"`
-}
-
-type MediaRepoConfig struct {
-	General        *GeneralConfig      `yaml:"repo"`
-	Homeservers    []*HomeserverConfig `yaml:"homeservers,flow"`
-	Admins         []string            `yaml:"admins,flow"`
-	Database       *DatabaseConfig     `yaml:"database"`
-	DataStores     []DatastoreConfig   `yaml:"datastores"`
-	Archiving      *ArchivingConfig    `yaml:"archiving"`
-	Uploads        *UploadsConfig      `yaml:"uploads"`
-	Downloads      *DownloadsConfig    `yaml:"downloads"`
-	Thumbnails     *ThumbnailsConfig   `yaml:"thumbnails"`
-	UrlPreviews    *UrlPreviewsConfig  `yaml:"urlPreviews"`
-	RateLimit      *RateLimitConfig    `yaml:"rateLimit"`
-	Identicons     *IdenticonsConfig   `yaml:"identicons"`
-	Quarantine     *QuarantineConfig   `yaml:"quarantine"`
-	TimeoutSeconds *TimeoutsConfig     `yaml:"timeouts"`
-	Metrics        *MetricsConfig      `yaml:"metrics"`
-	SharedSecret   *SharedSecretConfig `yaml:"sharedSecretAuth"`
-}
diff --git a/common/config/models_domain.go b/common/config/models_domain.go
new file mode 100644
index 0000000000000000000000000000000000000000..98d60c9acecd500c43b450b9fca96c1f73970f1e
--- /dev/null
+++ b/common/config/models_domain.go
@@ -0,0 +1,74 @@
+package config
+
+type ArchivingConfig struct {
+	Enabled            bool  `yaml:"enabled"`
+	SelfService        bool  `yaml:"selfService"`
+	TargetBytesPerPart int64 `yaml:"targetBytesPerPart"`
+}
+
+type UploadsConfig struct {
+	StoragePaths         []string            `yaml:"storagePaths,flow"` // deprecated
+	MaxSizeBytes         int64               `yaml:"maxBytes"`
+	MinSizeBytes         int64               `yaml:"minBytes"`
+	AllowedTypes         []string            `yaml:"allowedTypes,flow"`
+	PerUserExclusions    map[string][]string `yaml:"exclusions,flow"`
+	ReportedMaxSizeBytes int64               `yaml:"reportedMaxBytes"`
+}
+
+type DatastoreConfig struct {
+	Type       string            `yaml:"type"`
+	Enabled    bool              `yaml:"enabled"`
+	ForUploads bool              `yaml:"forUploads"` // deprecated
+	MediaKinds []string          `yaml:"forKinds,flow"`
+	Options    map[string]string `yaml:"opts,flow"`
+}
+
+type DownloadsConfig struct {
+	MaxSizeBytes        int64 `yaml:"maxBytes"`
+	FailureCacheMinutes int   `yaml:"failureCacheMinutes"`
+}
+
+type ThumbnailsConfig struct {
+	MaxSourceBytes      int64           `yaml:"maxSourceBytes"`
+	Types               []string        `yaml:"types,flow"`
+	MaxAnimateSizeBytes int64           `yaml:"maxAnimateSizeBytes"`
+	Sizes               []ThumbnailSize `yaml:"sizes,flow"`
+	AllowAnimated       bool            `yaml:"allowAnimated"`
+	DefaultAnimated     bool            `yaml:"defaultAnimated"`
+	StillFrame          float32         `yaml:"stillFrame"`
+}
+
+type ThumbnailSize struct {
+	Width  int `yaml:"width"`
+	Height int `yaml:"height"`
+}
+
+type UrlPreviewsConfig struct {
+	Enabled            bool     `yaml:"enabled"`
+	NumWords           int      `yaml:"numWords"`
+	NumTitleWords      int      `yaml:"numTitleWords"`
+	MaxLength          int      `yaml:"maxLength"`
+	MaxTitleLength     int      `yaml:"maxTitleLength"`
+	MaxPageSizeBytes   int64    `yaml:"maxPageSizeBytes"`
+	FilePreviewTypes   []string `yaml:"filePreviewTypes,flow"`
+	DisallowedNetworks []string `yaml:"disallowedNetworks,flow"`
+	AllowedNetworks    []string `yaml:"allowedNetworks,flow"`
+	UnsafeCertificates bool     `yaml:"previewUnsafeCertificates"`
+}
+
+type IdenticonsConfig struct {
+	Enabled bool `yaml:"enabled"`
+}
+
+type QuarantineConfig struct {
+	ReplaceThumbnails bool   `yaml:"replaceThumbnails"`
+	ReplaceDownloads  bool   `yaml:"replaceDownloads"`
+	ThumbnailPath     string `yaml:"thumbnailPath"`
+	AllowLocalAdmins  bool   `yaml:"allowLocalAdmins"`
+}
+
+type TimeoutsConfig struct {
+	UrlPreviews  int `yaml:"urlPreviewTimeoutSeconds"`
+	Federation   int `yaml:"federationTimeoutSeconds"`
+	ClientServer int `yaml:"clientServerTimeoutSeconds"`
+}
diff --git a/common/rcontext/request_context.go b/common/rcontext/request_context.go
index 2f89fb244991b6aa2766fe391df2752b20940b83..d168ce60ac4b8d48e02e0bfa7a00ce94035b88f1 100644
--- a/common/rcontext/request_context.go
+++ b/common/rcontext/request_context.go
@@ -11,7 +11,12 @@ func Initial() RequestContext {
 	return RequestContext{
 		Context: context.Background(),
 		Log:     &logrus.Entry{},
-		Config:  config.Get(),
+		Config: config.DomainRepoConfig{
+			MinimumRepoConfig: config.Get().MinimumRepoConfig,
+			Downloads:         config.Get().Downloads.DownloadsConfig,
+			Thumbnails:        config.Get().Thumbnails.ThumbnailsConfig,
+			UrlPreviews:       config.Get().UrlPreviews.UrlPreviewsConfig,
+		},
 	}.populate()
 }
 
@@ -20,7 +25,7 @@ type RequestContext struct {
 
 	// These are also stored on the context object itself
 	Log    *logrus.Entry           // mr.logger
-	Config *config.MediaRepoConfig // mr.serverConfig
+	Config config.DomainRepoConfig // mr.serverConfig
 }
 
 func (c RequestContext) populate() RequestContext {
diff --git a/util/config.go b/util/config.go
index 416bb68d0a6817e360b4f589d237cd2fb791db8a..04980a6af268ebfbd4a1dfe073d235a4d00fdfd8 100644
--- a/util/config.go
+++ b/util/config.go
@@ -14,7 +14,7 @@ func GetHomeserverConfig(server string) *config.HomeserverConfig {
 	for i := 0; i < len(config.Get().Homeservers); i++ {
 		hs := config.Get().Homeservers[i]
 		if hs.Name == server {
-			return hs
+			return &hs
 		}
 	}