diff --git a/cmd/frednode/main.go b/cmd/frednode/main.go
index 79260c811f933e6b34f5641321a1846a52093ac6..d4d83ecfc4cc3d850b7c72586b18f26f3dfb0db5 100644
--- a/cmd/frednode/main.go
+++ b/cmd/frednode/main.go
@@ -3,9 +3,11 @@ package main
 import (
 	"github.com/BurntSushi/toml"
 	"github.com/alecthomas/kingpin"
+	"github.com/go-errors/errors"
 	"github.com/mmcloughlin/geohash"
 	"github.com/rs/zerolog"
 	"github.com/rs/zerolog/log"
+	"gitlab.tu-berlin.de/mcc-fred/fred/pkg/dynamoconnect"
 	"gitlab.tu-berlin.de/mcc-fred/fred/pkg/interconnection"
 	"os"
 	"os/signal"
@@ -45,6 +47,12 @@ type fredConfig struct {
 	RemoteStore struct {
 		Host string `toml:"host"`
 	} `toml:"remotestore"`
+	DynamoDB struct {
+		Table      string `toml:"table"`
+		Region     string `toml:"region"`
+		PublicKey  string `toml:"publickey"`
+		PrivateKey string `toml:"privatekey"`
+	} `toml:"dynamodb"`
 	Bdb struct {
 		Path string `toml:"path"`
 	} `toml:"badgerdb"`
@@ -60,16 +68,20 @@ var (
 	wsHost            = kingpin.Flag("ws-host", "Host address of webserver.").String()
 	wsSSL             = kingpin.Flag("use-tls", "Use TLS/SSL to serve over HTTPS. Works only if host argument is a FQDN.").PlaceHolder("USE-SSL").Bool()
 	zmqHost           = kingpin.Flag("zmq-host", "(Publicly reachable) address of this zmq server.").String()
-	adaptor           = kingpin.Flag("adaptor", "Storage adaptor, can be \"remote\", \"badgerdb\", \"memory\".").Enum("leveldb", "remote", "badgerdb", "memory")
+	adaptor           = kingpin.Flag("adaptor", "Storage adaptor, can be \"remote\", \"badgerdb\", \"memory\", \"dynamo\".").Enum("remote", "badgerdb", "memory", "dynamo")
 	logLevel          = kingpin.Flag("log-level", "Log level, can be \"debug\", \"info\" ,\"warn\", \"error\", \"fatal\", \"panic\".").Enum("debug", "info", "warn", "errors", "fatal", "panic")
 	handler           = kingpin.Flag("handler", "Mode of log handler, can be \"dev\", \"prod\".").Enum("dev", "prod")
 	remoteStorageHost = kingpin.Flag("remote-storage-host", "Host address of GRPC Server.").String()
+	dynamoTable       = kingpin.Flag("dynamo-table", "AWS table for DynamoDB storage backend.").String()
+	dynamoRegion      = kingpin.Flag("dynamo-region", "AWS region for DynamoDB storage backend.").String()
+
 	// TODO this should be a list of nodes. One node is enough, but if we want reliability we should accept multiple etcd nodes
 	naseHost = kingpin.Flag("nase-host", "Host where the etcd-server runs").String()
 	bdbPath  = kingpin.Flag("badgerdb-path", "Path to the badgerdb database").String()
 )
 
 func main() {
+	var err error
 
 	kingpin.Version(apiversion)
 	kingpin.HelpFlag.Short('h')
@@ -121,6 +133,12 @@ func main() {
 	if *remoteStorageHost != "" {
 		fc.RemoteStore.Host = *remoteStorageHost
 	}
+	if *dynamoTable != "" {
+		fc.DynamoDB.Table = *dynamoTable
+	}
+	if *dynamoRegion != "" {
+		fc.DynamoDB.Region = *dynamoRegion
+	}
 	if *naseHost != "" {
 		fc.NaSe.Host = *naseHost
 	}
@@ -181,6 +199,11 @@ func main() {
 		store = badgerdb.NewMemory()
 	case "remote":
 		store = storage.NewClient(fc.RemoteStore.Host)
+	case "dynamo":
+		store, err = dynamoconnect.New(fc.DynamoDB.Table, fc.DynamoDB.Region)
+		if err != nil {
+			log.Fatal().Msgf("could not open a dynamo connection: %s", err.(*errors.Error).ErrorStack())
+		}
 	default:
 		log.Fatal().Msg("unknown storage backend")
 	}
diff --git a/config.toml b/config.toml
index ab58bd5eac5e9c7287d0db565a9579235494b25b..2d2cbecc6b726553b3ca1d3fac08b25946e026bc 100644
--- a/config.toml
+++ b/config.toml
@@ -17,6 +17,10 @@ adaptor = "badgerdb"
 [zmq]
 host = ":5555"
 
+[dynamodb]
+table = "fredtable"
+region = "eu-central-1"
+
 [remotestore]
 host = "localhost:1337"
 
diff --git a/go.mod b/go.mod
index d5462b4435ee3c0bea96fa60415dec5e74e11882..8e7de19dc8b28f492cbe0f93fa67a7dcd34061fa 100644
--- a/go.mod
+++ b/go.mod
@@ -8,6 +8,7 @@ require (
 	github.com/alecthomas/kingpin v2.2.6+incompatible
 	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
 	github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
+	github.com/aws/aws-sdk-go v1.34.13
 	github.com/coreos/go-semver v0.3.0 // indirect
 	github.com/dgraph-io/badger/v2 v2.0.3
 	github.com/gin-contrib/logger v0.0.2
@@ -17,9 +18,10 @@ require (
 	github.com/gogo/protobuf v1.3.1 // indirect
 	github.com/golang/protobuf v1.4.1
 	github.com/google/uuid v1.1.1 // indirect
+	github.com/gusaul/go-dynamock v0.0.0-20200325102056-aaeeb0c0e9c1
 	github.com/mmcloughlin/geohash v0.9.0
 	github.com/rs/zerolog v1.17.2
-	github.com/stretchr/testify v1.4.0
+	github.com/stretchr/testify v1.5.1
 	github.com/syndtr/goleveldb v1.0.0
 	github.com/zeromq/goczmq v4.1.0+incompatible
 	go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb
diff --git a/go.sum b/go.sum
index 3f3913739e84d913d45d0a0a3502fde8deb8ab27..3d2eb76764c7ec3a929d66c3a985ea05e7577239 100644
--- a/go.sum
+++ b/go.sum
@@ -17,6 +17,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/aws/aws-sdk-go v1.34.13 h1:wwNWSUh4FGJxXVOVVNj2lWI8wTe5hK8sGWlK7ziEcgg=
+github.com/aws/aws-sdk-go v1.34.13/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -80,6 +82,7 @@ github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotf
 github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
 github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
 github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -125,10 +128,14 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
 github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/gusaul/go-dynamock v0.0.0-20200325102056-aaeeb0c0e9c1 h1:lPA38imc4ThIPhJ10toIuYU2EQFfH8nlFGbPiydKLwk=
+github.com/gusaul/go-dynamock v0.0.0-20200325102056-aaeeb0c0e9c1/go.mod h1:KfoAbLEFfaTk307snIG9ptFwiBHy4DRS4vrEi4Qn4VE=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
+github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
 github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -178,6 +185,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -222,6 +231,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
 github.com/stretchr/testify v1.3.0/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/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8 h1:ndzgwNDnKIqyCvHTXaCqh9KlOWKvBry6nuXMJmonVsE=
@@ -286,6 +297,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
diff --git a/pkg/dynamoconnect/dynamoconnect.go b/pkg/dynamoconnect/dynamoconnect.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d028b0365de39fc3a1737cbde113f0bf7a5b733
--- /dev/null
+++ b/pkg/dynamoconnect/dynamoconnect.go
@@ -0,0 +1,428 @@
+package dynamoconnect
+
+import (
+	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
+	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
+	"github.com/aws/aws-sdk-go/service/dynamodb/expression"
+	"github.com/rs/zerolog/log"
+	"strings"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/session"
+	"github.com/aws/aws-sdk-go/service/dynamodb"
+	"github.com/go-errors/errors"
+)
+
+const (
+	keyName = "Key"
+)
+
+// Storage is a struct that saves all necessary information to access the database, in this case the session for DynamoDB and the table name.
+type Storage struct {
+	dynamotable string
+	svc         dynamodbiface.DynamoDBAPI
+}
+
+// makeKeyName creates the internal DynamoDB key given a keygroup name and an id.
+func makeKeyName(kgname string, id string) string {
+	return kgname + "/" + id
+}
+
+// makeKeygroupKeyName creates the internal DynamoDB key given a keygroup name.
+func makeKeygroupKeyName(kgname string) string {
+	return kgname + "/"
+}
+
+// getKey returns the keygroup and id of a key.
+func getKey(key string) (kg, id string) {
+	s := strings.Split(key, "/")
+	kg = s[0]
+	if len(s) > 1 {
+		id = s[1]
+	}
+	return
+}
+
+// New creates a new Session for DynamoDB.
+func New(table, region string) (s *Storage, err error) {
+	log.Debug().Msgf("creating a new dynamodb connection to table %s in region %s", table, region)
+
+	log.Debug().Msg("Checked creds - OK!")
+
+	sess := session.Must(session.NewSession(&aws.Config{
+		Region: aws.String(region),
+	}))
+
+	log.Debug().Msg("Created session - OK!")
+
+	svc := dynamodb.New(sess)
+
+	log.Debug().Msg("Created service - OK!")
+
+	log.Debug().Msgf("Loading table %s...", table)
+
+	// check if the table with that name even exists
+	// if not: error out
+	desc, err := svc.DescribeTable(&dynamodb.DescribeTableInput{
+		TableName: aws.String(table),
+	})
+
+	if err != nil {
+		return nil, errors.New(err)
+	}
+
+	log.Debug().Msgf("Checking table %s...", table)
+
+	// check that the table has the correct fields (i.e. a primary hash key with name "key") for our use
+	if len(desc.Table.KeySchema) != 1 {
+		return nil, errors.Errorf("expected a single primary range key with name \"%s\" but go %d keys", keyName, len(desc.Table.KeySchema))
+	}
+
+	log.Debug().Msg("Checked table fields - OK!")
+
+	if *(desc.Table.KeySchema[0].AttributeName) != keyName && *(desc.Table.KeySchema[0].KeyType) != dynamodb.KeyTypeHash {
+		return nil, errors.Errorf("expected the primary key to be named \"%s\" and be of type range but got %s with type %s", keyName, *(desc.Table.KeySchema[0].AttributeName), *(desc.Table.KeySchema[0].KeyType))
+	}
+
+	log.Debug().Msg("Checked table keys - OK!")
+
+	return &Storage{
+		dynamotable: table,
+		svc:         dynamodbiface.DynamoDBAPI(svc),
+	}, nil
+}
+
+// Close closes the underlying DynamoDB connection (no cleanup needed at the moment).
+func (s *Storage) Close() error {
+	return nil
+}
+
+// Read returns an item with the specified id from the specified keygroup.
+func (s *Storage) Read(kg string, id string) (string, error) {
+
+	key := makeKeyName(kg, id)
+
+	result, err := s.svc.GetItem(&dynamodb.GetItemInput{
+		Key: map[string]*dynamodb.AttributeValue{
+			keyName: {
+				S: aws.String(key),
+			},
+		},
+		TableName: &s.dynamotable,
+	})
+
+	if err != nil {
+		return "", errors.New(err)
+	}
+
+	if result.Item == nil {
+		return "", errors.Errorf("could not find item %s in keygroup %s", id, kg)
+	}
+
+	Item := struct {
+		Key   string
+		Value string
+	}{}
+
+	err = dynamodbattribute.UnmarshalMap(result.Item, &Item)
+	if err != nil {
+		return "", errors.New(err)
+	}
+
+	return Item.Value, nil
+
+}
+
+// ReadAll returns all items in the specified keygroup.
+func (s *Storage) ReadAll(kg string) (map[string]string, error) {
+	items := make(map[string]string)
+
+	key := makeKeygroupKeyName(kg)
+
+	filt := expression.Name(keyName).BeginsWith(key)
+
+	expr, err := expression.NewBuilder().WithFilter(filt).Build()
+	if err != nil {
+		return items, errors.New(err)
+	}
+
+	params := &dynamodb.ScanInput{
+		ExpressionAttributeNames:  expr.Names(),
+		ExpressionAttributeValues: expr.Values(),
+		FilterExpression:          expr.Filter(),
+		ProjectionExpression:      expr.Projection(),
+		TableName:                 aws.String(s.dynamotable),
+	}
+
+	// Make the DynamoDB Query API call
+	result, err := s.svc.Scan(params)
+	if err != nil {
+		return items, errors.New(err)
+	}
+
+	for _, i := range result.Items {
+
+		item := struct {
+			Key   string
+			Value string
+		}{}
+
+		err = dynamodbattribute.UnmarshalMap(i, &item)
+
+		if err != nil {
+			return items, errors.New(err)
+		}
+
+		if item.Key == key {
+			continue
+		}
+
+		_, id := getKey(item.Key)
+
+		items[id] = item.Value
+
+	}
+
+	return items, nil
+}
+
+// IDs returns the keys of all items in the specified keygroup.
+func (s *Storage) IDs(kg string) ([]string, error) {
+	var ids []string
+
+	key := makeKeygroupKeyName(kg)
+
+	filt := expression.Name(keyName).BeginsWith(key)
+
+	expr, err := expression.NewBuilder().WithFilter(filt).Build()
+	if err != nil {
+		return ids, errors.New(err)
+	}
+
+	params := &dynamodb.ScanInput{
+		ExpressionAttributeNames:  expr.Names(),
+		ExpressionAttributeValues: expr.Values(),
+		FilterExpression:          expr.Filter(),
+		ProjectionExpression:      expr.Projection(),
+		TableName:                 aws.String(s.dynamotable),
+	}
+
+	// Make the DynamoDB Query API call
+	result, err := s.svc.Scan(params)
+	if err != nil {
+		return ids, errors.New(err)
+	}
+
+	for _, i := range result.Items {
+
+		item := struct {
+			Key string
+		}{}
+
+		err = dynamodbattribute.UnmarshalMap(i, &item)
+
+		if err != nil {
+			return ids, errors.New(err)
+		}
+
+		if item.Key == key {
+			continue
+		}
+
+		_, id := getKey(item.Key)
+
+		ids = append(ids, id)
+
+	}
+
+	return ids, nil
+}
+
+// Update updates the item with the specified id in the specified keygroup.
+func (s *Storage) Update(kg, id, val string) error {
+
+	key := makeKeyName(kg, id)
+
+	Item := struct {
+		Key   string
+		Value string
+	}{
+		Key:   key,
+		Value: val,
+	}
+
+	av, err := dynamodbattribute.MarshalMap(Item)
+
+	if err != nil {
+		return errors.New(err)
+	}
+
+	input := &dynamodb.PutItemInput{
+		Item:      av,
+		TableName: aws.String(s.dynamotable),
+	}
+
+	_, err = s.svc.PutItem(input)
+	if err != nil {
+		return errors.New(err)
+	}
+
+	return nil
+}
+
+// Delete deletes the item with the specified id from the specified keygroup.
+func (s *Storage) Delete(kg string, id string) error {
+	key := makeKeyName(kg, id)
+
+	input := &dynamodb.DeleteItemInput{
+		TableName: aws.String(s.dynamotable),
+		Key: map[string]*dynamodb.AttributeValue{
+			keyName: {
+				S: aws.String(key),
+			},
+		},
+	}
+
+	_, err := s.svc.DeleteItem(input)
+	if err != nil {
+		return errors.New(err)
+	}
+
+	return nil
+}
+
+// Exists checks if the given data item exists in the dynamodb database.
+func (s *Storage) Exists(kg string, id string) bool {
+	key := makeKeyName(kg, id)
+
+	result, err := s.svc.GetItem(&dynamodb.GetItemInput{
+		Key: map[string]*dynamodb.AttributeValue{
+			keyName: {
+				S: aws.String(key),
+			},
+		},
+		TableName: &s.dynamotable,
+	})
+
+	if err != nil {
+		return false
+	}
+
+	if result.Item == nil {
+		return false
+	}
+
+	return true
+}
+
+// ExistsKeygroup checks if the given keygroup exists in the DynamoDB database.
+func (s *Storage) ExistsKeygroup(kg string) bool {
+	key := makeKeygroupKeyName(kg)
+
+	result, err := s.svc.GetItem(&dynamodb.GetItemInput{
+		Key: map[string]*dynamodb.AttributeValue{
+			keyName: {
+				S: aws.String(key),
+			},
+		},
+		TableName: &s.dynamotable,
+	})
+
+	if err != nil {
+		return false
+	}
+
+	if result.Item == nil {
+		return false
+	}
+
+	return true
+}
+
+// CreateKeygroup creates the given keygroup in the DynamoDB database.
+func (s *Storage) CreateKeygroup(kg string) error {
+	key := makeKeygroupKeyName(kg)
+
+	Item := struct {
+		Key   string
+		Value string
+	}{
+		Key:   key,
+		Value: key,
+	}
+
+	av, err := dynamodbattribute.MarshalMap(Item)
+
+	if err != nil {
+		return errors.New(err)
+	}
+
+	input := &dynamodb.PutItemInput{
+		Item:      av,
+		TableName: aws.String(s.dynamotable),
+	}
+
+	_, err = s.svc.PutItem(input)
+	if err != nil {
+		return errors.New(err)
+	}
+
+	return nil
+}
+
+// DeleteKeygroup deletes the given keygroup from the DynamoDB database.
+func (s *Storage) DeleteKeygroup(kg string) error {
+
+	key := makeKeygroupKeyName(kg)
+
+	filt := expression.Name(keyName).BeginsWith(key)
+
+	expr, err := expression.NewBuilder().WithFilter(filt).Build()
+	if err != nil {
+		return errors.New(err)
+	}
+
+	params := &dynamodb.ScanInput{
+		ExpressionAttributeNames:  expr.Names(),
+		ExpressionAttributeValues: expr.Values(),
+		FilterExpression:          expr.Filter(),
+		ProjectionExpression:      expr.Projection(),
+		TableName:                 aws.String(s.dynamotable),
+	}
+
+	// Make the DynamoDB Query API call
+	result, err := s.svc.Scan(params)
+	if err != nil {
+		return errors.New(err)
+	}
+
+	for _, i := range result.Items {
+
+		item := struct {
+			Key string
+		}{}
+
+		err = dynamodbattribute.UnmarshalMap(i, &item)
+
+		if err != nil {
+			return errors.New(err)
+		}
+
+		input := &dynamodb.DeleteItemInput{
+
+			Key: map[string]*dynamodb.AttributeValue{
+				keyName: {
+					S: aws.String(item.Key),
+				},
+			},
+			TableName: aws.String(s.dynamotable),
+		}
+
+		_, err := s.svc.DeleteItem(input)
+		if err != nil {
+			return errors.New(err)
+		}
+	}
+
+	return nil
+}