diff --git a/pom.xml b/pom.xml
index f025a8d2773ea95f82e9515478160a7b7c9231e0..81a7b56fa923a6a7e28752bff26af60aae2c8bd7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,7 @@
         <module>provider/legal-azure</module>
         <module>provider/legal-aws</module>
         <module>provider/legal-ibm</module>
+        <module>provider/legal-reference</module>
     </modules>
 
     <repositories>
diff --git a/provider/legal-reference/Dockerfile b/provider/legal-reference/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..b8dc68a58cb58f0f61c8e6c56239364aaa7141ae
--- /dev/null
+++ b/provider/legal-reference/Dockerfile
@@ -0,0 +1,7 @@
+# Use the official AdoptOpenJDK for a base image.
+# https://hub.docker.com/_/openjdk
+FROM openjdk:8-slim
+WORKDIR /app
+COPY target/legal-reference-0.0.1-SNAPSHOT-spring-boot.jar legal.jar
+# Run the web service on container startup.
+CMD java -Djava.security.egd=file:/dev/./urandom -Dserver.port=8080 -jar /app/legal.jar
diff --git a/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml b/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml
new file mode 100644
index 0000000000000000000000000000000000000000..65fa3b4b7ec7c708f05e4b188e57fe51585ee5d7
--- /dev/null
+++ b/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml
@@ -0,0 +1,95 @@
+apiVersion: v1
+data:
+    AUTHORIZE_API: ${AUTHORIZE_API}
+    MONGO_DB_URL: ${MONGO_DB_URL}
+    MONGO_DB_USER: ${MONGO_DB_USER}
+    MONGO_DB_NAME: ${MONGO_DB_NAME}
+    REGION: ${REGION}
+kind: ConfigMap
+metadata:
+    labels:
+        app: legal
+    name: legal-config
+    namespace: default
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+    generateName: legal-anthos
+    labels:
+        app: legal
+    name: legal
+    namespace: default
+spec:
+    selector:
+        matchLabels:
+            app: legal
+    replicas: 1
+    template:
+        metadata:
+            labels:
+                app: legal
+        spec:
+            containers:
+                -   env:
+                        -   name: AUTHORIZE_API
+                            valueFrom:
+                                configMapKeyRef:
+                                    key: AUTHORIZE_API
+                                    name: legal-config
+                        -   name: MONGO_DB_URL
+                            valueFrom:
+                                configMapKeyRef:
+                                    key: MONGO_DB_URL
+                                    name: legal-config
+                        -   name: MONGO_DB_USER
+                            valueFrom:
+                                configMapKeyRef:
+                                    key: MONGO_DB_USER
+                                    name: legal-config
+                        -   name: MONGO_DB_PASSWORD
+                            valueFrom:
+                                secretKeyRef:
+                                    name: legal-secret
+                                    key: mongo.db.password
+                        -   name: MONGO_DB_NAME
+                            valueFrom:
+                                configMapKeyRef:
+                                    key: MONGO_DB_NAME
+                                    name: legal-config
+                        -   name: MB_RABBITMQ_URI
+                            valueFrom:
+                                secretKeyRef:
+                                    name: legal-secret
+                                    key: mb.rabbitmq.uri
+                        -   name: REGION
+                            valueFrom:
+                                configMapKeyRef:
+                                    key: REGION
+                                    name: legal-config
+                    image: us.gcr.io/osdu-anthos-02/os-legal/anthos-legal:latest
+                    name: os-legal-1-sha256-1
+---
+apiVersion: v1
+kind: Service
+metadata:
+    name: legal
+    namespace: default
+spec:
+    ports:
+        -   protocol: TCP
+            port: 80
+            targetPort: 8080
+    selector:
+        app: legal
+    type: LoadBalancer
+---
+apiVersion: v1
+data:
+    mongo.db.password: ${MONGO_DB_PASSWORD}
+    mb.rabbitmq.uri: ${MB_RABBITMQ_URI}
+kind: Secret
+metadata:
+    name: legal-secret
+    namespace: default
+type: Opaque
\ No newline at end of file
diff --git a/provider/legal-reference/pom.xml b/provider/legal-reference/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d1b0131f9977bc4521befd14654e9ecb8d3114fd
--- /dev/null
+++ b/provider/legal-reference/pom.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+    <parent>
+		<groupId>org.opengroup.osdu.legal</groupId>
+		<artifactId>legal-service</artifactId>
+        <version>0.0.5-SNAPSHOT</version>
+    </parent>
+
+	<artifactId>legal-reference</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+	<name>legal-reference</name>
+	<description>Legal service for Anthos</description>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<optional>true</optional>
+		</dependency>
+        <dependency>
+            <groupId>org.opengroup.osdu.legal</groupId>
+            <artifactId>legal-core</artifactId>
+            <version>0.0.5-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opengroup.osdu</groupId>
+            <artifactId>os-core-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opengroup.osdu</groupId>
+            <artifactId>core-lib-gcp</artifactId>
+            <version>0.1.17</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>27.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.12</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.9.9.3</version>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-databind</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-mongodb</artifactId>
+    </dependency>
+
+		<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-circuitbreaker -->
+		<dependency>
+			<groupId>io.github.resilience4j</groupId>
+			<artifactId>resilience4j-circuitbreaker</artifactId>
+			<version>0.17.0</version>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-retry -->
+		<dependency>
+			<groupId>io.github.resilience4j</groupId>
+			<artifactId>resilience4j-retry</artifactId>
+			<version>0.17.0</version>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.6</version>
+		</dependency>
+
+       <!-- Test Dependencies -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+        <!-- Test Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2 -->
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 -->
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>3.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>cobertura-maven-plugin</artifactId>
+            <version>2.7</version>
+            <scope>test</scope>
+        </dependency>
+
+		<!-- https://mvnrepository.com/artifact/com.github.stefanbirkner/system-rules -->
+		<dependency>
+			<groupId>com.github.stefanbirkner</groupId>
+			<artifactId>system-rules</artifactId>
+			<version>1.2.0</version>
+			<scope>test</scope>
+		</dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-config</artifactId>
+        </dependency>
+    <dependency>
+      <groupId>com.rabbitmq</groupId>
+      <artifactId>amqp-client</artifactId>
+    </dependency>
+
+  </dependencies>
+    
+	<build>
+		<plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                        <configuration>
+                            <classifier>spring-boot</classifier>
+                            <mainClass>
+                                org.opengroup.osdu.legal.LegalApplication
+                            </mainClass>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+		</plugins>
+	</build>
+</project>
diff --git a/provider/legal-reference/skaffold.yaml b/provider/legal-reference/skaffold.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ffc7dcaed691b475f40d58c87284955b87096d72
--- /dev/null
+++ b/provider/legal-reference/skaffold.yaml
@@ -0,0 +1,11 @@
+apiVersion: skaffold/v2beta5
+kind: Config
+metadata:
+  name: legal-reference
+build:
+  artifacts:
+  - image: us.gcr.io/osdu-anthos-02/os-legal/anthos-legal
+deploy:
+  kubectl:
+    manifests:
+    - kubernetes/deployments/deployment-legal-service.yml
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..828947fda71bc1e77b4c2def19a4b5ca9a1d21f7
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal;
+
+import org.opengroup.osdu.core.gcp.multitenancy.TenantFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.FilterType;
+
+@ComponentScan(value = {"org.opengroup.osdu"}, excludeFilters = {
+    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = TenantFactory.class)
+})
+@SpringBootApplication(exclude = {MongoAutoConfiguration.class})
+public class LegalApplication extends SpringBootServletInitializer {
+
+  @Override
+  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+    return application.sources(LegalApplication.class);
+  }
+
+  public static void main(String[] args) {
+    SpringApplication.run(LegalApplication.class, args);
+  }
+
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..27111c2508495c99e68d79db6cdb9c937efb00b6
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties
+@Getter
+@Setter
+public class MongoDBConfigProperties {
+
+  private String mongoDbUrl;
+  private String mongoDbUser;
+  private String mongoDbPassword;
+  private String mongoDbName;
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cb658fff09fd53ec2dbf0efbe9a117ebed348fe
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties
+@Getter
+@Setter
+public class RabbitMqConfigProperties {
+
+  private String mbRabbitMqUri;
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..95e4f5d8d0cc342f5c4cd8ebfb482318eb55fb89
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.countries;
+
+import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
+import org.opengroup.osdu.legal.config.MongoDBConfigProperties;
+import org.opengroup.osdu.legal.provider.interfaces.IStorageReader;
+import org.opengroup.osdu.legal.provider.interfaces.IStorageReaderFactory;
+import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StorageReaderFactoryImpl implements IStorageReaderFactory {
+
+  private static final String LEGAL_COLLECTION_NAME = "countries";
+
+  private final MongoDBConfigProperties mongoDBConfigProperties;
+  private final MongoClientProvider clientProvider;
+
+  @Autowired
+  public StorageReaderFactoryImpl(MongoDBConfigProperties mongoDBConfigProperties, MongoClientProvider clientProvider) {
+    this.mongoDBConfigProperties = mongoDBConfigProperties;
+    this.clientProvider = clientProvider;
+  }
+
+  @Override
+  public IStorageReader getReader(TenantInfo tenant, String projectRegion) {
+    return new StorageReaderImpl(tenant, projectRegion, mongoDBConfigProperties.getMongoDbName(),
+        LEGAL_COLLECTION_NAME, clientProvider);
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..9811957719f56b06c31ab998d809f162aaf9c90b
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.countries;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import java.util.List;
+import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
+import org.opengroup.osdu.legal.provider.interfaces.IStorageReader;
+import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+
+public class StorageReaderImpl implements IStorageReader {
+
+  private final TenantInfo tenantInfo;
+  private final String cloudRegion;
+  private final String dbName;
+  private final String collectionName;
+  private final MongoClientProvider client;
+
+  public StorageReaderImpl(TenantInfo tenantInfo, String projectRegion, String dbName,
+      String collectionName, MongoClientProvider client) {
+    this.tenantInfo = tenantInfo;
+    this.cloudRegion = projectRegion;
+    this.collectionName = collectionName;
+    this.dbName = dbName;
+    this.client = client;
+  }
+
+  @Override
+  public byte[] readAllBytes() {
+    MongoOperations ops = new MongoTemplate(client.getMongoClient(), dbName);
+
+    Query query = new Query(Criteria
+        .where("tenant").is(tenantInfo.getName())
+        .and("region").is(cloudRegion));
+
+    query.fields().include("name");
+    query.fields().include("alpha2");
+    query.fields().include("numeric");
+    query.fields().include("residencyRisk");
+    query.fields().include("typesNotApplyDataResidency");
+
+    List<JsonObject> objects = ops.find(query, JsonObject.class, collectionName);
+
+    JsonArray array = new JsonArray();
+    for (JsonObject s : objects) {
+      array.add(s);
+    }
+
+    return new Gson().toJson(array).getBytes();
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java
new file mode 100644
index 0000000000000000000000000000000000000000..d79843ba8f5bffe6a06be964ba1deaccfd97a881
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.di;
+
+import org.opengroup.osdu.core.gcp.multitenancy.IPublisherFactory;
+import org.opengroup.osdu.core.gcp.multitenancy.PublisherFactory;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PublisherFactoryService extends AbstractFactoryBean<IPublisherFactory> {
+
+  @Override
+  protected IPublisherFactory createInstance() throws Exception {
+    return new PublisherFactory();
+  }
+
+  @Override
+  public Class<?> getObjectType() {
+    return IPublisherFactory.class;
+  }
+}
\ No newline at end of file
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2e5306bb078152ecc1abd3af7acaf46bf29c18a
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.di;
+
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.concurrent.TimeoutException;
+import javax.annotation.PostConstruct;
+import org.opengroup.osdu.legal.config.RabbitMqConfigProperties;
+import org.opengroup.osdu.legal.messagebus.IMessageFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RabbitMQFactoryImpl implements IMessageFactory {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(RabbitMQFactoryImpl.class);
+
+  private final RabbitMqConfigProperties rabbitMqConfigProperties;
+  private Channel channel;
+
+  @Autowired
+  public RabbitMQFactoryImpl(RabbitMqConfigProperties rabbitMqConfigProperties) {
+    this.rabbitMqConfigProperties = rabbitMqConfigProperties;
+  }
+
+  @PostConstruct
+  private void init() {
+    ConnectionFactory factory = new ConnectionFactory();
+    try {
+      String mbRabbitMqUri = rabbitMqConfigProperties.getMbRabbitMqUri();
+
+      LOGGER.debug(String.format("RabbitMQ Uri = %s", mbRabbitMqUri));
+
+      factory.setUri(mbRabbitMqUri);
+      factory.setAutomaticRecoveryEnabled(true);
+      Connection conn = factory.newConnection();
+      this.channel = conn.createChannel();
+
+      LOGGER.debug("RabbitMQ Channel was created.");
+
+      for (String queue : Arrays
+          .asList(DEFAULT_QUEUE_NAME, INDEXER_QUEUE_NAME, LEGAL_QUEUE_NAME)) {
+        channel.queueDeclare("os-legal-" + queue, false, false, false, null);
+
+        LOGGER.debug(String.format("Queue [os-legal- %s ] was declared.", queue));
+      }
+    } catch (KeyManagementException | NoSuchAlgorithmException | URISyntaxException | IOException | TimeoutException e) {
+      LOGGER.error(e.getMessage(), e);
+    }
+
+  }
+
+  @Override
+  public void sendMessage(String msg) {
+    this.sendMessage("records", msg);
+  }
+
+  @Override
+  public void sendMessage(String queueName, String msg) {
+    String queueNameWithPrefix = "os-legal-" + queueName;
+
+    try {
+      channel.basicPublish("", queueNameWithPrefix, null, msg.getBytes());
+
+      LOGGER.info(String.format("[x] Sent '%s' to queue [ %s]", msg, queueNameWithPrefix));
+
+    } catch (IOException e) {
+      LOGGER.error(String.format("Unable to publish message to [ %s ]", queueNameWithPrefix));
+      LOGGER.error(e.getMessage(), e);
+    }
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1fcd83abb089745f92b4ad112974504bc4937b7
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.di;
+
+import static java.util.Objects.isNull;
+
+import com.google.gson.Gson;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import org.bson.Document;
+import org.opengroup.osdu.core.common.cache.ICache;
+import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
+import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory;
+import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+@Primary
+@Component
+public class TenantFactoryImpl implements ITenantFactory {
+
+  private static final Logger LOG = LoggerFactory.getLogger(TenantFactoryImpl.class);
+  private static final String SCHEMA_DATABASE = "main";
+  private static final String TENANT_INFO = "tenantinfo";
+
+  private final MongoClientProvider clientProvider;
+
+  @Autowired
+  public TenantFactoryImpl(MongoClientProvider clientProvider) {
+    this.clientProvider = clientProvider;
+  }
+
+  private Map<String, TenantInfo> tenants;
+
+  public boolean exists(String tenantName) {
+    if (this.tenants == null) {
+      initTenants();
+    }
+    return this.tenants.containsKey(tenantName);
+  }
+
+  public TenantInfo getTenantInfo(String tenantName) {
+    if (Objects.isNull(tenants) || this.tenants.isEmpty()) {
+      initTenants();
+    }
+    return this.tenants.get(tenantName);
+  }
+
+  public Collection<TenantInfo> listTenantInfo() {
+    if (this.tenants == null) {
+      initTenants();
+    }
+    return this.tenants.values();
+  }
+
+  public <V> ICache<String, V> createCache(String tenantName, String host, int port,
+      int expireTimeSeconds, Class<V> classOfV) {
+    return null;
+  }
+
+  public void flushCache() {
+  }
+
+  private void initTenants() {
+    this.tenants = new HashMap<>();
+    MongoCollection<Document> mongoCollection = clientProvider
+        .getMongoClient()
+        .getDatabase(SCHEMA_DATABASE)
+        .getCollection(TENANT_INFO, Document.class);
+
+    FindIterable<Document> results = mongoCollection.find();
+
+    if (isNull(results) || isNull(results.first())) {
+      LOG.error(String.format("Collection \'%s\' is empty.", results));
+    }
+    for (Document document : results) {
+      TenantInfo tenantInfo = new Gson().fromJson(document.toJson(), TenantInfo.class);
+      this.tenants.put(tenantInfo.getName(), tenantInfo);
+    }
+  }
+
+}
+
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c552b74d6b94d8052ad4f75db944d85708b9ffa
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.entity;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import lombok.Data;
+import org.opengroup.osdu.core.common.model.legal.LegalTag;
+import org.opengroup.osdu.core.common.model.legal.Properties;
+import org.springframework.data.annotation.Id;
+
+@Data
+public class LegalTagMongoEntity {
+
+  @Id
+  private Long id;
+  private String name;
+  private String description;
+  private PropertiesMongoEntity properties;
+  private Boolean isValid;
+
+  public LegalTagMongoEntity() {
+
+  }
+
+  public LegalTagMongoEntity(LegalTag legalTag) {
+    this.id = legalTag.getId();
+    this.name = legalTag.getName();
+    this.description = legalTag.getDescription();
+    this.properties = new PropertiesMongoEntity(legalTag.getProperties());
+    this.isValid = legalTag.getIsValid();
+  }
+
+  public static LegalTag convertTo(LegalTagMongoEntity entity) {
+    LegalTag legalTag = new LegalTag();
+
+    legalTag.setId(entity.getId());
+    legalTag.setProperties(PropertiesMongoEntity.convertTo(entity.getProperties()));
+    legalTag.setDescription(entity.getDescription());
+    legalTag.setName(entity.getName());
+    legalTag.setIsValid(entity.getIsValid());
+
+    return legalTag;
+  }
+
+  public static LegalTagMongoEntity convertFrom(LegalTag legalTag) {
+    LegalTagMongoEntity entity = new LegalTagMongoEntity();
+
+    entity.setId(legalTag.getId());
+    entity.setProperties(new PropertiesMongoEntity(legalTag.getProperties()));
+    entity.setDescription(legalTag.getDescription());
+    entity.setName(legalTag.getName());
+    entity.setIsValid(legalTag.getIsValid());
+
+    return entity;
+  }
+
+  @Data
+  private static class PropertiesMongoEntity {
+
+    private List<String> countryOfOrigin = new ArrayList();
+    private String contractId = "";
+    private Date expirationDate;
+    private String originator = "";
+    private String dataType = "";
+    private String securityClassification = "";
+    private String personalData = "";
+    private String exportClassification = "";
+
+    public PropertiesMongoEntity() {
+    }
+
+    public PropertiesMongoEntity(Properties properties) {
+      this.countryOfOrigin = properties.getCountryOfOrigin();
+      this.contractId = properties.getContractId();
+      this.expirationDate = new Date(properties.getExpirationDate().getTime());
+      this.originator = properties.getOriginator();
+      this.dataType = properties.getDataType();
+      this.securityClassification = properties.getSecurityClassification();
+      this.personalData = properties.getPersonalData();
+      this.exportClassification = properties.getExportClassification();
+    }
+
+    public static Properties convertTo(PropertiesMongoEntity entity) {
+      Properties properties = new Properties();
+
+      properties.setCountryOfOrigin(entity.getCountryOfOrigin());
+      properties.setContractId(entity.getContractId());
+
+      properties.setExpirationDate(new java.sql.Date(entity.getExpirationDate().getTime()));
+
+      properties.setOriginator(entity.getOriginator());
+      properties.setDataType(entity.getDataType());
+      properties.setSecurityClassification(entity.getSecurityClassification());
+      properties.setPersonalData(entity.getPersonalData());
+      properties.setExportClassification(entity.getExportClassification());
+
+      return properties;
+    }
+
+    public static PropertiesMongoEntity convertFrom(Properties properties) {
+      PropertiesMongoEntity entity = new PropertiesMongoEntity();
+
+      entity.countryOfOrigin = properties.getCountryOfOrigin();
+      entity.contractId = properties.getContractId();
+      entity.expirationDate = new Date(properties.getExpirationDate().getTime());
+      entity.originator = properties.getOriginator();
+      entity.dataType = properties.getDataType();
+      entity.securityClassification = properties.getSecurityClassification();
+      entity.personalData = properties.getPersonalData();
+      entity.exportClassification = properties.getExportClassification();
+
+      return entity;
+    }
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..512f165a910b4b2b930513bd1e65a64efe312c1a
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.jobs;
+
+import com.google.gson.Gson;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.legal.StatusChangedTag;
+import org.opengroup.osdu.core.common.model.legal.StatusChangedTags;
+import org.opengroup.osdu.legal.messagebus.IMessageFactory;
+import org.opengroup.osdu.legal.provider.interfaces.ILegalTagPublisher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class LegalTagPublisherImpl implements ILegalTagPublisher {
+
+  private final IMessageFactory mq;
+
+  @Autowired
+  public LegalTagPublisherImpl(IMessageFactory mq) {
+    this.mq = mq;
+  }
+
+  @Override
+  public void publish(String projectId, DpsHeaders headers, StatusChangedTags tags) {
+
+    final int BATCH_SIZE = 50;
+    Gson gson = new Gson();
+    Map<String, String> message = new HashMap<>();
+
+    for (int i = 0; i < tags.getStatusChangedTags().size(); i += BATCH_SIZE) {
+
+      List<StatusChangedTag> batch = tags.getStatusChangedTags().subList(i,
+          Math.min(tags.getStatusChangedTags().size(), i + BATCH_SIZE));
+      String json = gson.toJson(batch);
+      message.put("data", json);
+      message.put(DpsHeaders.ACCOUNT_ID, headers.getPartitionIdWithFallbackToAccountId());
+      message.put(DpsHeaders.DATA_PARTITION_ID, headers.getPartitionIdWithFallbackToAccountId());
+      headers.addCorrelationIdIfMissing();
+      message.put(DpsHeaders.CORRELATION_ID, headers.getCorrelationId());
+      mq.sendMessage(IMessageFactory.LEGAL_QUEUE_NAME, gson.toJson(message));
+    }
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e88bcf11042c5c103ce8300c1c339ef43f48bfe
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.messagebus;
+
+public interface IMessageFactory {
+	String DEFAULT_QUEUE_NAME = "records";
+	String LEGAL_QUEUE_NAME = "legal";
+	String INDEXER_QUEUE_NAME = "indexer";
+
+	void sendMessage(String msg);
+
+	void sendMessage(String queueName, String msg);
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..90caf6870a19fa521c072a58da14c513e5eb013a
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.security;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties
+@Getter
+@Setter
+public class EntitlementsConfig {
+
+  private String authorizeApi;
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..bac5b7a9dc1a20814a1d52688cb96831fa47c07a
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.security;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+  @Override
+  protected void configure(HttpSecurity http) throws Exception {
+    http.httpBasic().disable()
+        .csrf().disable();
+
+  }
+
+  @Override
+  public void configure(WebSecurity web) throws Exception {
+    web.ignoring().antMatchers("/api-docs")
+        .antMatchers("/index")
+        .antMatchers("/swagger");
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..544d683df35e870cd273ecb1467e5231a032f51c
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.tags;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepository;
+import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepositoryFactory;
+import org.opengroup.osdu.legal.tags.dataaccess.MongoLegalTagRepository;
+import org.opengroup.osdu.legal.tags.dataaccess.ResilientLegalTagRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+@Service
+@Primary
+public class LegalTagRepositoryFactoryMongoImpl implements ILegalTagRepositoryFactory {
+
+  private final Map<String, ILegalTagRepository> tenantRepositories = new HashMap<>();
+
+  @Autowired
+  private MongoLegalTagRepository mongoLegalTagRepository;
+
+  @Override
+  public ILegalTagRepository get(String tenantName) {
+    if (StringUtils.isBlank(tenantName)) {
+      throw invalidTenantGivenException(tenantName);
+    }
+    if (!tenantRepositories.containsKey(tenantName)) {
+      addRepository(tenantName);
+    }
+    return tenantRepositories.get(tenantName);
+  }
+
+  private void addRepository(String tenantName) {
+    ILegalTagRepository repo = new ResilientLegalTagRepository(mongoLegalTagRepository);
+    tenantRepositories.put(tenantName, repo);
+  }
+
+  private AppException invalidTenantGivenException(String tenantName) {
+    return new AppException(403, "Forbidden",
+        String.format("You do not have access to the %s value given %s",
+            DpsHeaders.ACCOUNT_ID, tenantName));
+  }
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..d28b228d2b3ea9a19f8721714901f523032ca452
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.tags.dataaccess;
+
+import static java.util.Objects.isNull;
+
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.legal.config.MongoDBConfigProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MongoClientProvider {
+
+  private static final Logger LOG = LoggerFactory.getLogger(MongoClientProvider.class);
+  private static final String MONGO_PREFIX = "mongodb://";
+  private static final String MONGO_OPTIONS = "retryWrites=true&w=majority&maxIdleTimeMS=10000";
+  private final MongoDBConfigProperties mongoDBConfigProperties;
+
+  private MongoClient mongoClient = null;
+
+  @Autowired
+  public MongoClientProvider(MongoDBConfigProperties mongoDBConfigProperties) {
+    this.mongoDBConfigProperties = mongoDBConfigProperties;
+  }
+
+  private MongoClient initMongoClient() throws RuntimeException {
+    final String connectionString = String.format("%s%s:%s@%s/?%s",
+        MONGO_PREFIX,
+        mongoDBConfigProperties.getMongoDbUser(),
+        mongoDBConfigProperties.getMongoDbPassword(),
+        mongoDBConfigProperties.getMongoDbUrl(),
+        MONGO_OPTIONS);
+    ConnectionString connString = new ConnectionString(connectionString);
+    MongoClientSettings settings = MongoClientSettings.builder()
+        .applyConnectionString(connString)
+        .retryWrites(true)
+        .build();
+    try {
+      mongoClient = MongoClients.create(settings);
+    } catch (Exception ex) {
+      LOG.error("Error connecting MongoDB", ex);
+      throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Error connecting MongoDB",
+          ex.getMessage(), ex);
+    }
+    return mongoClient;
+  }
+
+  public MongoClient getMongoClient() {
+    return isNull(mongoClient) ? initMongoClient() : mongoClient;
+  }
+
+  public MongoOperations getOps(String dbName) {
+    return new MongoTemplate(getMongoClient(), dbName);
+  }
+
+}
diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc445e6c6bc2fd5a242f2640eab3c549a56468bf
--- /dev/null
+++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.tags.dataaccess;
+
+import static com.google.common.primitives.Longs.asList;
+import static java.util.Objects.isNull;
+import static org.apache.commons.lang3.BooleanUtils.negate;
+import static org.opengroup.osdu.legal.entity.LegalTagMongoEntity.convertFrom;
+import static org.opengroup.osdu.legal.entity.LegalTagMongoEntity.convertTo;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.ArrayUtils;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.legal.LegalTag;
+import org.opengroup.osdu.core.common.model.legal.ListLegalTagArgs;
+import org.opengroup.osdu.legal.config.MongoDBConfigProperties;
+import org.opengroup.osdu.legal.entity.LegalTagMongoEntity;
+import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class MongoLegalTagRepository implements ILegalTagRepository {
+
+  private final MongoDBConfigProperties mongoDBConfigProperties;
+  private final MongoClientProvider clientProvider;
+
+  @Autowired
+  public MongoLegalTagRepository(MongoDBConfigProperties mongoDBConfigProperties, MongoClientProvider clientProvider) {
+    this.mongoDBConfigProperties = mongoDBConfigProperties;
+    this.clientProvider = clientProvider;
+  }
+
+  @Override
+  public Long create(LegalTag legalTag) {
+    Preconditions.checkNotNull(legalTag, "Legal tag is null!");
+    Preconditions.checkNotNull(legalTag.getId(), "Legal tag's id is null!");
+
+    MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName());
+
+    LegalTagMongoEntity savedEntity = ops.save(convertFrom(legalTag), LEGAL_TAGS_ENTITYNAME);
+
+    return savedEntity.getId();
+  }
+
+  @Override
+  public Collection<LegalTag> get(long[] ids) {
+    Preconditions.checkNotNull(ids, "List of legal tag ids is null!");
+    Preconditions.checkArgument(ArrayUtils.isNotEmpty(ids), "List of legal tag ids is empty!");
+
+    MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName());
+
+    Query query = new Query(Criteria.where("_id").in(asList(ids)));
+    List<LegalTagMongoEntity> entities =
+        ops.find(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+
+    return entities.stream()
+        .map(LegalTagMongoEntity::convertTo)
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public Boolean delete(LegalTag legalTag) {
+    Preconditions.checkNotNull(legalTag, "Legal tag is null!");
+
+    MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName());
+
+    Query query = new Query(Criteria.where("_id").is(legalTag.getId()));
+
+    Boolean exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+
+    if (exists) {
+      ops.remove(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+      exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+    }
+
+    return negate(exists);
+  }
+
+  @Override
+  public LegalTag update(LegalTag newLegalTag) {
+    Preconditions.checkNotNull(newLegalTag, "Legal tag is null!");
+
+    MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName());
+
+    Query query = new Query(Criteria.where("_id").is(newLegalTag.getId()));
+
+    Boolean exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+
+    if (negate(exists)) {
+      throw AppException.legalTagDoesNotExistError(newLegalTag.getName());
+    }
+
+    LegalTagMongoEntity savedEntity = ops.save(convertFrom(newLegalTag), LEGAL_TAGS_ENTITYNAME);
+
+    return convertTo(savedEntity);
+  }
+
+  @Override
+  public Collection<LegalTag> list(ListLegalTagArgs args) {
+    MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName());
+
+    Query query = new Query();
+
+    if (negate(isNull(args.getIsValid()))) {
+      query.addCriteria(Criteria.where("isValid").is(args.getIsValid()));
+    }
+
+    List<LegalTagMongoEntity> entities =
+        ops.find(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME);
+
+    return entities.stream()
+        .map(LegalTagMongoEntity::convertTo)
+        .collect(Collectors.toList());
+  }
+}
diff --git a/provider/legal-reference/src/main/resources/application.properties b/provider/legal-reference/src/main/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..76350ce894a8741dac613c52cc44b9c487834e4a
--- /dev/null
+++ b/provider/legal-reference/src/main/resources/application.properties
@@ -0,0 +1,24 @@
+LOG_PREFIX=legal
+
+server.servlet.contextPath=/api/legal/v1/
+logging.level.org.springframework.web=DEBUG
+server.port=8080
+
+JAVA_HEAP_OPTS=-Xms4096M -Xmx4096M
+JAVA_GC_OPTS=-XX:+UseG1GC -XX:+UseStringDeduplication -XX:InitiatingHeapOccupancyPercent=45
+
+ACCEPT_HTTP=true
+DEFAULT_DATA_COUNTRY=US
+
+#This must be overridden
+mongo-db-url={MONGO_DB_URL}
+mongo-db-user={MONGO_DB_USER}
+mongo-db-password={MONGO_DB_PASSWORD}
+mongo-db-name={MONGO_DB_NAME}
+mb-rabbitmq-uri=amqp://guest:guest@localhost:5672
+
+REGION=us-central1
+AUTHORIZE_API=https://entitlements-java-ckqkfalyaq-uc.a.run.app/entitlements/v1
+
+
+
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..71785a50ed5ce23c6759e8aea6debc6e6d69f8c6
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal;
+
+import org.opengroup.osdu.core.common.model.legal.Properties;
+import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule;
+
+public class InvalidCooRule extends Rule {
+
+  @Override
+  public boolean shouldCheck(Properties properties) {
+    return true;
+  }
+
+  @Override
+  protected String hasError(Properties properties) {
+    return String.format(
+        "Invalid country of origin set. It should match one of the ISO alpha 2 codes and be a country with no restriction on data residency. Found: %s.",
+        properties.getCountryOfOrigin());
+  }
+}
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..0be9240646df8551b109a53e8cdd47a08fea7fb5
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class LegalApplicationTests {
+
+  @Test
+  public void contextLoads() {
+  }
+
+}
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..bce261a49fe4c998da9c912e25fed90fe523f84c
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal;
+
+import org.opengroup.osdu.core.common.model.legal.Properties;
+import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule;
+
+public class MockRule extends Rule {
+
+  @Override
+  public boolean shouldCheck(Properties properties) {
+    return true;
+  }
+
+  @Override
+  protected String hasError(Properties properties) {
+    return "";
+  }
+}
\ No newline at end of file
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ee0847ec5e097efb9eeb78dca7018ca3227e126
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import javax.validation.Configuration;
+import javax.validation.ConstraintValidator;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import org.opengroup.osdu.core.common.model.http.RequestInfo;
+import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule;
+import org.opengroup.osdu.core.common.model.tenant.TenantInfo;
+import org.opengroup.osdu.legal.tags.LegalTagConstraintValidator;
+
+public class MockValidationValidator extends LegalTagConstraintValidator {
+
+  private final String rulesetName;
+
+  public MockValidationValidator(String ruleSet, RulesetProvider rsp) {
+    this.rulesetName = ruleSet;
+    this.ruleSetProvider = rsp;
+  }
+
+  public MockValidationValidator() {
+    this.rulesetName = TenantInfo.ComplianceRuleSets.SHARED;
+    this.ruleSetProvider = CreateRsp(new MockRule());
+  }
+
+  @Override
+  public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
+    this.requestInfo = mock(RequestInfo.class);
+    when(requestInfo.getComplianceRuleSet()).thenReturn(rulesetName);
+    return super.getInstance(key);
+  }
+
+  @Override
+  public void releaseInstance(ConstraintValidator<?, ?> instance) {
+
+  }
+
+  public static Validator GetValidator(String rulesetName, RulesetProvider rsp) {
+    Configuration<?> config = Validation.byDefaultProvider().configure();
+    config.constraintValidatorFactory(new MockValidationValidator(rulesetName, rsp));
+    ValidatorFactory factory = config.buildValidatorFactory();
+    return factory.getValidator();
+  }
+
+  public static Validator GetValidator(String rulesetName) {
+    Configuration<?> config = Validation.byDefaultProvider().configure();
+    config.constraintValidatorFactory(
+        new MockValidationValidator(rulesetName, CreateRsp(new MockRule())));
+    ValidatorFactory factory = config.buildValidatorFactory();
+    return factory.getValidator();
+  }
+
+  public static Validator GetValidator() {
+    Configuration<?> config = Validation.byDefaultProvider().configure();
+    return GetValidator(TenantInfo.ComplianceRuleSets.SHARED);
+  }
+
+  public static RulesetProvider CreateRsp(Rule... rules) {
+    RulesetProvider rsp = mock(RulesetProvider.class);
+    when(rsp.get()).thenReturn(Arrays.asList(rules));
+    return rsp;
+  }
+}
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..3126cc231ddb36d7abeb538cac01d3363e62daca
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.tags;
+
+import static org.opengroup.osdu.core.common.model.legal.Properties.DEFAULT_EXPIRATIONDATE;
+
+import java.sql.Date;
+import java.util.ArrayList;
+import org.opengroup.osdu.core.common.model.legal.LegalTag;
+import org.opengroup.osdu.core.common.model.legal.Properties;
+import org.opengroup.osdu.legal.tags.dto.LegalTagDto;
+import org.opengroup.osdu.legal.tags.dto.UpdateLegalTag;
+
+public class LegalTestUtils {
+
+  public static LegalTag createValidLegalTag(String name) {
+    LegalTag legalTag = new LegalTag();
+    legalTag.setProperties(createValidProperties());
+    legalTag.setName(name);
+    legalTag.setIsValid(false);
+    legalTag.setDefaultId();
+    return legalTag;
+  }
+
+  public static Properties createValidProperties() {
+    Properties properties = new Properties();
+    properties.setCountryOfOrigin(new ArrayList<String>() {{
+      add("USA");
+    }});
+    properties.setExpirationDate(new Date(System.currentTimeMillis()));
+    properties.setOriginator("MyCompany");
+    properties.setContractId("Unknown");
+    properties.setDataType("Tranferred Data");
+    properties.setPersonalData("Sensitive Personal Information");
+    properties.setSecurityClassification("Confidential");
+    properties.setExportClassification("ECCN");
+    return properties;
+  }
+
+  public static UpdateLegalTag createUpdateLegalTag(String name) {
+    UpdateLegalTag legalTag = new UpdateLegalTag();
+    legalTag.setExpirationDate(DEFAULT_EXPIRATIONDATE);
+    legalTag.setContractId("abc123");
+    legalTag.setName(name);
+    legalTag.setDescription("myDescription");
+    return legalTag;
+  }
+
+  public static LegalTagDto createValidLegalTagDto(String name) {
+    return LegalTagDto.convertTo(createValidLegalTag(name));
+  }
+}
diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5045b01044d7a7d1ae22d20ca324d4592c17eac0
--- /dev/null
+++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2021 Google LLC
+ * Copyright 2021 EPAM Systems, Inc
+ *
+ * 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
+ *
+ *     https://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 org.opengroup.osdu.legal.tags.dataaccess;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.MockitoAnnotations.initMocks;
+import static org.opengroup.osdu.legal.tags.LegalTestUtils.createValidLegalTag;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.legal.LegalTag;
+import org.opengroup.osdu.core.common.model.legal.ListLegalTagArgs;
+import org.opengroup.osdu.legal.config.MongoDBConfigProperties;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+
+@Ignore
+@RunWith(SpringRunner.class)
+@PrepareForTest({MongoOperations.class, MongoClientProvider.class, MongoClient.class,
+    MongoLegalTagRepository.class})
+public class MongoLegalTagRepositoryTest {
+
+  private static final String DB_NAME = "test";
+
+  @MockBean
+  private MongoClient client;
+
+  @MockBean
+  private MongoOperations ops;
+
+  @MockBean
+  private MongoClientProvider clientProvider;
+
+  @MockBean
+  private MongoDBConfigProperties mongoDBConfigProperties;
+
+  @InjectMocks
+  private MongoLegalTagRepository repo;
+
+  @Before
+  public void setup() throws Exception {
+    final String connectionString = String.format("%s%s:%s@%s/?%s",
+        "mongodb://",
+        "admin",
+        "gonrg422",
+        "localhost:27017",
+        "retryWrites=true&w=majority");
+    ConnectionString connString = new ConnectionString(connectionString);
+    MongoClientSettings settings = MongoClientSettings.builder()
+        .applyConnectionString(connString)
+        .retryWrites(true)
+        .build();
+
+    client = MongoClients.create(settings);
+    ops = new MongoTemplate(client, DB_NAME);
+    repo = new MongoLegalTagRepository(mongoDBConfigProperties, clientProvider);
+
+    ReflectionTestUtils.setField(repo, "dbName", DB_NAME);
+    ReflectionTestUtils.setField(clientProvider, "mongoClient", client);
+
+    initMocks(this);
+  }
+
+  @After
+  public void teardown() throws Exception {
+    client.getDatabase(DB_NAME).drop();
+  }
+
+  @Test
+  public void testCreate() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+
+    Long saved_id1 = repo.create(tag1);
+
+    assertEquals(id1, saved_id1);
+
+    try {
+      LegalTag nullIdtag = createValidLegalTag("nulltag");
+      nullIdtag.setId(null);
+      repo.create(nullIdtag);
+      fail("Expected exception");
+    } catch (NullPointerException e) {
+    }
+
+    LegalTag tag2 = createValidLegalTag("tag2");
+    tag2.setIsValid(true);
+    Long id2 = tag2.getId();
+
+    Long saved_id2 = repo.create(tag2);
+
+    assertEquals(id2, saved_id2);
+
+  }
+
+  @Test
+  public void testGet() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+
+    Long saved_id1 = repo.create(tag1);
+    assertEquals(id1, saved_id1);
+
+    LegalTag tag2 = createValidLegalTag("tag2");
+    tag2.setIsValid(true);
+    Long id2 = tag2.getId();
+
+    Long saved_id2 = repo.create(tag2);
+
+    assertEquals(id2, saved_id2);
+
+    Collection<LegalTag> retrv1 = repo.get(new long[]{id1});
+    assertEquals(retrv1.size(), 1);
+
+    LegalTag retrv1_tag1 = retrv1.iterator().next();
+    assertEquals(tag1, retrv1_tag1);
+  }
+
+  @Test
+  public void testNone() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+
+    Long saved_id1 = repo.create(tag1);
+    assertEquals(id1, saved_id1);
+
+    LegalTag tag2 = createValidLegalTag("tag2");
+    tag2.setIsValid(true);
+    Long id2 = tag2.getId();
+
+    Long saved_id2 = repo.create(tag2);
+
+    assertEquals(id2, saved_id2);
+
+    Collection<LegalTag> retrv1 = repo.get(new long[]{4324L});
+    assertEquals(retrv1.size(), 0);
+  }
+
+
+  @Test
+  public void testGetMultiple() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+
+    Long saved_id1 = repo.create(tag1);
+    assertEquals(id1, saved_id1);
+
+    LegalTag tag2 = createValidLegalTag("tag2");
+    tag2.setIsValid(true);
+    Long id2 = tag2.getId();
+
+    Long saved_id2 = repo.create(tag2);
+
+    assertEquals(id2, saved_id2);
+
+    Collection<LegalTag> retrv1 = repo.get(new long[]{id1, id2});
+    assertEquals(retrv1.size(), 2);
+
+    Iterator<LegalTag> it = retrv1.iterator();
+
+    LegalTag retrv1_tag1 = it.next();
+    assertEquals(tag1, retrv1_tag1);
+    LegalTag retrv1_tag2 = it.next();
+    assertEquals(tag2, retrv1_tag2);
+  }
+
+  @Test
+  public void testUpdate() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+    tag1.setDescription("description1");
+
+    try {
+      repo.update(tag1);
+      fail("expected exception when updating object not present in the database");
+    } catch (AppException ex) {
+    }
+
+    Long saved_id1 = repo.create(tag1);
+    assertEquals(id1, saved_id1);
+
+    Collection<LegalTag> retrv1 = repo.get(new long[]{id1});
+    assertEquals(retrv1.size(), 1);
+
+    Iterator<LegalTag> retrv1_it = retrv1.iterator();
+
+    LegalTag retrv1_tag1 = retrv1_it.next();
+    assertEquals(tag1, retrv1_tag1);
+
+    retrv1_tag1.setDescription("description2");
+
+    // This update will work without extra logic because retrv1_tag1 is
+    // actually a CloudantBackedLegalTag with a valid _rev
+    repo.update(retrv1_tag1);
+
+    Collection<LegalTag> retrv2 = repo.get(new long[]{id1});
+    assertEquals(retrv2.size(), 1);
+
+    Iterator<LegalTag> retrv2_it = retrv2.iterator();
+
+    LegalTag retrv2_tag1 = retrv2_it.next();
+
+    assertNotEquals(tag1, retrv2_tag1);
+    assertEquals(retrv1_tag1, retrv2_tag1);
+
+    LegalTag tag1_equivalent = createValidLegalTag("tag1");
+    tag1.setDescription("description3");
+    assertEquals(id1, tag1_equivalent.getId());
+
+    // This update would fail it the update method didn't handle the missing _rev
+    repo.update(tag1_equivalent);
+
+    // This update would fail it the update method didn't handle the outdated _rev
+    repo.update(retrv2_tag1);
+
+  }
+
+  @Test
+  public void testDelete() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    Long id1 = tag1.getId();
+    tag1.setDescription("description1");
+
+    assertTrue(repo.delete(tag1));
+
+    Long saved_id1 = repo.create(tag1);
+    assertEquals(id1, saved_id1);
+
+    Collection<LegalTag> retrv1 = repo.get(new long[]{id1});
+    assertEquals(retrv1.size(), 1);
+
+    assertTrue(repo.delete(tag1));
+
+    Collection<LegalTag> retrv2 = repo.get(new long[]{id1});
+    assertEquals(retrv2.size(), 0);
+
+    repo.create(tag1);
+
+    Collection<LegalTag> retrv3 = repo.get(new long[]{id1});
+    assertEquals(retrv3.size(), 1);
+
+    Iterator<LegalTag> retrv3_it = retrv3.iterator();
+
+    LegalTag retrv3_tag1 = retrv3_it.next();
+    assertEquals(tag1, retrv3_tag1);
+
+    retrv3_tag1.setDescription("description2");
+    assertNotEquals(tag1, retrv3_tag1);
+
+    repo.update(retrv3_tag1);
+
+    Collection<LegalTag> retrv4 = repo.get(new long[]{id1});
+    assertEquals(retrv4.size(), 1);
+
+    // This would fail without the retry on conflict logic
+    assertTrue(repo.delete(retrv3_tag1));
+
+    Collection<LegalTag> retrv5 = repo.get(new long[]{id1});
+    assertEquals(retrv5.size(), 0);
+
+  }
+
+  @Test
+  public void testList() throws Exception {
+    when(clientProvider.getOps(anyString())).thenReturn(ops);
+    LegalTag tag1 = createValidLegalTag("tag1");
+    tag1.setIsValid(false);
+    repo.create(tag1);
+    LegalTag tag2 = createValidLegalTag("tag2");
+    tag2.setIsValid(true);
+    repo.create(tag2);
+    LegalTag tag3 = createValidLegalTag("tag3");
+    tag3.setIsValid(false);
+    repo.create(tag3);
+    LegalTag tag4 = createValidLegalTag("tag4");
+    tag4.setIsValid(true);
+    repo.create(tag4);
+    LegalTag tag5 = createValidLegalTag("tag5");
+    tag5.setIsValid(false);
+    repo.create(tag5);
+    LegalTag tag6 = createValidLegalTag("tag6");
+    tag6.setIsValid(true);
+    repo.create(tag6);
+
+    ListLegalTagArgs allTagsNoPaging = new ListLegalTagArgs();
+    allTagsNoPaging.setIsValid(null);
+    allTagsNoPaging.setLimit(0);
+
+    Set<String> allNames = repo.list(allTagsNoPaging).stream().map(t -> t.getName())
+        .collect(Collectors.toSet());
+
+    assertEquals(6, allNames.size());
+    assertTrue(allNames.contains("tag1"));
+    assertTrue(allNames.contains("tag2"));
+    assertTrue(allNames.contains("tag3"));
+    assertTrue(allNames.contains("tag4"));
+    assertTrue(allNames.contains("tag5"));
+    assertTrue(allNames.contains("tag6"));
+
+    ListLegalTagArgs validTagsNoPaging = new ListLegalTagArgs();
+    validTagsNoPaging.setIsValid(true);
+    validTagsNoPaging.setLimit(0);
+
+    Set<String> validNames = repo.list(validTagsNoPaging).stream().map(t -> t.getName())
+        .collect(Collectors.toSet());
+
+    assertEquals(3, validNames.size());
+    assertTrue(validNames.contains("tag2"));
+    assertTrue(validNames.contains("tag4"));
+    assertTrue(validNames.contains("tag6"));
+  }
+}
\ No newline at end of file