Repository: scionproto/scion
Pull request #3845 (2020-07-31 15:23:05)

cs, sd: simplify database configs
The CS and the SD use multiple databases: path, beacon, trust,
revocation, and/or renewal. Each database was each own type
in the Go codebase, leading to a lot of duplicated code.

This PR changes the above in the following ways:
- The database configurations to reuse the same type.
- The database configuration type has been reworked from
a map to a struct.
- Helper factories have been added to a new storage package,
to simplify the creation of databases.
- CS and SD configs no longer accept database backend fields.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3845)
<!-- Reviewable:end -->



Patch:
diff --git a/go.mod b/go.mod
index ba485e57d..ae03fc245 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,6 @@ require (
 	github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
 	github.com/dchest/cmac v0.0.0-20150527144652-62ff55a1048c
 	github.com/golang/mock v1.4.0
-	github.com/golang/protobuf v1.4.0 // indirect
 	github.com/google/go-cmp v0.4.0
 	github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036 // indirect
 	github.com/google/gopacket v1.1.16-0.20190123011826-102d5ca2098c
@@ -20,15 +19,14 @@ require (
 	github.com/mattn/go-sqlite3 v1.9.1-0.20180719091609-b3511bfdd742
 	github.com/opentracing/opentracing-go v1.1.0
 	github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible
-	github.com/pelletier/go-toml v1.8.0
+	github.com/pelletier/go-toml v1.8.1-0.20200708110244-34de94e6a887
 	github.com/pkg/errors v0.8.2-0.20190227000051-27936f6d90f9 // indirect
-	github.com/prometheus/client_golang v1.1.0
-	github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect
+	github.com/prometheus/client_golang v1.6.0
 	github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44
 	github.com/smartystreets/goconvey v1.6.4
 	github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b
 	github.com/spf13/cobra v1.0.0
-	github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709
+	github.com/stretchr/testify v1.4.0
 	github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4
 	github.com/uber/jaeger-client-go v2.20.1+incompatible
 	github.com/uber/jaeger-lib v2.0.0+incompatible // indirect
diff --git a/go.sum b/go.sum
index b65a2e111..c5856fb72 100644
--- a/go.sum
+++ b/go.sum
@@ -7,13 +7,14 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
 dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
 git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY=
 github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/antlr/antlr4 v0.0.0-20181218183524-be58ebffde8e h1:yxMh4HIdsSh2EqxUESWvzszYMNzOugRyYCeohfwNULM=
 github.com/antlr/antlr4 v0.0.0-20181218183524-be58ebffde8e/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
@@ -28,7 +29,10 @@ github.com/buildkite/go-buildkite v2.2.1-0.20190413010238-568b6651b687+incompati
 github.com/buildkite/go-buildkite v2.2.1-0.20190413010238-568b6651b687+incompatible/go.mod h1:WTV0aX5KnQ9ofsKMg2CLUBLJNsQ0RwOEKPhrXXZWPcE=
 github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
 github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -58,13 +62,13 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
 github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
@@ -74,7 +78,6 @@ github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
 github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -85,7 +88,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
@@ -121,7 +123,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
 github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -181,10 +183,9 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible h1:MUIwjEiAMYk8zkXXUQeb5itrXF+HpS2pfxNsA2a7AiY=
 github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
-github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
+github.com/pelletier/go-toml v1.8.1-0.20200708110244-34de94e6a887 h1:0r6tAXtt8p5+IJtshL5f+5E/z0qH2aE89UmV4/tRF64=
+github.com/pelletier/go-toml v1.8.1-0.20200708110244-34de94e6a887/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
 github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -197,25 +198,24 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
-github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
+github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
-github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
+github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
 github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
-github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
+github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -247,6 +247,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
 github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
 github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -267,8 +268,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709 h1:Ko2LQMrRU+Oy/+EDBwX7eZ2jp3C47eDBB8EIhKTun+I=
-github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4 h1:w58e6FAOMd+rUgOfhaBb+ZVOQIOfUkpv5AAQVmf6hsI=
 github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
@@ -299,10 +300,8 @@ go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
 golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 h1:Q7tZBpemrlsc2I7IyODzhtallWRSm4Q0d09pL6XbQtU=
 golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -342,6 +341,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -352,12 +352,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
-golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
+golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -374,7 +374,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -389,13 +388,11 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
-google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440 h1:VOR2wHHZJgoALLvnlCN4JUaWACO1lOLXiSN2F3g/GXU=
 google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
 google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -404,10 +401,10 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
 google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
@@ -419,8 +416,8 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
diff --git a/go/cs/BUILD.bazel b/go/cs/BUILD.bazel
index 4080960f1..f82ee876d 100644
--- a/go/cs/BUILD.bazel
+++ b/go/cs/BUILD.bazel
@@ -12,7 +12,6 @@ go_library(
     deps = [
         "//go/cs/beacon:go_default_library",
         "//go/cs/beaconing:go_default_library",
-        "//go/cs/beaconstorage:go_default_library",
         "//go/cs/config:go_default_library",
         "//go/cs/handlers:go_default_library",
         "//go/cs/ifstate:go_default_library",
@@ -33,7 +32,6 @@ go_library(
         "//go/lib/infra/modules/seghandler:go_default_library",
         "//go/lib/log:go_default_library",
         "//go/lib/pathdb:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
         "//go/lib/prom:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/snet:go_default_library",
@@ -43,6 +41,7 @@ go_library(
         "//go/pkg/cs:go_default_library",
         "//go/pkg/cs/trust:go_default_library",
         "//go/pkg/cs/trust/handler:go_default_library",
+        "//go/pkg/storage:go_default_library",
         "//go/pkg/trust:go_default_library",
         "//go/pkg/trust/compat:go_default_library",
         "//go/pkg/trust/metrics:go_default_library",
diff --git a/go/cs/beaconstorage/BUILD.bazel b/go/cs/beaconstorage/BUILD.bazel
deleted file mode 100644
index 218c572c3..000000000
--- a/go/cs/beaconstorage/BUILD.bazel
+++ /dev/null
@@ -1,27 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "config.go",
-        "sample.go",
-        "store.go",
-    ],
-    importpath = "github.com/scionproto/scion/go/cs/beaconstorage",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//go/cs/beacon:go_default_library",
-        "//go/cs/beacon/beacondbsqlite:go_default_library",
-        "//go/lib/addr:go_default_library",
-        "//go/lib/common:go_default_library",
-        "//go/lib/config:go_default_library",
-        "//go/lib/ctrl/path_mgmt:go_default_library",
-        "//go/lib/infra/modules/cleaner:go_default_library",
-        "//go/lib/infra/modules/db:go_default_library",
-        "//go/lib/log:go_default_library",
-        "//go/lib/serrors:go_default_library",
-        "//go/lib/spath:go_default_library",
-        "//go/lib/util:go_default_library",
-        "//go/proto:go_default_library",
-    ],
-)
diff --git a/go/cs/beaconstorage/config.go b/go/cs/beaconstorage/config.go
deleted file mode 100644
index 4fae46edc..000000000
--- a/go/cs/beaconstorage/config.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package beaconstorage provides a "factory" for beacon stores.
-// A config containing the backend type and the connection string
-// are used to create a specific beacon db.
-package beaconstorage
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/scionproto/scion/go/cs/beacon"
-	"github.com/scionproto/scion/go/cs/beacon/beacondbsqlite"
-	"github.com/scionproto/scion/go/lib/addr"
-	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/util"
-)
-
-// Backend indicates the database backend type.
-type Backend string
-
-const (
-	// backendNone is the empty backend. It defaults to sqlite.
-	backendNone Backend = ""
-	// BackendSqlite indicates an sqlite backend.
-	BackendSqlite Backend = "sqlite"
-)
-
-const (
-	// BackendKey is the backend key in the config mapping.
-	BackendKey = "backend"
-	// ConnectionKey is the connection key in the config mapping.
-	ConnectionKey = "connection"
-)
-
-var _ (config.Config) = (*BeaconDBConf)(nil)
-
-// BeaconDBConf is the configuration for the connection to the trust database.
-type BeaconDBConf map[string]string
-
-// InitDefaults chooses the sqlite backend if no backend is set and sets all keys
-// to lower case.
-func (cfg *BeaconDBConf) InitDefaults() {
-	if *cfg == nil {
-		*cfg = make(BeaconDBConf)
-	}
-	m := *cfg
-	util.LowerKeys(m)
-	if cfg.Backend() == backendNone {
-		m[BackendKey] = string(BackendSqlite)
-	}
-}
-
-// Backend returns the database backend type.
-func (cfg *BeaconDBConf) Backend() Backend {
-	return Backend((*cfg)[BackendKey])
-}
-
-// Connection returns the database connection information.
-func (cfg *BeaconDBConf) Connection() string {
-	return (*cfg)[ConnectionKey]
-}
-
-// MaxOpenConns returns the limit for maximum open connections to the database.
-func (cfg *BeaconDBConf) MaxOpenConns() (int, bool) {
-	return db.ConfiguredMaxOpenConns(*cfg)
-}
-
-// MaxIdleConns returns the limit for maximum idle connections to the database.
-func (cfg *BeaconDBConf) MaxIdleConns() (int, bool) {
-	return db.ConfiguredMaxIdleConns(*cfg)
-}
-
-// Validate validates that all values are parsable, and the backend is set.
-func (cfg *BeaconDBConf) Validate() error {
-	if err := db.ValidateConfigLimits(*cfg); err != nil {
-		return err
-	}
-	if err := cfg.validateBackend(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (cfg *BeaconDBConf) validateBackend() error {
-	switch cfg.Backend() {
-	case BackendSqlite:
-		return nil
-	case backendNone:
-		return serrors.New("No backend set")
-	}
-	return common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-}
-
-func (cfg *BeaconDBConf) validateConnection() error {
-	if cfg.Connection() == "" {
-		return serrors.New("empty connection not allowed")
-	}
-	return nil
-}
-
-// Sample writes a config sample to the writer.
-func (cfg *BeaconDBConf) Sample(dst io.Writer, path config.Path, ctx config.CtxMap) {
-	config.WriteString(dst, fmt.Sprintf(beaconDbSample, ctx[config.ID]))
-}
-
-// ConfigName is the key in the toml file.
-func (cfg *BeaconDBConf) ConfigName() string {
-	return "beacon_db"
-}
-
-// New creates a BeaconDB from the config.
-func (cfg *BeaconDBConf) New(ia addr.IA) (beacon.DB, error) {
-	log.Info("Connecting BeaconDB", "backend", cfg.Backend(), "connection", cfg.Connection())
-	var err error
-	var bdb beacon.DB
-
-	switch cfg.Backend() {
-	case BackendSqlite:
-		bdb, err = beacondbsqlite.New(cfg.Connection(), ia)
-	default:
-		return nil, common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-	}
-	if err != nil {
-		return nil, err
-	}
-	bdb = beacon.DBWithMetrics("std", bdb)
-	db.SetConnLimits(cfg, bdb)
-	return bdb, nil
-}
-
-// NewStore creates a new beacon store backed by the configured database.
-func (cfg *BeaconDBConf) NewStore(ia addr.IA, policies beacon.Policies) (Store, error) {
-	db, err := cfg.New(ia)
-	if err != nil {
-		return nil, err
-	}
-	return beacon.NewBeaconStore(policies, db)
-}
-
-// NewCoreStore creates a new core beacon store backed by the configured database.
-func (cfg *BeaconDBConf) NewCoreStore(ia addr.IA, policies beacon.CorePolicies) (Store, error) {
-	db, err := cfg.New(ia)
-	if err != nil {
-		return nil, err
-	}
-	return beacon.NewCoreBeaconStore(policies, db)
-}
diff --git a/go/cs/beaconstorage/store.go b/go/cs/beaconstorage/store.go
deleted file mode 100644
index 727517fad..000000000
--- a/go/cs/beaconstorage/store.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beaconstorage
-
-import (
-	"context"
-
-	"github.com/scionproto/scion/go/cs/beacon"
-	"github.com/scionproto/scion/go/lib/addr"
-	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
-	"github.com/scionproto/scion/go/lib/infra/modules/cleaner"
-	"github.com/scionproto/scion/go/lib/spath"
-	"github.com/scionproto/scion/go/proto"
-)
-
-// Store is the interface to interact with the beacon store.
-type Store interface {
-	// PreFilter indicates whether the beacon will be filtered on insert by
-	// returning an error with the reason. This allows the caller to drop
-	// ignored beacons.
-	PreFilter(beacon beacon.Beacon) error
-	// BeaconsToPropagate returns a channel that provides all beacons to
-	// propagate at the time of the call. The selection is based on the
-	// configured propagation policy.
-	BeaconsToPropagate(ctx context.Context) (<-chan beacon.BeaconOrErr, error)
-	// SegmentsToRegister returns a channel that provides all beacons to
-	// register at the time of the call. The selections is based on the
-	// configured propagation policy for the requested segment type.
-	SegmentsToRegister(ctx context.Context, segType proto.PathSegType) (
-		<-chan beacon.BeaconOrErr, error)
-	// InsertBeacon adds a verified beacon to the store, ignoring revocations.
-	InsertBeacon(ctx context.Context, beacon beacon.Beacon) (beacon.InsertStats, error)
-	// InsertRevocations inserts the revocation into the BeaconDB.
-	// The provided revocation must be verified by the caller.
-	InsertRevocations(ctx context.Context, revocations ...*path_mgmt.SignedRevInfo) error
-	// DeleteRevocation deletes the revocation from the BeaconDB.
-	DeleteRevocation(ctx context.Context, ia addr.IA, ifid common.IFIDType) error
-	// UpdatePolicy updates the policy. Beacons that are filtered by all
-	// policies after the update are removed.
-	UpdatePolicy(ctx context.Context, policy beacon.Policy) error
-	// MaxExpTime returns the segment maximum expiration time for the given policy.
-	MaxExpTime(policyType beacon.PolicyType) spath.ExpTimeType
-	// DeleteExpired deletes expired Beacons from the store.
-	DeleteExpiredBeacons(ctx context.Context) (int, error)
-	// DeleteExpiredRevocations deletes expired Revocations from the store.
-	DeleteExpiredRevocations(ctx context.Context) (int, error)
-	// Close closes the store.
-	Close() error
-}
-
-// NewBeaconCleaner creates a cleaner task, which deletes expired beacons.
-func NewBeaconCleaner(s Store) *cleaner.Cleaner {
-	return cleaner.New(func(ctx context.Context) (int, error) {
-		return s.DeleteExpiredBeacons(ctx)
-	}, "bs_beacon")
-}
-
-// NewRevocationCleaner creates a cleaner task, which deletes expired revocations.
-func NewRevocationCleaner(s Store) *cleaner.Cleaner {
-	return cleaner.New(func(ctx context.Context) (int, error) {
-		return s.DeleteExpiredRevocations(ctx)
-	}, "bs_revocation")
-}
diff --git a/go/cs/config/BUILD.bazel b/go/cs/config/BUILD.bazel
index 5ba24bbb9..a267d0096 100644
--- a/go/cs/config/BUILD.bazel
+++ b/go/cs/config/BUILD.bazel
@@ -10,16 +10,14 @@ go_library(
     importpath = "github.com/scionproto/scion/go/cs/config",
     visibility = ["//visibility:public"],
     deps = [
-        "//go/cs/beaconstorage:go_default_library",
         "//go/lib/common:go_default_library",
         "//go/lib/config:go_default_library",
         "//go/lib/ctrl/path_mgmt:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
         "//go/lib/serrors:go_default_library",
-        "//go/lib/truststorage:go_default_library",
         "//go/lib/util:go_default_library",
+        "//go/pkg/storage:go_default_library",
     ],
 )
 
@@ -28,13 +26,11 @@ go_test(
     srcs = ["config_test.go"],
     embed = [":go_default_library"],
     deps = [
-        "//go/cs/beaconstorage/beaconstoragetest:go_default_library",
         "//go/lib/ctrl/path_mgmt:go_default_library",
         "//go/lib/env/envtest:go_default_library",
         "//go/lib/log/logtest:go_default_library",
-        "//go/lib/pathstorage/pathstoragetest:go_default_library",
-        "//go/lib/truststorage/truststoragetest:go_default_library",
         "//go/lib/util:go_default_library",
+        "//go/pkg/storage/test:go_default_library",
         "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
diff --git a/go/cs/config/config.go b/go/cs/config/config.go
index 0615e5935..6d060f38e 100644
--- a/go/cs/config/config.go
+++ b/go/cs/config/config.go
@@ -19,16 +19,14 @@ import (
 	"io"
 	"time"
 
-	"github.com/scionproto/scion/go/cs/beaconstorage"
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/pathstorage"
 	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/truststorage"
 	"github.com/scionproto/scion/go/lib/util"
+	"github.com/scionproto/scion/go/pkg/storage"
 )
 
 const (
@@ -70,19 +68,19 @@ var _ config.Config = (*Config)(nil)
 
 // Config is the control server configuration.
 type Config struct {
-	General   env.General                `toml:"general,omitempty"`
-	Features  env.Features               `toml:"features,omitempty"`
-	Logging   log.Config                 `toml:"log,omitempty"`
-	Metrics   env.Metrics                `toml:"metrics,omitempty"`
-	Tracing   env.Tracing                `toml:"tracing,omitempty"`
-	QUIC      env.QUIC                   `toml:"quic,omitempty"`
-	BeaconDB  beaconstorage.BeaconDBConf `toml:"beacon_db,omitempty"`
-	TrustDB   truststorage.TrustDBConf   `toml:"trust_db,omitempty"`
-	RenewalDB truststorage.RenewalDBConf `toml:"renewal_db,omitempty"`
-	PathDB    pathstorage.PathDBConf     `toml:"path_db,omitempty"`
-	BS        BSConfig                   `toml:"beaconing,omitempty"`
-	PS        PSConfig                   `toml:"path,omitempty"`
-	CA        CA                         `toml:"ca,omitempty"`
+	General   env.General      `toml:"general,omitempty"`
+	Features  env.Features     `toml:"features,omitempty"`
+	Logging   log.Config       `toml:"log,omitempty"`
+	Metrics   env.Metrics      `toml:"metrics,omitempty"`
+	Tracing   env.Tracing      `toml:"tracing,omitempty"`
+	QUIC      env.QUIC         `toml:"quic,omitempty"`
+	BeaconDB  storage.DBConfig `toml:"beacon_db,omitempty"`
+	TrustDB   storage.DBConfig `toml:"trust_db,omitempty"`
+	RenewalDB storage.DBConfig `toml:"renewal_db,omitempty"`
+	PathDB    storage.DBConfig `toml:"path_db,omitempty"`
+	BS        BSConfig         `toml:"beaconing,omitempty"`
+	PS        PSConfig         `toml:"path,omitempty"`
+	CA        CA               `toml:"ca,omitempty"`
 }
 
 // InitDefaults initializes the default values for all parts of the config.
@@ -129,10 +127,34 @@ func (cfg *Config) Sample(dst io.Writer, path config.Path, _ config.CtxMap) {
 		&cfg.Metrics,
 		&cfg.Tracing,
 		&cfg.QUIC,
-		&cfg.BeaconDB,
-		&cfg.TrustDB,
-		&cfg.RenewalDB,
-		&cfg.PathDB,
+		config.OverrideName(
+			config.FormatData(
+				&cfg.BeaconDB,
+				storage.SetID(storage.SampleBeaconDB, idSample).Connection,
+			),
+			"beacon_db",
+		),
+		config.OverrideName(
+			config.FormatData(
+				&cfg.TrustDB,
+				storage.SetID(storage.SampleTrustDB, idSample).Connection,
+			),
+			"trust_db",
+		),
+		config.OverrideName(
+			config.FormatData(
+				&cfg.RenewalDB,
+				storage.SetID(storage.SampleRenewalDB, idSample).Connection,
+			),
+			"renewal_db",
+		),
+		config.OverrideName(
+			config.FormatData(
+				&cfg.PathDB,
+				storage.SetID(storage.SamplePathDB, idSample).Connection,
+			),
+			"path_db",
+		),
 		&cfg.BS,
 		&cfg.PS,
 		&cfg.CA,
diff --git a/go/cs/cs.go b/go/cs/cs.go
index e622b7530..9e8e1e8b0 100644
--- a/go/cs/cs.go
+++ b/go/cs/cs.go
@@ -22,8 +22,8 @@ import (
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/spf13/cobra"
 
+	"github.com/scionproto/scion/go/cs/beacon"
 	"github.com/scionproto/scion/go/cs/beaconing"
-	"github.com/scionproto/scion/go/cs/beaconstorage"
 	"github.com/scionproto/scion/go/cs/config"
 	"github.com/scionproto/scion/go/cs/handlers"
 	"github.com/scionproto/scion/go/cs/ifstate"
@@ -44,7 +44,6 @@ import (
 	"github.com/scionproto/scion/go/lib/infra/modules/seghandler"
 	"github.com/scionproto/scion/go/lib/log"
 	"github.com/scionproto/scion/go/lib/pathdb"
-	"github.com/scionproto/scion/go/lib/pathstorage"
 	"github.com/scionproto/scion/go/lib/prom"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/snet"
@@ -54,6 +53,7 @@ import (
 	"github.com/scionproto/scion/go/pkg/cs"
 	cstrust "github.com/scionproto/scion/go/pkg/cs/trust"
 	trusthandler "github.com/scionproto/scion/go/pkg/cs/trust/handler"
+	"github.com/scionproto/scion/go/pkg/storage"
 	"github.com/scionproto/scion/go/pkg/trust"
 	"github.com/scionproto/scion/go/pkg/trust/compat"
 	trustmetrics "github.com/scionproto/scion/go/pkg/trust/metrics"
@@ -141,19 +141,20 @@ func run(file string) error {
 		return err
 	}
 
-	pathDB, revCache, err := pathstorage.NewPathStorage(cfg.PathDB)
+	revCache := storage.NewRevocationStorage()
+	pathDB, err := storage.NewPathStorage(cfg.PathDB)
 	if err != nil {
 		return serrors.WrapStr("initializing path storage", err)
 	}
 	defer revCache.Close()
-	pathDB = pathdb.WithMetrics(string(cfg.PathDB.Backend()), pathDB)
+	pathDB = pathdb.WithMetrics(string(storage.BackendSqlite), pathDB)
 	defer pathDB.Close()
 
-	trustDB, err := cfg.TrustDB.New()
+	trustDB, err := storage.NewTrustStorage(cfg.TrustDB)
 	if err != nil {
 		return serrors.WrapStr("initializing trust storage", err)
 	}
-	trustDB = trustmetrics.WrapDB(string(cfg.TrustDB.Backend()), trustDB)
+	trustDB = trustmetrics.WrapDB(string(storage.BackendSqlite), trustDB)
 	defer trustDB.Close()
 	if err := cs.LoadTrustMaterial(cfg.General.ConfigDir, trustDB, log.Root()); err != nil {
 		return err
@@ -266,7 +267,7 @@ func run(file string) error {
 
 	var chainBuilder cstrust.ChainBuilder
 	if topo.CA() {
-		renewalDB, err := cfg.RenewalDB.New()
+		renewalDB, err := storage.NewRenewalStorage(cfg.RenewalDB)
 		if err != nil {
 			return serrors.WrapStr("initializing renewal database", err)
 		}
@@ -420,19 +421,24 @@ func setup(cfg *config.Config) (*ifstate.Interfaces, error) {
 	return intfs, nil
 }
 
-func loadBeaconStore(core bool, ia addr.IA, cfg config.Config) (beaconstorage.Store, bool, error) {
+func loadBeaconStore(core bool, ia addr.IA, cfg config.Config) (cs.Store, bool, error) {
+	db, err := storage.NewBeaconStorage(cfg.BeaconDB, ia)
+	if err != nil {
+		return nil, false, err
+	}
+	db = beacon.DBWithMetrics(string(storage.BackendSqlite), db)
 	if core {
 		policies, err := cs.LoadCorePolicies(cfg.BS.Policies)
 		if err != nil {
 			return nil, false, err
 		}
-		store, err := cfg.BeaconDB.NewCoreStore(ia, policies)
+		store, err := beacon.NewCoreBeaconStore(policies, db)
 		return store, *policies.Prop.Filter.AllowIsdLoop, err
 	}
 	policies, err := cs.LoadNonCorePolicies(cfg.BS.Policies)
 	if err != nil {
 		return nil, false, err
 	}
-	store, err := cfg.BeaconDB.NewStore(ia, policies)
+	store, err := beacon.NewBeaconStore(policies, db)
 	return store, *policies.Prop.Filter.AllowIsdLoop, err
 }
diff --git a/go/lib/config/config.go b/go/lib/config/config.go
index 5a689a1b0..ae78dff1b 100644
--- a/go/lib/config/config.go
+++ b/go/lib/config/config.go
@@ -167,3 +167,41 @@ func LoadFile(file string, cfg interface{}) error {
 	}
 	return nil
 }
+
+type nameOverrideSampler struct {
+	Sampler
+	name string
+}
+
+func (s nameOverrideSampler) ConfigName() string {
+	return s.name
+}
+
+// OverrideName creates a sampler that is identical to the one in the argument,
+// except it will use the desired config name instead of the original one.
+func OverrideName(s Sampler, name string) Sampler {
+	return nameOverrideSampler{
+		Sampler: s,
+		name:    name,
+	}
+}
+
+type formatDataSampler struct {
+	Sampler
+	data []interface{}
+}
+
+func (s formatDataSampler) Sample(dst io.Writer, path Path, ctx CtxMap) {
+	buf := &bytes.Buffer{}
+	s.Sampler.Sample(buf, path, ctx)
+	WriteString(dst, fmt.Sprintf(string(buf.Bytes()), s.data...))
+}
+
+// FormatData creates a sampler that will call fmt.Sprintf on the string returned
+// by s.Sample using the supplied argument information.
+func FormatData(s Sampler, a ...interface{}) Sampler {
+	return formatDataSampler{
+		Sampler: s,
+		data:    a,
+	}
+}
diff --git a/go/lib/pathstorage/BUILD.bazel b/go/lib/pathstorage/BUILD.bazel
deleted file mode 100644
index 325732cfa..000000000
--- a/go/lib/pathstorage/BUILD.bazel
+++ /dev/null
@@ -1,23 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "pathstorage.go",
-        "sample.go",
-    ],
-    importpath = "github.com/scionproto/scion/go/lib/pathstorage",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//go/lib/common:go_default_library",
-        "//go/lib/config:go_default_library",
-        "//go/lib/infra/modules/db:go_default_library",
-        "//go/lib/log:go_default_library",
-        "//go/lib/pathdb:go_default_library",
-        "//go/lib/pathdb/sqlite:go_default_library",
-        "//go/lib/revcache:go_default_library",
-        "//go/lib/revcache/memrevcache:go_default_library",
-        "//go/lib/serrors:go_default_library",
-        "//go/lib/util:go_default_library",
-    ],
-)
diff --git a/go/lib/pathstorage/pathstorage.go b/go/lib/pathstorage/pathstorage.go
deleted file mode 100644
index d6dc92a1e..000000000
--- a/go/lib/pathstorage/pathstorage.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2018 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pathstorage
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/pathdb"
-	sqlitepathdb "github.com/scionproto/scion/go/lib/pathdb/sqlite"
-	"github.com/scionproto/scion/go/lib/revcache"
-	"github.com/scionproto/scion/go/lib/revcache/memrevcache"
-	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/util"
-)
-
-type Backend string
-
-const (
-	BackendNone   Backend = ""
-	BackendSqlite Backend = "sqlite"
-	BackendMem    Backend = "mem"
-)
-
-const (
-	BackendKey    = "backend"
-	ConnectionKey = "connection"
-)
-
-var _ config.Config = (*PathDBConf)(nil)
-
-// PathDBConf is the configuration for the connection to the path database.
-type PathDBConf map[string]string
-
-// InitDefaults choses the sqlite backend if no backend is set.
-func (cfg *PathDBConf) InitDefaults() {
-	if *cfg == nil {
-		*cfg = make(PathDBConf)
-	}
-	m := *cfg
-	util.LowerKeys(m)
-	if cfg.Backend() == BackendNone {
-		m[BackendKey] = string(BackendSqlite)
-	}
-}
-
-func (cfg *PathDBConf) Backend() Backend {
-	return Backend((*cfg)[BackendKey])
-}
-
-func (cfg *PathDBConf) Connection() string {
-	return (*cfg)[ConnectionKey]
-}
-
-func (cfg *PathDBConf) MaxOpenConns() (int, bool) {
-	return db.ConfiguredMaxOpenConns(*cfg)
-}
-
-func (cfg *PathDBConf) MaxIdleConns() (int, bool) {
-	return db.ConfiguredMaxIdleConns(*cfg)
-}
-
-func (cfg *PathDBConf) Sample(dst io.Writer, _ config.Path, ctx config.CtxMap) {
-	config.WriteString(dst, fmt.Sprintf(pathDbSample, ctx[config.ID]))
-}
-
-func (cfg *PathDBConf) ConfigName() string {
-	return "path_db"
-}
-
-// Validate validates the configuration, should be called after InitDefaults.
-func (cfg *PathDBConf) Validate() error {
-	if err := db.ValidateConfigLimits(*cfg); err != nil {
-		return err
-	}
-	if err := cfg.validateBackend(); err != nil {
-		return err
-	}
-	if err := cfg.validateConnection(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (cfg *PathDBConf) validateBackend() error {
-	switch cfg.Backend() {
-	case BackendSqlite:
-		return nil
-	case BackendNone:
-		return serrors.New("No backend set")
-	}
-	return common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-}
-
-func (cfg *PathDBConf) validateConnection() error {
-	if cfg.Connection() == "" {
-		return serrors.New("Empty connection not allowed")
-	}
-	return nil
-}
-
-var _ config.Config = (*RevCacheConf)(nil)
-
-// RevCacheConf is the configuration for the connection to the revocation cache.
-type RevCacheConf map[string]string
-
-// InitDefaults chooses the in-memory backend if no backend is set.
-func (cfg *RevCacheConf) InitDefaults() {
-	if *cfg == nil {
-		*cfg = make(RevCacheConf)
-	}
-	m := *cfg
-	util.LowerKeys(m)
-	if cfg.Backend() == BackendNone {
-		m[BackendKey] = string(BackendMem)
-	}
-}
-
-func (cfg *RevCacheConf) Backend() Backend {
-	return Backend((*cfg)[BackendKey])
-}
-
-func (cfg *RevCacheConf) Connection() string {
-	return (*cfg)[ConnectionKey]
-}
-
-func (cfg *RevCacheConf) MaxOpenConns() (int, bool) {
-	return db.ConfiguredMaxOpenConns(*cfg)
-}
-
-func (cfg *RevCacheConf) MaxIdleConns() (int, bool) {
-	return db.ConfiguredMaxIdleConns(*cfg)
-}
-
-// Validate validates the configuration, should be called after InitDefaults.
-func (cfg *RevCacheConf) Validate() error {
-	if err := db.ValidateConfigLimits(*cfg); err != nil {
-		return err
-	}
-	if err := cfg.validateBackend(); err != nil {
-		return err
-	}
-	if err := cfg.validateConnection(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (cfg *RevCacheConf) Sample(dst io.Writer, _ config.Path, _ config.CtxMap) {
-	config.WriteString(dst, revSample)
-}
-
-func (cfg *RevCacheConf) ConfigName() string {
-	return "rev_cache"
-}
-
-func (cfg *RevCacheConf) validateBackend() error {
-	switch cfg.Backend() {
-	case BackendSqlite, BackendMem:
-		return nil
-	case BackendNone:
-		return serrors.New("No backend set")
-	}
-	return common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-}
-
-func (cfg *RevCacheConf) validateConnection() error {
-	if cfg.Backend() != BackendMem && cfg.Connection() == "" {
-		return serrors.New("Empty connection not allowed")
-	}
-	return nil
-}
-
-// NewPathStorage creates a PathStorage from the given configs. Periodic
-// cleaners for the given databases have to be manually created and started
-// (see cleaner package).
-func NewPathStorage(pdbConf PathDBConf) (pathdb.PathDB, revcache.RevCache, error) {
-
-	if err := pdbConf.Validate(); err != nil {
-		return nil, nil, common.NewBasicError("Invalid pathdb config", err)
-	}
-	pdb, err := newPathDB(pdbConf)
-	if err != nil {
-		return nil, nil, err
-	}
-	rc, err := newRevCache(pdbConf)
-	if err != nil {
-		return nil, nil, err
-	}
-	return pdb, rc, nil
-}
-
-func newPathDB(conf PathDBConf) (pathdb.PathDB, error) {
-	log.Info("Connecting PathDB", "backend", conf.Backend(), "connection", conf.Connection())
-	var err error
-	var pdb pathdb.PathDB
-
-	switch conf.Backend() {
-	case BackendSqlite:
-		pdb, err = sqlitepathdb.New(conf.Connection())
-	case BackendNone:
-		return nil, nil
-	default:
-		return nil, common.NewBasicError("Unsupported backend", nil, "backend", conf.Backend())
-	}
-
-	if err != nil {
-		return nil, err
-	}
-	db.SetConnLimits(&conf, pdb)
-	return pdb, nil
-}
-
-func newRevCache(conf PathDBConf) (revcache.RevCache, error) {
-	switch conf.Backend() {
-	case BackendSqlite:
-		log.Info("Connecting RevCache", "backend", "memory")
-		return memrevcache.New(), nil
-	default:
-		return nil, common.NewBasicError("Unsupported backend", nil, "backend", conf.Backend())
-	}
-}
diff --git a/go/lib/pathstorage/sample.go b/go/lib/pathstorage/sample.go
deleted file mode 100644
index 13203208d..000000000
--- a/go/lib/pathstorage/sample.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pathstorage
-
-const pathDbSample = `
-# The type of pathdb backend.
-backend = "sqlite"
-
-# Path to the path database. (required)
-connection = "/var/lib/scion/pathdb/%s.path.db"
-
-# The maximum number of open connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_open_conns = ""
-
-# The maximum number of idle connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_idle_conns = ""
-`
-
-const revSample = `
-# The type of RevCache backend.
-backend = "mem"
-
-# The maximum number of open connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_open_conns = ""
-
-# The maximum number of idle connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_idle_conns = ""
-`
diff --git a/go/lib/truststorage/renewal.go b/go/lib/truststorage/renewal.go
deleted file mode 100644
index b081d5e51..000000000
--- a/go/lib/truststorage/renewal.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2018 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package truststorage
-
-import (
-	"fmt"
-	"io"
-	"strconv"
-
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/util"
-	"github.com/scionproto/scion/go/pkg/trust/renewal"
-	"github.com/scionproto/scion/go/pkg/trust/renewal/sqlite"
-)
-
-var _ (config.Config) = (*RenewalDBConf)(nil)
-
-// RenewalDBConf is the configuration for the connection to the renewal database.
-type RenewalDBConf map[string]string
-
-// InitDefaults choses the sqlite backend if no backend is set.
-func (cfg *RenewalDBConf) InitDefaults() {
-	if *cfg == nil {
-		*cfg = make(RenewalDBConf)
-	}
-	m := *cfg
-	util.LowerKeys(m)
-	if cfg.Backend() == BackendNone {
-		m[BackendKey] = string(BackendSqlite)
-	}
-}
-
-func (cfg *RenewalDBConf) Backend() Backend {
-	return Backend((*cfg)[BackendKey])
-}
-
-func (cfg *RenewalDBConf) Connection() string {
-	return (*cfg)[ConnectionKey]
-}
-
-func (cfg *RenewalDBConf) MaxOpenConns() (int, bool) {
-	return db.ConfiguredMaxOpenConns(*cfg)
-}
-
-func (cfg *RenewalDBConf) MaxIdleConns() (int, bool) {
-	return db.ConfiguredMaxIdleConns(*cfg)
-}
-
-func (cfg *RenewalDBConf) Sample(dst io.Writer, path config.Path, ctx config.CtxMap) {
-	config.WriteString(dst, fmt.Sprintf(renewalDbSample, ctx[config.ID]))
-}
-
-func (cfg *RenewalDBConf) ConfigName() string {
-	return "renewal_db"
-}
-
-func (cfg *RenewalDBConf) Validate() error {
-	if err := db.ValidateConfigLimits(*cfg); err != nil {
-		return err
-	}
-	// Backend and connection can be empty.
-	return nil
-}
-
-func (cfg *RenewalDBConf) validateBackend() error {
-	switch cfg.Backend() {
-	case BackendSqlite:
-		return nil
-	case BackendNone:
-		return serrors.New("No backend set")
-	}
-	return serrors.New("unsupported backend", "backend", cfg.Backend())
-}
-
-func (cfg *RenewalDBConf) validateConnection() error {
-	if cfg.Connection() == "" {
-		return serrors.New("empty connection not allowed")
-	}
-	return nil
-}
-
-func (cfg *RenewalDBConf) parsedBool(key string) (bool, error) {
-	val, ok := (*cfg)[key]
-	if !ok || val == "" {
-		return true, nil
-	}
-	return strconv.ParseBool(val)
-}
-
-// New creates a renewal database from the config.
-func (cfg *RenewalDBConf) New() (renewal.DB, error) {
-	if err := cfg.validateBackend(); err != nil {
-		return nil, err
-	}
-	if err := cfg.validateConnection(); err != nil {
-		return nil, err
-	}
-
-	log.Info("Connecting RenewalDB", "backend", cfg.Backend(), "connection", cfg.Connection())
-	tdb, err := sqlite.New(cfg.Connection())
-	if err != nil {
-		return nil, err
-	}
-	db.SetConnLimits(cfg, tdb)
-	return tdb, nil
-}
diff --git a/go/lib/truststorage/sample.go b/go/lib/truststorage/sample.go
deleted file mode 100644
index 9b5e40372..000000000
--- a/go/lib/truststorage/sample.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package truststorage
-
-const trustDbSample = `
-# The type of trustdb backend. (default sqlite)
-backend = "sqlite"
-
-# Connection for the trust database. (required)
-connection = "/var/lib/scion/spki/%s.trust.db"
-
-# Add cache for database queries. This option is currently only supported
-# for sqlite backends. In case of the empty string, caching is set by
-# default to on ("true"|"false"|"") (default "")
-cached = ""
-
-# The maximum number of open connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_open_conns = ""
-
-# The maximum number of idle connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_idle_conns = ""
-`
-
-const renewalDbSample = `
-# The type of renewal database backend. (default sqlite)
-backend = "sqlite"
-
-# Connection for the renewal database. (required)
-connection = "/var/lib/scion/spki/%s.renewal.db"
-
-# The maximum number of open connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_open_conns = ""
-
-# The maximum number of idle connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_idle_conns = ""
-`
diff --git a/go/lib/truststorage/truststorage.go b/go/lib/truststorage/truststorage.go
deleted file mode 100644
index 6df6cd3a5..000000000
--- a/go/lib/truststorage/truststorage.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2018 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package truststorage provides a "factory" for trust database.
-// A config containing the backend type and the connection string
-// are used to create a specific trust db.
-package truststorage
-
-import (
-	"fmt"
-	"io"
-	"strconv"
-
-	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/util"
-	"github.com/scionproto/scion/go/pkg/trust"
-	"github.com/scionproto/scion/go/pkg/trust/sqlite"
-)
-
-type Backend string
-
-const (
-	BackendNone   Backend = ""
-	BackendSqlite Backend = "sqlite"
-)
-
-const (
-	BackendKey    = "backend"
-	ConnectionKey = "connection"
-	CachedKey     = "cached"
-)
-
-var _ (config.Config) = (*TrustDBConf)(nil)
-
-// TrustDBConf is the configuration for the connection to the trust database.
-type TrustDBConf map[string]string
-
-// InitDefaults choses the sqlite backend if no backend is set.
-func (cfg *TrustDBConf) InitDefaults() {
-	if *cfg == nil {
-		*cfg = make(TrustDBConf)
-	}
-	m := *cfg
-	util.LowerKeys(m)
-	if cfg.Backend() == BackendNone {
-		m[BackendKey] = string(BackendSqlite)
-	}
-}
-
-func (cfg *TrustDBConf) Backend() Backend {
-	return Backend((*cfg)[BackendKey])
-}
-
-func (cfg *TrustDBConf) Connection() string {
-	return (*cfg)[ConnectionKey]
-}
-
-func (cfg *TrustDBConf) Cached() bool {
-	cached, _ := cfg.parsedBool(CachedKey)
-	return cached
-}
-
-func (cfg *TrustDBConf) MaxOpenConns() (int, bool) {
-	return db.ConfiguredMaxOpenConns(*cfg)
-}
-
-func (cfg *TrustDBConf) MaxIdleConns() (int, bool) {
-	return db.ConfiguredMaxIdleConns(*cfg)
-}
-
-func (cfg *TrustDBConf) Sample(dst io.Writer, path config.Path, ctx config.CtxMap) {
-	config.WriteString(dst, fmt.Sprintf(trustDbSample, ctx[config.ID]))
-}
-
-func (cfg *TrustDBConf) ConfigName() string {
-	return "trust_db"
-}
-
-func (cfg *TrustDBConf) Validate() error {
-	if err := db.ValidateConfigLimits(*cfg); err != nil {
-		return err
-	}
-	if err := cfg.validateBackend(); err != nil {
-		return err
-	}
-	if err := cfg.validateConnection(); err != nil {
-		return err
-	}
-	if _, err := cfg.parsedBool(CachedKey); err != nil {
-		return serrors.WrapStr("invalid 'cached' value", err)
-	}
-	return nil
-}
-
-func (cfg *TrustDBConf) validateBackend() error {
-	switch cfg.Backend() {
-	case BackendSqlite:
-		return nil
-	case BackendNone:
-		return serrors.New("No backend set")
-	}
-	return common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-}
-
-func (cfg *TrustDBConf) validateConnection() error {
-	if cfg.Connection() == "" {
-		return serrors.New("empty connection not allowed")
-	}
-	return nil
-}
-
-func (cfg *TrustDBConf) parsedBool(key string) (bool, error) {
-	val, ok := (*cfg)[key]
-	if !ok || val == "" {
-		return true, nil
-	}
-	return strconv.ParseBool(val)
-}
-
-// New creates a trust database from the config.
-func (cfg *TrustDBConf) New() (trust.DB, error) {
-	log.Info("Connecting TrustDB", "backend", cfg.Backend(), "connection", cfg.Connection())
-	var err error
-	var tdb trust.DB
-
-	switch cfg.Backend() {
-	case BackendSqlite:
-		tdb, err = sqlite.New(cfg.Connection())
-	default:
-		return nil, common.NewBasicError("Unsupported backend", nil, "backend", cfg.Backend())
-	}
-
-	if err != nil {
-		return nil, err
-	}
-	if cfg.Cached() {
-		// FIXME(roosd): Enable again.
-		// tdb = trustdbcached.WithCache(tdb)
-	}
-
-	db.SetConnLimits(cfg, tdb)
-	return tdb, nil
-}
diff --git a/go/pkg/cs/BUILD.bazel b/go/pkg/cs/BUILD.bazel
index dd2f8f7a7..81aa0a400 100644
--- a/go/pkg/cs/BUILD.bazel
+++ b/go/pkg/cs/BUILD.bazel
@@ -16,18 +16,20 @@ go_library(
         "//go/cs/beacon:go_default_library",
         "//go/cs/beaconing:go_default_library",
         "//go/cs/beaconing/compat:go_default_library",
-        "//go/cs/beaconstorage:go_default_library",
         "//go/cs/config:go_default_library",
         "//go/cs/ifstate:go_default_library",
         "//go/cs/keepalive:go_default_library",
         "//go/cs/onehop:go_default_library",
         "//go/lib/addr:go_default_library",
+        "//go/lib/common:go_default_library",
         "//go/lib/ctrl:go_default_library",
+        "//go/lib/ctrl/path_mgmt:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/infra:go_default_library",
         "//go/lib/infra/infraenv:go_default_library",
         "//go/lib/infra/messenger:go_default_library",
         "//go/lib/infra/messenger/tcp:go_default_library",
+        "//go/lib/infra/modules/cleaner:go_default_library",
         "//go/lib/infra/modules/itopo:go_default_library",
         "//go/lib/infra/modules/seghandler:go_default_library",
         "//go/lib/keyconf:go_default_library",
diff --git a/go/pkg/cs/tasks.go b/go/pkg/cs/tasks.go
index c2d60bcbe..36b338104 100644
--- a/go/pkg/cs/tasks.go
+++ b/go/pkg/cs/tasks.go
@@ -23,14 +23,16 @@ import (
 	"github.com/scionproto/scion/go/cs/beacon"
 	"github.com/scionproto/scion/go/cs/beaconing"
 	beaconingcompat "github.com/scionproto/scion/go/cs/beaconing/compat"
-	"github.com/scionproto/scion/go/cs/beaconstorage"
 	"github.com/scionproto/scion/go/cs/ifstate"
 	"github.com/scionproto/scion/go/cs/keepalive"
 	"github.com/scionproto/scion/go/cs/onehop"
 	"github.com/scionproto/scion/go/lib/addr"
+	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/ctrl"
+	"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
 	"github.com/scionproto/scion/go/lib/infra"
 	"github.com/scionproto/scion/go/lib/infra/messenger"
+	"github.com/scionproto/scion/go/lib/infra/modules/cleaner"
 	"github.com/scionproto/scion/go/lib/infra/modules/seghandler"
 	"github.com/scionproto/scion/go/lib/pathdb"
 	"github.com/scionproto/scion/go/lib/periodic"
@@ -52,7 +54,7 @@ type TasksConfig struct {
 	TrustDB         trust.DB
 	PathDB          pathdb.PathDB
 	RevCache        revcache.RevCache
-	BeaconStore     beaconstorage.Store
+	BeaconStore     Store
 	Signer          ctrl.Signer
 	Msgr            infra.Messenger
 	AddressRewriter *messenger.AddressRewriter
@@ -199,8 +201,8 @@ type Tasks struct {
 }
 
 func StartTasks(cfg TasksConfig) (*Tasks, error) {
-	beaconCleaner := beaconstorage.NewBeaconCleaner(cfg.BeaconStore)
-	revCleaner := beaconstorage.NewRevocationCleaner(cfg.BeaconStore)
+	beaconCleaner := newBeaconCleaner(cfg.BeaconStore)
+	revCleaner := newRevocationCleaner(cfg.BeaconStore)
 
 	segCleaner := pathdb.NewCleaner(cfg.PathDB, "ps_segments")
 	segRevCleaner := revcache.NewCleaner(cfg.RevCache, "ps_revocation")
@@ -285,7 +287,7 @@ type LegacyTasksConfig struct {
 	Public      *net.UDPAddr
 	Intfs       *ifstate.Interfaces
 	OneHopConn  *snet.SCIONPacketConn
-	BeaconStore beaconstorage.Store
+	BeaconStore Store
 	Signer      ctrl.Signer
 	Msgr        infra.Messenger
 
@@ -345,3 +347,64 @@ func killRunners(runners []*periodic.Runner) {
 		r.Kill()
 	}
 }
+
+// Store is the interface to interact with the beacon store.
+type Store interface {
+	// PreFilter indicates whether the beacon will be filtered on insert by
+	// returning an error with the reason. This allows the caller to drop
+	// ignored beacons.
+	PreFilter(beacon beacon.Beacon) error
+	// BeaconsToPropagate returns a channel that provides all beacons to
+	// propagate at the time of the call. The selection is based on the
+	// configured propagation policy.
+	BeaconsToPropagate(ctx context.Context) (<-chan beacon.BeaconOrErr, error)
+	// SegmentsToRegister returns a channel that provides all beacons to
+	// register at the time of the call. The selections is based on the
+	// configured propagation policy for the requested segment type.
+	SegmentsToRegister(ctx context.Context, segType proto.PathSegType) (
+		<-chan beacon.BeaconOrErr, error)
+	// InsertBeacon adds a verified beacon to the store, ignoring revocations.
+	InsertBeacon(ctx context.Context, beacon beacon.Beacon) (beacon.InsertStats, error)
+	// InsertRevocations inserts the revocation into the BeaconDB.
+	// The provided revocation must be verified by the caller.
+	InsertRevocations(ctx context.Context, revocations ...*path_mgmt.SignedRevInfo) error
+	// DeleteRevocation deletes the revocation from the BeaconDB.
+	DeleteRevocation(ctx context.Context, ia addr.IA, ifid common.IFIDType) error
+	// UpdatePolicy updates the policy. Beacons that are filtered by all
+	// policies after the update are removed.
+	UpdatePolicy(ctx context.Context, policy beacon.Policy) error
+	// MaxExpTime returns the segment maximum expiration time for the given policy.
+	MaxExpTime(policyType beacon.PolicyType) spath.ExpTimeType
+	// DeleteExpired deletes expired Beacons from the store.
+	DeleteExpiredBeacons(ctx context.Context) (int, error)
+	// DeleteExpiredRevocations deletes expired Revocations from the store.
+	DeleteExpiredRevocations(ctx context.Context) (int, error)
+	// Close closes the store.
+	Close() error
+}
+
+// expiredBeaconsDeleter delets expired beacons from the store.
+type expiredBeaconsDeleter interface {
+	// DeleteExpired deletes expired Beacons from the store.
+	DeleteExpiredBeacons(ctx context.Context) (int, error)
+}
+
+// newBeaconCleaner creates a cleaner task, which deletes expired beacons.
+func newBeaconCleaner(s expiredBeaconsDeleter) *cleaner.Cleaner {
+	return cleaner.New(func(ctx context.Context) (int, error) {
+		return s.DeleteExpiredBeacons(ctx)
+	}, "bs_beacon")
+}
+
+// expiredRevocationsDeleter deletes expired Revocations from the store.
+type expiredRevocationsDeleter interface {
+	// DeleteExpiredRevocations deletes expired Revocations from the store.
+	DeleteExpiredRevocations(ctx context.Context) (int, error)
+}
+
+// newRevocationCleaner creates a cleaner task, which deletes expired revocations.
+func newRevocationCleaner(s expiredRevocationsDeleter) *cleaner.Cleaner {
+	return cleaner.New(func(ctx context.Context) (int, error) {
+		return s.DeleteExpiredRevocations(ctx)
+	}, "bs_revocation")
+}
diff --git a/go/pkg/sciond/BUILD.bazel b/go/pkg/sciond/BUILD.bazel
index 7f99237af..65d7f1bad 100644
--- a/go/pkg/sciond/BUILD.bazel
+++ b/go/pkg/sciond/BUILD.bazel
@@ -13,7 +13,6 @@ go_library(
         "//go/lib/pathdb:go_default_library",
         "//go/lib/revcache:go_default_library",
         "//go/lib/serrors:go_default_library",
-        "//go/pkg/sciond/config:go_default_library",
         "//go/pkg/sciond/fetcher:go_default_library",
         "//go/pkg/sciond/internal/servers:go_default_library",
         "//go/pkg/trust:go_default_library",
diff --git a/go/pkg/sciond/config/BUILD.bazel b/go/pkg/sciond/config/BUILD.bazel
index 2119de2e6..364098080 100644
--- a/go/pkg/sciond/config/BUILD.bazel
+++ b/go/pkg/sciond/config/BUILD.bazel
@@ -12,11 +12,10 @@ go_library(
         "//go/lib/config:go_default_library",
         "//go/lib/env:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
         "//go/lib/sciond:go_default_library",
         "//go/lib/serrors:go_default_library",
-        "//go/lib/truststorage:go_default_library",
         "//go/lib/util:go_default_library",
+        "//go/pkg/storage:go_default_library",
     ],
 )
 
@@ -27,9 +26,8 @@ go_test(
     deps = [
         "//go/lib/env/envtest:go_default_library",
         "//go/lib/log/logtest:go_default_library",
-        "//go/lib/pathstorage/pathstoragetest:go_default_library",
         "//go/lib/sciond:go_default_library",
-        "//go/lib/truststorage/truststoragetest:go_default_library",
+        "//go/pkg/storage/test:go_default_library",
         "@com_github_pelletier_go_toml//:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
     ],
diff --git a/go/pkg/sciond/config/config.go b/go/pkg/sciond/config/config.go
index 728bc6d81..4bcf2cec9 100644
--- a/go/pkg/sciond/config/config.go
+++ b/go/pkg/sciond/config/config.go
@@ -22,11 +22,10 @@ import (
 	"github.com/scionproto/scion/go/lib/config"
 	"github.com/scionproto/scion/go/lib/env"
 	"github.com/scionproto/scion/go/lib/log"
-	"github.com/scionproto/scion/go/lib/pathstorage"
 	"github.com/scionproto/scion/go/lib/sciond"
 	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/lib/truststorage"
 	"github.com/scionproto/scion/go/lib/util"
+	"github.com/scionproto/scion/go/pkg/storage"
 )
 
 var (
@@ -36,15 +35,14 @@ var (
 var _ config.Config = (*Config)(nil)
 
 type Config struct {
-	General  env.General              `toml:"general,omitempty"`
-	Features env.Features             `toml:"features,omitempty"`
-	Logging  log.Config               `toml:"log,omitempty"`
-	Metrics  env.Metrics              `toml:"metrics,omitempty"`
-	Tracing  env.Tracing              `toml:"tracing,omitempty"`
-	TrustDB  truststorage.TrustDBConf `toml:"trust_db,omitempty"`
-	// PathDB contains the configuration for the PathDB connection.
-	PathDB pathstorage.PathDBConf `toml:"path_db,omitempty"`
-	SD     SDConfig               `toml:"sd,omitempty"`
+	General  env.General      `toml:"general,omitempty"`
+	Features env.Features     `toml:"features,omitempty"`
+	Logging  log.Config       `toml:"log,omitempty"`
+	Metrics  env.Metrics      `toml:"metrics,omitempty"`
+	Tracing  env.Tracing      `toml:"tracing,omitempty"`
+	TrustDB  storage.DBConfig `toml:"trust_db,omitempty"`
+	PathDB   storage.DBConfig `toml:"path_db,omitempty"`
+	SD       SDConfig         `toml:"sd,omitempty"`
 }
 
 func (cfg *Config) InitDefaults() {
@@ -79,8 +77,20 @@ func (cfg *Config) Sample(dst io.Writer, path config.Path, _ config.CtxMap) {
 		&cfg.Logging,
 		&cfg.Metrics,
 		&cfg.Tracing,
-		&cfg.TrustDB,
-		&cfg.PathDB,
+		config.OverrideName(
+			config.FormatData(
+				&cfg.TrustDB,
+				storage.SetID(storage.SampleTrustDB, idSample).Connection,
+			),
+			"trust_db",
+		),
+		config.OverrideName(
+			config.FormatData(
+				&cfg.PathDB,
+				storage.SetID(storage.SamplePathDB, idSample).Connection,
+			),
+			"path_db",
+		),
 		&cfg.SD,
 	)
 }
diff --git a/go/pkg/sciond/sciond.go b/go/pkg/sciond/sciond.go
index 7da5911be..d693ca60b 100644
--- a/go/pkg/sciond/sciond.go
+++ b/go/pkg/sciond/sciond.go
@@ -32,7 +32,6 @@ import (
 	"github.com/scionproto/scion/go/lib/pathdb"
 	"github.com/scionproto/scion/go/lib/revcache"
 	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/pkg/sciond/config"
 	"github.com/scionproto/scion/go/pkg/sciond/fetcher"
 	"github.com/scionproto/scion/go/pkg/sciond/internal/servers"
 	"github.com/scionproto/scion/go/pkg/trust"
@@ -41,8 +40,8 @@ import (
 )
 
 // InitTracer initializes the global tracer.
-func InitTracer(cfg config.Config) (io.Closer, error) {
-	tracer, trCloser, err := cfg.Tracing.NewTracer(cfg.General.ID)
+func InitTracer(tracing env.Tracing, id string) (io.Closer, error) {
+	tracer, trCloser, err := tracing.NewTracer(id)
 	if err != nil {
 		return nil, err
 	}
diff --git a/go/lib/truststorage/BUILD.bazel b/go/pkg/storage/BUILD.bazel
similarity index 55%
rename from go/lib/truststorage/BUILD.bazel
rename to go/pkg/storage/BUILD.bazel
index f3914d662..55588032e 100644
--- a/go/lib/truststorage/BUILD.bazel
+++ b/go/pkg/storage/BUILD.bazel
@@ -3,19 +3,22 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
 go_library(
     name = "go_default_library",
     srcs = [
-        "renewal.go",
         "sample.go",
-        "truststorage.go",
+        "storage.go",
     ],
-    importpath = "github.com/scionproto/scion/go/lib/truststorage",
+    importpath = "github.com/scionproto/scion/go/pkg/storage",
     visibility = ["//visibility:public"],
     deps = [
-        "//go/lib/common:go_default_library",
+        "//go/cs/beacon:go_default_library",
+        "//go/cs/beacon/beacondbsqlite:go_default_library",
+        "//go/lib/addr:go_default_library",
         "//go/lib/config:go_default_library",
         "//go/lib/infra/modules/db:go_default_library",
         "//go/lib/log:go_default_library",
-        "//go/lib/serrors:go_default_library",
-        "//go/lib/util:go_default_library",
+        "//go/lib/pathdb:go_default_library",
+        "//go/lib/pathdb/sqlite:go_default_library",
+        "//go/lib/revcache:go_default_library",
+        "//go/lib/revcache/memrevcache:go_default_library",
         "//go/pkg/trust:go_default_library",
         "//go/pkg/trust/renewal:go_default_library",
         "//go/pkg/trust/renewal/sqlite:go_default_library",
diff --git a/go/cs/beaconstorage/sample.go b/go/pkg/storage/sample.go
similarity index 60%
rename from go/cs/beaconstorage/sample.go
rename to go/pkg/storage/sample.go
index 1fc86770d..573eaabb4 100644
--- a/go/cs/beaconstorage/sample.go
+++ b/go/pkg/storage/sample.go
@@ -1,4 +1,4 @@
-// Copyright 2019 Anapaya Systems
+// Copyright 2020 Anapaya Systems
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,20 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package beaconstorage
+package storage
 
-const beaconDbSample = `
-# The type of trustdb backend. (default sqlite)
-backend = "sqlite"
+const sample = `
+# Connection for the database.
+connection = "%s"
 
-# Connection for the trust database.
-connection = "/var/lib/scion/beacondb/%s.beacon.db"
+# The maximum number of open connections to the database. In case of 0,
+# the limit is not set and uses the go default. (default 0)
+max_open_conns = 0
 
-# The maximum number of open connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_open_conns = ""
-
-# The maximum number of idle connections to the database. In case of the
-# empty string, the limit is not set and uses the go default. (default "")
-max_idle_conns = ""
+# The maximum number of idle connections to the database. In case of 0,
+# the limit is not set and uses the go default. (default 0)
+max_idle_conns = 0
 `
diff --git a/go/pkg/storage/storage.go b/go/pkg/storage/storage.go
new file mode 100644
index 000000000..1028d87c0
--- /dev/null
+++ b/go/pkg/storage/storage.go
@@ -0,0 +1,152 @@
+// Copyright 2020 Anapaya Systems
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package storage provides factories for various application storage backends.
+package storage
+
+import (
+	"fmt"
+	"io"
+
+	"github.com/scionproto/scion/go/cs/beacon"
+	sqlitebeacondb "github.com/scionproto/scion/go/cs/beacon/beacondbsqlite"
+	"github.com/scionproto/scion/go/lib/addr"
+	"github.com/scionproto/scion/go/lib/config"
+	"github.com/scionproto/scion/go/lib/infra/modules/db"
+	"github.com/scionproto/scion/go/lib/log"
+	"github.com/scionproto/scion/go/lib/pathdb"
+	sqlitepathdb "github.com/scionproto/scion/go/lib/pathdb/sqlite"
+	"github.com/scionproto/scion/go/lib/revcache"
+	"github.com/scionproto/scion/go/lib/revcache/memrevcache"
+	"github.com/scionproto/scion/go/pkg/trust"
+	"github.com/scionproto/scion/go/pkg/trust/renewal"
+	sqliterenewaldb "github.com/scionproto/scion/go/pkg/trust/renewal/sqlite"
+	sqlitetrustdb "github.com/scionproto/scion/go/pkg/trust/sqlite"
+)
+
+// Backend indicates the database backend type.
+type Backend string
+
+const (
+	// BackendSqlite indicates an sqlite backend.
+	BackendSqlite Backend = "sqlite"
+	// DefaultPath indicates the default connection string for a generic database.
+	DefaultPath = "/share/scion.db"
+)
+
+// Default samples for various databases.
+var (
+	SampleBeaconDB = DBConfig{
+		Connection: "/share/cache/%s.beacon.db",
+	}
+	SamplePathDB = DBConfig{
+		Connection: "/share/cache/%s.path.db",
+	}
+	SampleRenewalDB = DBConfig{
+		Connection: "/share/data/trustdb/%s.renewal.db",
+	}
+	SampleTrustDB = DBConfig{
+		Connection: "/share/data/trustdb/%s.trust.db",
+	}
+)
+
+// SetID returns a clone of the configuration that has the ID set on the connection string.
+func SetID(cfg DBConfig, id string) *DBConfig {
+	cfg.Connection = fmt.Sprintf(cfg.Connection, id)
+	return &cfg
+}
+
+var _ (config.Config) = (*DBConfig)(nil)
+
+// DBConfig is the configuration for the connection to a database.
+type DBConfig struct {
+	Connection   string `toml:"connection,omitempty"`
+	MaxOpenConns int    `toml:"max_open_conns,omitempty"`
+	MaxIdleConns int    `toml:"max_idle_conns,omitempty"`
+}
+
+// SetConnLimits sets the maximum number of open and idle connections based on the configuration.
+// Limits of 0 mean the Go default will be used.
+func SetConnLimits(d db.LimitSetter, c DBConfig) {
+	if c.MaxOpenConns != 0 {
+		d.SetMaxOpenConns(c.MaxOpenConns)
+	}
+	if c.MaxIdleConns != 0 {
+		d.SetMaxIdleConns(c.MaxIdleConns)
+	}
+}
+
+func (cfg *DBConfig) InitDefaults() {
+	if cfg.Connection == "" {
+		cfg.Connection = DefaultPath
+	}
+}
+
+func (cfg *DBConfig) Validate() error {
+	return nil
+}
+
+// Sample writes a config sample to the writer.
+func (cfg *DBConfig) Sample(dst io.Writer, path config.Path, ctx config.CtxMap) {
+	config.WriteString(dst, sample)
+}
+
+// ConfigName is the key in the toml file.
+func (cfg *DBConfig) ConfigName() string {
+	return "db"
+}
+
+func NewBeaconStorage(c DBConfig, ia addr.IA) (beacon.DB, error) {
+	log.Info("Connecting BeaconDB", "backend", BackendSqlite, "connection", c.Connection)
+	db, err := sqlitebeacondb.New(c.Connection, ia)
+	if err != nil {
+		return nil, err
+	}
+	SetConnLimits(db, c)
+	return db, nil
+}
+
+func NewPathStorage(c DBConfig) (pathdb.PathDB, error) {
+	log.Info("Connecting PathDB", "backend", BackendSqlite, "connection", c.Connection)
+	db, err := sqlitepathdb.New(c.Connection)
+	if err != nil {
+		return nil, err
+	}
+	SetConnLimits(db, c)
+	return db, nil
+}
+
+func NewRevocationStorage() revcache.RevCache {
+	return memrevcache.New()
+}
+
+func NewTrustStorage(c DBConfig) (trust.DB, error) {
+	log.Info("Connecting TrustDB", "backend", BackendSqlite, "connection", c.Connection)
+	db, err := sqlitetrustdb.New(c.Connection)
+	if err != nil {
+		return nil, err
+	}
+	SetConnLimits(db, c)
+	return db, nil
+}
+
+func NewRenewalStorage(c DBConfig) (renewal.DB, error) {
+	log.Info("Connecting RenewalDB", "backend", BackendSqlite, "connection", c.Connection)
+	db, err := sqliterenewaldb.New(c.Connection)
+	if err != nil {
+		return nil, err
+	}
+	SetConnLimits(db, c)
+	return db, nil
+}
diff --git a/go/sciond/BUILD.bazel b/go/sciond/BUILD.bazel
index 3dcf13eeb..882efd8e0 100644
--- a/go/sciond/BUILD.bazel
+++ b/go/sciond/BUILD.bazel
@@ -21,7 +21,6 @@ go_library(
         "//go/lib/infra/modules/itopo:go_default_library",
         "//go/lib/log:go_default_library",
         "//go/lib/pathdb:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
         "//go/lib/periodic:go_default_library",
         "//go/lib/prom:go_default_library",
         "//go/lib/revcache:go_default_library",
@@ -31,6 +30,7 @@ go_library(
         "//go/pkg/sciond:go_default_library",
         "//go/pkg/sciond/config:go_default_library",
         "//go/pkg/sciond/fetcher:go_default_library",
+        "//go/pkg/storage:go_default_library",
         "//go/pkg/trust:go_default_library",
         "//go/pkg/trust/compat:go_default_library",
         "//go/pkg/trust/metrics:go_default_library",
diff --git a/go/sciond/main.go b/go/sciond/main.go
index 1cac68c4c..8473f0bdd 100644
--- a/go/sciond/main.go
+++ b/go/sciond/main.go
@@ -31,7 +31,6 @@ import (
 	"github.com/scionproto/scion/go/lib/infra/modules/itopo"
 	"github.com/scionproto/scion/go/lib/log"
 	"github.com/scionproto/scion/go/lib/pathdb"
-	"github.com/scionproto/scion/go/lib/pathstorage"
 	"github.com/scionproto/scion/go/lib/periodic"
 	"github.com/scionproto/scion/go/lib/prom"
 	"github.com/scionproto/scion/go/lib/revcache"
@@ -41,6 +40,7 @@ import (
 	"github.com/scionproto/scion/go/pkg/sciond"
 	"github.com/scionproto/scion/go/pkg/sciond/config"
 	"github.com/scionproto/scion/go/pkg/sciond/fetcher"
+	"github.com/scionproto/scion/go/pkg/storage"
 	"github.com/scionproto/scion/go/pkg/trust"
 	"github.com/scionproto/scion/go/pkg/trust/compat"
 	trustmetrics "github.com/scionproto/scion/go/pkg/trust/metrics"
@@ -96,16 +96,18 @@ func run(file string) error {
 		return err
 	}
 
-	closer, err := sciond.InitTracer(cfg)
+	closer, err := sciond.InitTracer(cfg.Tracing, cfg.General.ID)
 	if err != nil {
 		return serrors.WrapStr("initializing tracer", err)
 	}
 	defer closer.Close()
 
-	pathDB, revCache, err := pathstorage.NewPathStorage(cfg.PathDB)
+	revCache := storage.NewRevocationStorage()
+	pathDB, err := storage.NewPathStorage(cfg.PathDB)
 	if err != nil {
 		return serrors.WrapStr("initializing path storage", err)
 	}
+	pathDB = pathdb.WithMetrics(string(storage.BackendSqlite), pathDB)
 	defer pathDB.Close()
 	defer revCache.Close()
 	cleaner := periodic.Start(pathdb.NewCleaner(pathDB, "sd_segments"),
@@ -115,11 +117,11 @@ func run(file string) error {
 		10*time.Second, 10*time.Second)
 	defer rcCleaner.Stop()
 
-	trustDB, err := cfg.TrustDB.New()
+	trustDB, err := storage.NewTrustStorage(cfg.TrustDB)
 	if err != nil {
 		return serrors.WrapStr("initializing trust database", err)
 	}
-	trustDB = trustmetrics.WrapDB(string(cfg.TrustDB.Backend()), trustDB)
+	trustDB = trustmetrics.WrapDB(string(storage.BackendSqlite), trustDB)
 	defer trustDB.Close()
 	engine, err := sciond.TrustEngine(cfg.General.ConfigDir, trustDB)
 	if err != nil {
diff --git a/go_deps.bzl b/go_deps.bzl
index c82de0d89..fc921f557 100644
--- a/go_deps.bzl
+++ b/go_deps.bzl
@@ -17,14 +17,14 @@ def go_deps():
     go_repository(
         name = "com_github_alecthomas_template",
         importpath = "github.com/alecthomas/template",
-        sum = "h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=",
-        version = "v0.0.0-20160405071501-a0175ee3bccc",
+        sum = "h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=",
+        version = "v0.0.0-20190718012654-fb15b899a751",
     )
     go_repository(
         name = "com_github_alecthomas_units",
         importpath = "github.com/alecthomas/units",
-        sum = "h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=",
-        version = "v0.0.0-20151022065526-2efee857e7cf",
+        sum = "h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=",
+        version = "v0.0.0-20190717042225-c3de453c63f4",
     )
     go_repository(
         name = "com_github_anmitsu_go_shlex",
@@ -86,6 +86,12 @@ def go_deps():
         sum = "h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=",
         version = "v1.1.0",
     )
+    go_repository(
+        name = "com_github_cespare_xxhash_v2",
+        importpath = "github.com/cespare/xxhash/v2",
+        sum = "h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=",
+        version = "v2.1.1",
+    )
     go_repository(
         name = "com_github_cheekybits_genny",
         importpath = "github.com/cheekybits/genny",
@@ -209,8 +215,8 @@ def go_deps():
     go_repository(
         name = "com_github_go_kit_kit",
         importpath = "github.com/go-kit/kit",
-        sum = "h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=",
-        version = "v0.8.0",
+        sum = "h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=",
+        version = "v0.9.0",
     )
     go_repository(
         name = "com_github_go_logfmt_logfmt",
@@ -401,8 +407,8 @@ def go_deps():
     go_repository(
         name = "com_github_json_iterator_go",
         importpath = "github.com/json-iterator/go",
-        sum = "h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=",
-        version = "v1.1.7",
+        sum = "h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=",
+        version = "v1.1.9",
     )
     go_repository(
         name = "com_github_jstemmer_go_junit_report",
@@ -629,8 +635,8 @@ def go_deps():
     go_repository(
         name = "com_github_pelletier_go_toml",
         importpath = "github.com/pelletier/go-toml",
-        sum = "h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=",
-        version = "v1.8.0",
+        sum = "h1:0r6tAXtt8p5+IJtshL5f+5E/z0qH2aE89UmV4/tRF64=",
+        version = "v1.8.1-0.20200708110244-34de94e6a887",
     )
     go_repository(
         name = "com_github_philhofer_fwd",
@@ -653,26 +659,26 @@ def go_deps():
     go_repository(
         name = "com_github_prometheus_client_golang",
         importpath = "github.com/prometheus/client_golang",
-        sum = "h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=",
-        version = "v1.1.0",
+        sum = "h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=",
+        version = "v1.6.0",
     )
     go_repository(
         name = "com_github_prometheus_client_model",
         importpath = "github.com/prometheus/client_model",
-        sum = "h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=",
-        version = "v0.0.0-20190812154241-14fe0d1b01d4",
+        sum = "h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=",
+        version = "v0.2.0",
     )
     go_repository(
         name = "com_github_prometheus_common",
         importpath = "github.com/prometheus/common",
-        sum = "h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=",
-        version = "v0.6.0",
+        sum = "h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=",
+        version = "v0.9.1",
     )
     go_repository(
         name = "com_github_prometheus_procfs",
         importpath = "github.com/prometheus/procfs",
-        sum = "h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=",
-        version = "v0.0.3",
+        sum = "h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=",
+        version = "v0.0.11",
     )
     go_repository(
         name = "com_github_prometheus_tsdb",
@@ -839,8 +845,8 @@ def go_deps():
     go_repository(
         name = "com_github_sirupsen_logrus",
         importpath = "github.com/sirupsen/logrus",
-        sum = "h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=",
-        version = "v1.2.0",
+        sum = "h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=",
+        version = "v1.4.2",
     )
     go_repository(
         name = "com_github_smartystreets_assertions",
@@ -930,8 +936,8 @@ def go_deps():
     go_repository(
         name = "com_github_stretchr_testify",
         importpath = "github.com/stretchr/testify",
-        sum = "h1:Ko2LQMrRU+Oy/+EDBwX7eZ2jp3C47eDBB8EIhKTun+I=",
-        version = "v1.3.1-0.20190311161405-34c6fa2dc709",
+        sum = "h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=",
+        version = "v1.4.0",
     )
     go_repository(
         name = "com_github_syndtr_gocapability",
@@ -1068,8 +1074,8 @@ def go_deps():
     go_repository(
         name = "in_gopkg_check_v1",
         importpath = "gopkg.in/check.v1",
-        sum = "h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=",
-        version = "v1.0.0-20180628173108-788fd7840127",
+        sum = "h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=",
+        version = "v1.0.0-20190902080502-41f04d3bba15",
     )
     go_repository(
         name = "in_gopkg_fsnotify_v1",
@@ -1224,14 +1230,14 @@ def go_deps():
     go_repository(
         name = "org_golang_x_sync",
         importpath = "golang.org/x/sync",
-        sum = "h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=",
-        version = "v0.0.0-20190423024810-112230192c58",
+        sum = "h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=",
+        version = "v0.0.0-20190911185100-cd5d95a43a6e",
     )
     go_repository(
         name = "org_golang_x_sys",
         importpath = "golang.org/x/sys",
-        sum = "h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=",
-        version = "v0.0.0-20200223170610-d5e6a3e2c0ae",
+        sum = "h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=",
+        version = "v0.0.0-20200420163511-1957bb5e6d1f",
     )
     go_repository(
         name = "org_golang_x_text",
diff --git a/licenses/data/com_github_cespare_xxhash_v2/LICENSE.txt b/licenses/data/com_github_cespare_xxhash_v2/LICENSE.txt
new file mode 100644
index 000000000..24b53065f
--- /dev/null
+++ b/licenses/data/com_github_cespare_xxhash_v2/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2016 Caleb Spare
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/licenses/data/com_github_prometheus_client_model/ruby/LICENSE b/licenses/data/com_github_prometheus_client_model/ruby/LICENSE
deleted file mode 100644
index 11069edd7..000000000
--- a/licenses/data/com_github_prometheus_client_model/ruby/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/python/topology/go.py b/python/topology/go.py
index 89921e930..055f85e7b 100755
--- a/python/topology/go.py
+++ b/python/topology/go.py
@@ -119,15 +119,12 @@ class GoGenerator(object):
             },
             'log': self._log_entry(name),
             'trust_db': {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.trust.db' % name),
             },
             'beacon_db':     {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.beacon.db' % name),
             },
             'path_db': {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.path.db' % name),
             },
             'tracing': self._tracing_entry(),
@@ -136,7 +133,6 @@ class GoGenerator(object):
         }
         if ca:
             raw_entry['renewal_db'] = {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.renewal.db' % name),
             }
         return raw_entry
@@ -168,7 +164,6 @@ class GoGenerator(object):
             },
             'log': self._log_entry(name),
             'trust_db': {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.trust.db' % name),
             },
             'tracing': self._tracing_entry(),
@@ -250,7 +245,6 @@ class GoGenerator(object):
             },
             'log': self._log_entry(name),
             'trust_db': {
-                'backend': 'sqlite',
                 'connection': os.path.join(self.db_dir, '%s.trust.db' % name),
             },
             'path_db': {


Test patch:
diff --git a/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel b/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel
deleted file mode 100644
index 013b0d852..000000000
--- a/go/cs/beaconstorage/beaconstoragetest/BUILD.bazel
+++ /dev/null
@@ -1,26 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["config.go"],
-    importpath = "github.com/scionproto/scion/go/cs/beaconstorage/beaconstoragetest",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//go/cs/beaconstorage:go_default_library",
-        "//go/lib/infra/modules/db:go_default_library",
-        "//go/lib/util:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["config_test.go"],
-    embed = [":go_default_library"],
-    deps = [
-        "//go/cs/beaconstorage:go_default_library",
-        "//go/lib/config:go_default_library",
-        "@com_github_pelletier_go_toml//:go_default_library",
-        "@com_github_stretchr_testify//require:go_default_library",
-    ],
-)
diff --git a/go/cs/beaconstorage/beaconstoragetest/config.go b/go/cs/beaconstorage/beaconstoragetest/config.go
deleted file mode 100644
index d0aab3e70..000000000
--- a/go/cs/beaconstorage/beaconstoragetest/config.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beaconstoragetest
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-
-	"github.com/scionproto/scion/go/cs/beaconstorage"
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/util"
-)
-
-// InitTestBeaconDBConf initializes the config with values that should be
-// overwritten during parsing.
-func InitTestBeaconDBConf(cfg *beaconstorage.BeaconDBConf) {
-	if *cfg == nil {
-		*cfg = make(beaconstorage.BeaconDBConf)
-	}
-	(*cfg)[db.MaxOpenConnsKey] = "maxOpenConns"
-	(*cfg)[db.MaxIdleConnsKey] = "maxIdleConns"
-}
-
-// CheckTestBeaconDBConf checks that the values are as expected from the sample.
-func CheckTestBeaconDBConf(t *testing.T, cfg *beaconstorage.BeaconDBConf, id string) {
-	util.LowerKeys(*cfg)
-	assert.False(t, isSet(cfg.MaxOpenConns()))
-	assert.False(t, isSet(cfg.MaxIdleConns()))
-	assert.Equal(t, beaconstorage.BackendSqlite, cfg.Backend())
-	assert.Equal(t, fmt.Sprintf("/var/lib/scion/beacondb/%s.beacon.db", id), cfg.Connection())
-}
-
-func isSet(_ int, set bool) bool {
-	return set
-}
diff --git a/go/cs/beaconstorage/beaconstoragetest/config_test.go b/go/cs/beaconstorage/beaconstoragetest/config_test.go
deleted file mode 100644
index b5aadd145..000000000
--- a/go/cs/beaconstorage/beaconstoragetest/config_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beaconstoragetest
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/pelletier/go-toml"
-	"github.com/stretchr/testify/require"
-
-	"github.com/scionproto/scion/go/cs/beaconstorage"
-	"github.com/scionproto/scion/go/lib/config"
-)
-
-func TestBeaconDBConfSample(t *testing.T) {
-	var sample bytes.Buffer
-	var cfg beaconstorage.BeaconDBConf
-	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
-	InitTestBeaconDBConf(&cfg)
-	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
-	require.NoError(t, err)
-	CheckTestBeaconDBConf(t, &cfg, "test")
-}
diff --git a/go/cs/config/config_test.go b/go/cs/config/config_test.go
index d9abe2928..b6b8904c7 100644
--- a/go/cs/config/config_test.go
+++ b/go/cs/config/config_test.go
@@ -22,13 +22,11 @@ import (
 	"github.com/pelletier/go-toml"
 	"github.com/stretchr/testify/assert"
 
-	"github.com/scionproto/scion/go/cs/beaconstorage/beaconstoragetest"
 	"github.com/scionproto/scion/go/lib/ctrl/path_mgmt"
 	"github.com/scionproto/scion/go/lib/env/envtest"
 	"github.com/scionproto/scion/go/lib/log/logtest"
-	"github.com/scionproto/scion/go/lib/pathstorage/pathstoragetest"
-	"github.com/scionproto/scion/go/lib/truststorage/truststoragetest"
 	"github.com/scionproto/scion/go/lib/util"
+	storagetest "github.com/scionproto/scion/go/pkg/storage/test"
 )
 
 func TestConfigSample(t *testing.T) {
@@ -59,9 +57,6 @@ func TestInvalidTTL(t *testing.T) {
 func InitTestConfig(cfg *Config) {
 	envtest.InitTest(&cfg.General, &cfg.Metrics, &cfg.Tracing, nil)
 	logtest.InitTestLogging(&cfg.Logging)
-	truststoragetest.InitTestConfig(&cfg.TrustDB)
-	beaconstoragetest.InitTestBeaconDBConf(&cfg.BeaconDB)
-	pathstoragetest.InitTestPathDBConf(&cfg.PathDB)
 	InitTestBSConfig(&cfg.BS)
 	InitTestCA(&cfg.CA)
 }
@@ -80,9 +75,10 @@ func InitTestPolicies(cfg *Policies) {
 func CheckTestConfig(t *testing.T, cfg *Config, id string) {
 	envtest.CheckTest(t, &cfg.General, &cfg.Metrics, &cfg.Tracing, nil, id)
 	logtest.CheckTestLogging(t, &cfg.Logging, id)
-	truststoragetest.CheckTestConfig(t, &cfg.TrustDB, id)
-	beaconstoragetest.CheckTestBeaconDBConf(t, &cfg.BeaconDB, id)
-	pathstoragetest.CheckTestPathDBConf(t, &cfg.PathDB, id)
+	storagetest.CheckTestTrustDBConfig(t, &cfg.TrustDB, id)
+	storagetest.CheckTestBeaconDBConfig(t, &cfg.BeaconDB, id)
+	storagetest.CheckTestPathDBConfig(t, &cfg.PathDB, id)
+	storagetest.CheckTestRenewalDBConfig(t, &cfg.RenewalDB, id)
 	CheckTestBSConfig(t, &cfg.BS)
 	CheckTestPSConfig(t, &cfg.PS, id)
 	CheckTestCA(t, &cfg.CA, id)
diff --git a/go/lib/pathstorage/pathstoragetest/BUILD.bazel b/go/lib/pathstorage/pathstoragetest/BUILD.bazel
deleted file mode 100644
index ef2b084ca..000000000
--- a/go/lib/pathstorage/pathstoragetest/BUILD.bazel
+++ /dev/null
@@ -1,26 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["config.go"],
-    importpath = "github.com/scionproto/scion/go/lib/pathstorage/pathstoragetest",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//go/lib/infra/modules/db:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
-        "//go/lib/util:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["config_test.go"],
-    embed = [":go_default_library"],
-    deps = [
-        "//go/lib/config:go_default_library",
-        "//go/lib/pathstorage:go_default_library",
-        "@com_github_pelletier_go_toml//:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
-    ],
-)
diff --git a/go/lib/pathstorage/pathstoragetest/config.go b/go/lib/pathstorage/pathstoragetest/config.go
deleted file mode 100644
index 1c7355777..000000000
--- a/go/lib/pathstorage/pathstoragetest/config.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pathstoragetest
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/pathstorage"
-	"github.com/scionproto/scion/go/lib/util"
-)
-
-func InitTestPathDBConf(cfg *pathstorage.PathDBConf) {
-	if *cfg == nil {
-		*cfg = make(pathstorage.PathDBConf)
-	}
-	(*cfg)[db.MaxOpenConnsKey] = "maxOpenConns"
-	(*cfg)[db.MaxIdleConnsKey] = "maxIdleConns"
-}
-
-func InitTestRevCacheConf(cfg *pathstorage.RevCacheConf) {
-	if *cfg == nil {
-		*cfg = make(pathstorage.RevCacheConf)
-	}
-	(*cfg)[db.MaxOpenConnsKey] = "maxOpenConns"
-	(*cfg)[db.MaxIdleConnsKey] = "maxIdleConns"
-}
-
-func CheckTestPathDBConf(t *testing.T, cfg *pathstorage.PathDBConf, id string) {
-	util.LowerKeys(*cfg)
-	assert.False(t, isSet(cfg.MaxOpenConns()))
-	assert.False(t, isSet(cfg.MaxIdleConns()))
-	assert.Equal(t, pathstorage.BackendSqlite, cfg.Backend())
-	assert.Equal(t, fmt.Sprintf("/var/lib/scion/pathdb/%s.path.db", id), cfg.Connection())
-}
-
-func CheckTestRevCacheConf(t *testing.T, cfg *pathstorage.RevCacheConf) {
-	util.LowerKeys(*cfg)
-	assert.False(t, isSet(cfg.MaxOpenConns()))
-	assert.False(t, isSet(cfg.MaxIdleConns()))
-	assert.Equal(t, pathstorage.BackendMem, cfg.Backend())
-}
-
-func isSet(_ int, set bool) bool {
-	return set
-}
diff --git a/go/lib/pathstorage/pathstoragetest/config_test.go b/go/lib/pathstorage/pathstoragetest/config_test.go
deleted file mode 100644
index f8e224f4d..000000000
--- a/go/lib/pathstorage/pathstoragetest/config_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pathstoragetest
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/pelletier/go-toml"
-	"github.com/stretchr/testify/assert"
-
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/pathstorage"
-)
-
-func TestPathDBConfSample(t *testing.T) {
-	var sample bytes.Buffer
-	var cfg pathstorage.PathDBConf
-	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
-	InitTestPathDBConf(&cfg)
-	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
-	assert.NoError(t, err)
-	CheckTestPathDBConf(t, &cfg, "test")
-}
-
-func TestRevCacheConfSample(t *testing.T) {
-	var sample bytes.Buffer
-	var cfg pathstorage.RevCacheConf
-	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
-	InitTestRevCacheConf(&cfg)
-	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
-	assert.NoError(t, err)
-	CheckTestRevCacheConf(t, &cfg)
-}
diff --git a/go/lib/truststorage/truststoragetest/BUILD.bazel b/go/lib/truststorage/truststoragetest/BUILD.bazel
deleted file mode 100644
index cf5e18f00..000000000
--- a/go/lib/truststorage/truststoragetest/BUILD.bazel
+++ /dev/null
@@ -1,26 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["config.go"],
-    importpath = "github.com/scionproto/scion/go/lib/truststorage/truststoragetest",
-    visibility = ["//visibility:public"],
-    deps = [
-        "//go/lib/infra/modules/db:go_default_library",
-        "//go/lib/truststorage:go_default_library",
-        "//go/lib/util:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["config_test.go"],
-    embed = [":go_default_library"],
-    deps = [
-        "//go/lib/config:go_default_library",
-        "//go/lib/truststorage:go_default_library",
-        "@com_github_pelletier_go_toml//:go_default_library",
-        "@com_github_stretchr_testify//assert:go_default_library",
-    ],
-)
diff --git a/go/lib/truststorage/truststoragetest/config.go b/go/lib/truststorage/truststoragetest/config.go
deleted file mode 100644
index 2d902e96c..000000000
--- a/go/lib/truststorage/truststoragetest/config.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package truststoragetest
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-
-	"github.com/scionproto/scion/go/lib/infra/modules/db"
-	"github.com/scionproto/scion/go/lib/truststorage"
-	"github.com/scionproto/scion/go/lib/util"
-)
-
-func InitTestConfig(cfg *truststorage.TrustDBConf) {
-	if *cfg == nil {
-		*cfg = make(truststorage.TrustDBConf)
-	}
-	(*cfg)[db.MaxOpenConnsKey] = "maxOpenConns"
-	(*cfg)[db.MaxIdleConnsKey] = "maxIdleConns"
-	(*cfg)[truststorage.CachedKey] = "set"
-}
-
-func CheckTestConfig(t *testing.T, cfg *truststorage.TrustDBConf, id string) {
-	util.LowerKeys(*cfg)
-	assert.False(t, isSet(cfg.MaxOpenConns()))
-	assert.False(t, isSet(cfg.MaxIdleConns()))
-	assert.True(t, cfg.Cached())
-	assert.Equal(t, truststorage.BackendSqlite, cfg.Backend())
-	assert.Equal(t, fmt.Sprintf("/var/lib/scion/spki/%s.trust.db", id), cfg.Connection())
-}
-
-func isSet(_ int, set bool) bool {
-	return set
-}
-
-func InitRenewalTestConfig(cfg *truststorage.RenewalDBConf) {
-	if *cfg == nil {
-		*cfg = make(truststorage.RenewalDBConf)
-	}
-	(*cfg)[db.MaxOpenConnsKey] = "maxOpenConns"
-	(*cfg)[db.MaxIdleConnsKey] = "maxIdleConns"
-}
-
-func CheckRenewalTestConfig(t *testing.T, cfg *truststorage.RenewalDBConf, id string) {
-	util.LowerKeys(*cfg)
-	assert.False(t, isSet(cfg.MaxOpenConns()))
-	assert.False(t, isSet(cfg.MaxIdleConns()))
-	assert.Equal(t, truststorage.BackendSqlite, cfg.Backend())
-	assert.Equal(t, fmt.Sprintf("/var/lib/scion/spki/%s.renewal.db", id), cfg.Connection())
-}
diff --git a/go/lib/truststorage/truststoragetest/config_test.go b/go/lib/truststorage/truststoragetest/config_test.go
deleted file mode 100644
index 2ea431b2a..000000000
--- a/go/lib/truststorage/truststoragetest/config_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2019 Anapaya Systems
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package truststoragetest
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/pelletier/go-toml"
-	"github.com/stretchr/testify/assert"
-
-	"github.com/scionproto/scion/go/lib/config"
-	"github.com/scionproto/scion/go/lib/truststorage"
-)
-
-func TestConfigSample(t *testing.T) {
-	var sample bytes.Buffer
-	var cfg truststorage.TrustDBConf
-	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
-	InitTestConfig(&cfg)
-	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
-	assert.NoError(t, err)
-	CheckTestConfig(t, &cfg, "test")
-}
-
-func TestRenewalConfigSample(t *testing.T) {
-	var sample bytes.Buffer
-	var cfg truststorage.RenewalDBConf
-	cfg.Sample(&sample, nil, map[string]string{config.ID: "test"})
-	InitRenewalTestConfig(&cfg)
-	err := toml.NewDecoder(bytes.NewReader(sample.Bytes())).Strict(true).Decode(&cfg)
-	assert.NoError(t, err)
-	CheckRenewalTestConfig(t, &cfg, "test")
-}
diff --git a/go/pkg/sciond/config/config_test.go b/go/pkg/sciond/config/config_test.go
index 27b1b096e..63a9722ea 100644
--- a/go/pkg/sciond/config/config_test.go
+++ b/go/pkg/sciond/config/config_test.go
@@ -23,9 +23,8 @@ import (
 
 	"github.com/scionproto/scion/go/lib/env/envtest"
 	"github.com/scionproto/scion/go/lib/log/logtest"
-	"github.com/scionproto/scion/go/lib/pathstorage/pathstoragetest"
 	"github.com/scionproto/scion/go/lib/sciond"
-	"github.com/scionproto/scion/go/lib/truststorage/truststoragetest"
+	storagetest "github.com/scionproto/scion/go/pkg/storage/test"
 )
 
 func TestConfigSample(t *testing.T) {
@@ -42,8 +41,6 @@ func TestConfigSample(t *testing.T) {
 func InitTestConfig(cfg *Config) {
 	envtest.InitTest(&cfg.General, &cfg.Metrics, &cfg.Tracing, nil)
 	logtest.InitTestLogging(&cfg.Logging)
-	truststoragetest.InitTestConfig(&cfg.TrustDB)
-	pathstoragetest.InitTestPathDBConf(&cfg.PathDB)
 	InitTestSDConfig(&cfg.SD)
 }
 
@@ -54,8 +51,8 @@ func InitTestSDConfig(cfg *SDConfig) {
 func CheckTestConfig(t *testing.T, cfg *Config, id string) {
 	envtest.CheckTest(t, &cfg.General, &cfg.Metrics, &cfg.Tracing, nil, id)
 	logtest.CheckTestLogging(t, &cfg.Logging, id)
-	truststoragetest.CheckTestConfig(t, &cfg.TrustDB, id)
-	pathstoragetest.CheckTestPathDBConf(t, &cfg.PathDB, id)
+	storagetest.CheckTestTrustDBConfig(t, &cfg.TrustDB, id)
+	storagetest.CheckTestPathDBConfig(t, &cfg.PathDB, id)
 	CheckTestSDConfig(t, &cfg.SD, id)
 }
 
diff --git a/go/pkg/storage/test/BUILD.bazel b/go/pkg/storage/test/BUILD.bazel
new file mode 100644
index 000000000..21ebc80e3
--- /dev/null
+++ b/go/pkg/storage/test/BUILD.bazel
@@ -0,0 +1,12 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["config.go"],
+    importpath = "github.com/scionproto/scion/go/pkg/storage/test",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//go/pkg/storage:go_default_library",
+        "@com_github_stretchr_testify//assert:go_default_library",
+    ],
+)
diff --git a/go/pkg/storage/test/config.go b/go/pkg/storage/test/config.go
new file mode 100644
index 000000000..e0d277390
--- /dev/null
+++ b/go/pkg/storage/test/config.go
@@ -0,0 +1,39 @@
+// Copyright 2019 Anapaya Systems
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/scionproto/scion/go/pkg/storage"
+)
+
+func CheckTestBeaconDBConfig(t *testing.T, cfg *storage.DBConfig, id string) {
+	assert.Equal(t, storage.SetID(storage.SampleBeaconDB, id), cfg)
+}
+
+func CheckTestPathDBConfig(t *testing.T, cfg *storage.DBConfig, id string) {
+	assert.Equal(t, storage.SetID(storage.SamplePathDB, id), cfg)
+}
+
+func CheckTestRenewalDBConfig(t *testing.T, cfg *storage.DBConfig, id string) {
+	assert.Equal(t, storage.SetID(storage.SampleRenewalDB, id), cfg)
+}
+
+func CheckTestTrustDBConfig(t *testing.T, cfg *storage.DBConfig, id string) {
+	assert.Equal(t, storage.SetID(storage.SampleTrustDB, id), cfg)
+}