diff --git a/config/mariadb/initdb.d/init.sql b/config/mariadb/initdb.d/init.sql
index c111da6fd21e422561c93d8cb21484d8c89e82a7..8cfeabee764ee951fe8b9291165b5b110fd68467 100644
--- a/config/mariadb/initdb.d/init.sql
+++ b/config/mariadb/initdb.d/init.sql
@@ -55,4 +55,15 @@ CREATE TABLE GithubWebhookTracking (
   needsRevalidation tinyint(1) DEFAULT 0,
   manualRevalidationCount int DEFAULT 0,
   PRIMARY KEY (id)
-);
\ No newline at end of file
+);
+
+-- eclipse_eca.GithubApplicationInstallation definition
+
+CREATE TABLE `GithubApplicationInstallation` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `appId` int(11) NOT NULL,
+  `installationId` int(11) NOT NULL,
+  `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `lastUpdated` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=389 DEFAULT CHARSET=utf8;
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8358b7553e8bf4d8c9de9a17a66d387f0586e0b4..a3eec59f652ed64e61848b438af07af9908da58c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,198 +1,210 @@
 <?xml version="1.0"?>
 <project
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-  xmlns="http://maven.apache.org/POM/4.0.0"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.eclipsefoundation</groupId>
-  <artifactId>git-eca</artifactId>
-  <version>1.1.0</version>
-  <properties>
-    <compiler-plugin.version>3.11.0</compiler-plugin.version>
-    <maven.compiler.source>17</maven.compiler.source>
-    <maven.compiler.target>17</maven.compiler.target>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
-    <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
-    <quarkus.platform.version>3.2.11.Final</quarkus.platform.version>
-    <surefire-plugin.version>3.1.2</surefire-plugin.version>
-    <maven.compiler.parameters>true</maven.compiler.parameters>
-    <eclipse-api-version>0.9.5</eclipse-api-version>
-    <auto-value.version>1.10.4</auto-value.version>
-    <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
-    <sonar.sources>src/main</sonar.sources>
-    <sonar.tests>src/test</sonar.tests>
-    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
-    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
-    <sonar.coverage.jacoco.xmlReportPaths>
-      ${project.basedir}/target/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
-    <sonar.junit.reportPath>${project.build.directory}/surefire-reports</sonar.junit.reportPath>
-    <sonar.host.url>https://sonarcloud.io</sonar.host.url>
-    <sonar.organization>eclipse-foundation-it</sonar.organization>
-    <sonar.projectKey>git-eca-rest-api</sonar.projectKey>
-    <sonar.projectName>Git ECA REST API</sonar.projectName>
-  </properties>
-  <repositories>
-    <repository>
-      <id>eclipsefdn</id>
-      <url>https://repo.eclipse.org/content/repositories/eclipsefdn/</url>
-      <releases>
-        <enabled>true</enabled>
-      </releases>
-      <snapshots>
-        <enabled>true</enabled>
-      </snapshots>
-    </repository>
-  </repositories>
-  <dependencyManagement>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.eclipsefoundation</groupId>
+    <artifactId>git-eca</artifactId>
+    <version>1.1.0</version>
+    <properties>
+        <compiler-plugin.version>3.11.0</compiler-plugin.version>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
+        <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
+        <quarkus.platform.version>3.2.11.Final</quarkus.platform.version>
+        <surefire-plugin.version>3.1.2</surefire-plugin.version>
+        <maven.compiler.parameters>true</maven.compiler.parameters>
+        <eclipse-api-version>0.9.5</eclipse-api-version>
+        <auto-value.version>1.10.4</auto-value.version>
+        <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
+        <sonar.sources>src/main</sonar.sources>
+        <sonar.tests>src/test</sonar.tests>
+        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
+        <sonar.coverage.jacoco.xmlReportPaths>
+            ${project.basedir}/target/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
+        <sonar.junit.reportPath>${project.build.directory}/surefire-reports</sonar.junit.reportPath>
+        <sonar.host.url>https://sonarcloud.io</sonar.host.url>
+        <sonar.organization>eclipse-foundation-it</sonar.organization>
+        <sonar.projectKey>git-eca-rest-api</sonar.projectKey>
+        <sonar.projectName>Git ECA REST API</sonar.projectName>
+    </properties>
+    <repositories>
+        <repository>
+            <id>eclipsefdn</id>
+            <url>https://repo.eclipse.org/content/repositories/eclipsefdn/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>${quarkus.platform.group-id}</groupId>
+                <artifactId>${quarkus.platform.artifact-id}</artifactId>
+                <version>${quarkus.platform.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
     <dependencies>
-      <dependency>
-        <groupId>${quarkus.platform.group-id}</groupId>
-        <artifactId>${quarkus.platform.artifact-id}</artifactId>
-        <version>${quarkus.platform.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-  <dependencies>
-    <dependency>
-      <groupId>org.eclipsefoundation</groupId>
-      <artifactId>quarkus-core</artifactId>
-      <version>${eclipse-api-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipsefoundation</groupId>
-      <artifactId>quarkus-persistence</artifactId>
-      <version>${eclipse-api-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipsefoundation</groupId>
-      <artifactId>quarkus-efservices</artifactId>
-      <version>${eclipse-api-version}</version>
-    </dependency>
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-smallrye-context-propagation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-smallrye-jwt</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.eclipsefoundation</groupId>
+            <artifactId>quarkus-core</artifactId>
+            <version>${eclipse-api-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipsefoundation</groupId>
+            <artifactId>quarkus-persistence</artifactId>
+            <version>${eclipse-api-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipsefoundation</groupId>
+            <artifactId>quarkus-efservices</artifactId>
+            <version>${eclipse-api-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-smallrye-context-propagation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-smallrye-jwt</artifactId>
+        </dependency>
 
-    <!-- Required for PKCS1 compatibility -->
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcprov-jdk18on</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcpkix-jdk18on</artifactId>
-    </dependency>
+        <!-- Required for PKCS1 compatibility -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk18on</artifactId>
+        </dependency>
 
-    <!-- Annotation preprocessors - reduce all of the boiler plate -->
-    <dependency>
-      <groupId>com.google.auto.value</groupId>
-      <artifactId>auto-value</artifactId>
-      <version>${auto-value.version}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mapstruct</groupId>
-      <artifactId>mapstruct</artifactId>
-      <version>${org.mapstruct.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.mapstruct</groupId>
-      <artifactId>mapstruct-processor</artifactId>
-      <version>${org.mapstruct.version}</version>
-      <scope>provided</scope>
-    </dependency>
+        <!-- Annotation preprocessors - reduce all of the boiler plate -->
+        <dependency>
+            <groupId>com.google.auto.value</groupId>
+            <artifactId>auto-value</artifactId>
+            <version>${auto-value.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>${org.mapstruct.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct-processor</artifactId>
+            <version>${org.mapstruct.version}</version>
+            <scope>provided</scope>
+        </dependency>
 
-    <!-- Test requirements -->
-    <dependency>
-      <groupId>org.eclipsefoundation</groupId>
-      <artifactId>quarkus-test-common</artifactId>
-      <version>${eclipse-api-version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-jacoco</artifactId>
-      <scope>test</scope>
-    </dependency>
+        <!-- Test requirements -->
+        <dependency>
+            <groupId>org.eclipsefoundation</groupId>
+            <artifactId>quarkus-test-common</artifactId>
+            <version>${eclipse-api-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jacoco</artifactId>
+            <scope>test</scope>
+        </dependency>
 
-    <!-- Following H2/devservices deps are made to circumvent need for docker -->
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-devservices-h2</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-jdbc-h2</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.h2database</groupId>
-      <artifactId>h2</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <!-- Flyway specific dependencies, used to setup tables in test -->
-    <dependency>
-      <groupId>io.quarkus</groupId>
-      <artifactId>quarkus-flyway</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
+        <!-- Following H2/devservices deps are made to circumvent need for
+        docker -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-devservices-h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-jdbc-h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- Flyway specific dependencies, used to setup tables in test -->
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-flyway</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-test-security</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.quarkus</groupId>
+            <artifactId>quarkus-test-security-oidc</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>${quarkus.platform.group-id}</groupId>
-        <artifactId>quarkus-maven-plugin</artifactId>
-        <version>${quarkus.platform.version}</version>
-        <extensions>true</extensions>
-        <executions>
-          <execution>
-            <goals>
-              <goal>build</goal>
-              <goal>generate-code</goal>
-              <goal>generate-code-tests</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>${compiler-plugin.version}</version>
-        <configuration>
-          <annotationProcessorPaths>
-            <path>
-              <groupId>com.google.auto.value</groupId>
-              <artifactId>auto-value</artifactId>
-              <version>${auto-value.version}</version>
-            </path>
-            <path>
-              <groupId>org.mapstruct</groupId>
-              <artifactId>mapstruct-processor</artifactId>
-              <version>${org.mapstruct.version}</version>
-            </path>
-          </annotationProcessorPaths>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>${surefire-plugin.version}</version>
-        <configuration>
-          <skipTests>false</skipTests>
-          <systemPropertyVariables>
-            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
-            <maven.home>${maven.home}</maven.home>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>${quarkus.platform.group-id}</groupId>
+                <artifactId>quarkus-maven-plugin</artifactId>
+                <version>${quarkus.platform.version}</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>build</goal>
+                            <goal>generate-code</goal>
+                            <goal>generate-code-tests</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${compiler-plugin.version}</version>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>com.google.auto.value</groupId>
+                            <artifactId>auto-value</artifactId>
+                            <version>${auto-value.version}</version>
+                        </path>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${org.mapstruct.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire-plugin.version}</version>
+                <configuration>
+                    <skipTests>false</skipTests>
+                    <systemPropertyVariables>
+                        <java.util.logging.manager>
+                            org.jboss.logmanager.LogManager</java.util.logging.manager>
+                        <maven.home>${maven.home}</maven.home>
+                    </systemPropertyVariables>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/GithubAdjacentResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/CommonResource.java
similarity index 62%
rename from src/main/java/org/eclipsefoundation/git/eca/resource/GithubAdjacentResource.java
rename to src/main/java/org/eclipsefoundation/git/eca/resource/CommonResource.java
index 5e8c79e751f2e3ae34d2fb66c94a39b11b173a9c..ac1ee2399fd8afaeb8457198e43e02f5c9af6f69 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/resource/GithubAdjacentResource.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/CommonResource.java
@@ -13,23 +13,29 @@ package org.eclipsefoundation.git.eca.resource;
 
 import java.util.Arrays;
 
-import jakarta.inject.Inject;
-
 import org.eclipsefoundation.core.helper.DateTimeHelper;
 import org.eclipsefoundation.core.model.RequestWrapper;
+import org.eclipsefoundation.git.eca.api.models.EclipseUser;
 import org.eclipsefoundation.git.eca.dto.GithubWebhookTracking;
+import org.eclipsefoundation.git.eca.service.UserService;
 import org.eclipsefoundation.persistence.dao.PersistenceDao;
 import org.eclipsefoundation.persistence.model.RDBMSQuery;
 import org.eclipsefoundation.persistence.service.FilterService;
 
+import io.quarkus.security.identity.SecurityIdentity;
+import io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipal;
+import jakarta.inject.Inject;
+
 /**
- * Contains operations and properties that are common to resources that interact with Github validation.
+ * Contains operations and properties that are common to resources that interact with Github validation and user accounts.
  * 
  * @author Martin Lowe
  *
  */
-public abstract class GithubAdjacentResource {
+public abstract class CommonResource {
 
+    @Inject
+    UserService users;
     @Inject
     PersistenceDao dao;
     @Inject
@@ -37,10 +43,22 @@ public abstract class GithubAdjacentResource {
 
     @Inject
     RequestWrapper wrapper;
+    @Inject
+    SecurityIdentity ident;
 
     void setRevalidationFlagForTracking(GithubWebhookTracking tracking) {
         tracking.setNeedsRevalidation(true);
         tracking.setLastUpdated(DateTimeHelper.now());
         dao.add(new RDBMSQuery<>(wrapper, filters.get(GithubWebhookTracking.class)), Arrays.asList(tracking));
     }
+
+    EclipseUser getUserForLoggedInAccount() {
+        if (ident.isAnonymous()) {
+            return null;
+        }
+        // cast to a principal w/ access to claims
+        DefaultJWTCallerPrincipal defaultPrin = (DefaultJWTCallerPrincipal) ident.getPrincipal();
+        // get the user account linked to the current claim
+        return users.getUser(defaultPrin.getClaim("email"));
+    }
 }
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/GithubWebhooksResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/GithubWebhooksResource.java
index 9fbe8f7da556734a5c6aba6abe1a0e96823e048b..98aafc28a1fd5dc548fb91341b9a2f8889fd60dc 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/resource/GithubWebhooksResource.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/GithubWebhooksResource.java
@@ -53,7 +53,7 @@ import jakarta.ws.rs.core.Response.Status;
  *
  */
 @Path("webhooks/github")
-public class GithubWebhooksResource extends GithubAdjacentResource {
+public class GithubWebhooksResource extends CommonResource {
     private static final Logger LOGGER = LoggerFactory.getLogger(GithubWebhooksResource.class);
 
     @Inject
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/OIDCResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/OIDCResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..043e36df7959dc7c70cf95367e07b52f7600a282
--- /dev/null
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/OIDCResource.java
@@ -0,0 +1,22 @@
+package org.eclipsefoundation.git.eca.resource;
+
+import java.net.URI;
+
+import io.quarkus.security.Authenticated;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Create a basic endpoint for enabling logins with redirects.
+ */
+@Authenticated
+@Path("login")
+public class OIDCResource {
+
+    @GET
+    public Response login(@QueryParam("redirect") URI redirect) {
+        return Response.status(302).location(redirect).build();
+    }
+}
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java
index 71a1e17ccef7275ebffa18893b1f3ea2c68b2062..48903cc7f687d0be3f837ce1b5955ea01fd14687 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/StatusResource.java
@@ -38,6 +38,7 @@ import jakarta.ws.rs.PathParam;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriInfo;
 
 /**
  * REST resource containing endpoints related to checking the status of validation requests.
@@ -46,7 +47,7 @@ import jakarta.ws.rs.core.Response;
  *
  */
 @Path("eca/status")
-public class StatusResource extends GithubAdjacentResource {
+public class StatusResource extends CommonResource {
 
     // parameter names for the status error page
     private static final String INCLUDE_INSTALL_LINK_PARAMETER = "includeInstallLink";
@@ -66,6 +67,9 @@ public class StatusResource extends GithubAdjacentResource {
     @Inject
     ProjectHelper projects;
 
+    @Inject
+    UriInfo info;
+
     // Qute templates, generates UI status page
     @Location("simple_fingerprint_ui")
     Template statusUiTemplate;
@@ -85,8 +89,7 @@ public class StatusResource extends GithubAdjacentResource {
     }
 
     /**
-     * Retrieves commit status information based on the fingerprint and builds a UI around the results for easier
-     * consumption.
+     * Retrieves commit status information based on the fingerprint and builds a UI around the results for easier consumption.
      * 
      * @param fingerprint the string associated with the request for looking up related commit statuses.
      * @return the HTML UI for the status of the fingerprint request
@@ -109,13 +112,15 @@ public class StatusResource extends GithubAdjacentResource {
                         .data("project", ps.isEmpty() ? null : ps.get(0))
                         .data(REPO_URL_PARAMETER, statuses.get(0).getRepoUrl())
                         .data("installationId", null)
+                        .data("currentUser", getUserForLoggedInAccount())
+                        .data("redirectUri", info.getPath())
                         .render())
                 .build();
     }
 
     /**
-     * Retrieves and checks the validity of the commit statuses for a Github pull request, and if out of date will
-     * revalidate the request automatically on load.
+     * Retrieves and checks the validity of the commit statuses for a Github pull request, and if out of date will revalidate the request
+     * automatically on load.
      * 
      * @param org the organization in Github that contains the target repo
      * @param repoName the name of the repo in Github containing the pull request
@@ -150,8 +155,7 @@ public class StatusResource extends GithubAdjacentResource {
             // get the data about the current request, and check that we have some validation statuses
             ValidationRequest req = validationHelper.generateRequest(installationId, repoFullName, prNo, repoUrl);
             List<CommitValidationStatus> statuses = validationStatus
-                    .getHistoricValidationStatusByShas(wrapper,
-                            req.getCommits().stream().map(Commit::getHash).toList());
+                    .getHistoricValidationStatusByShas(wrapper, req.getCommits().stream().map(Commit::getHash).toList());
             // check if we have any data, and if there is none, attempt to validate the request information
             if (statuses.isEmpty()) {
                 // run the validation for the current request adhoc
@@ -170,8 +174,7 @@ public class StatusResource extends GithubAdjacentResource {
                 }
 
                 // retrieve the status of the commits to display on the status page
-                statuses = validationStatus
-                        .getHistoricValidationStatusByShas(wrapper, r.getCommits().keySet().stream().toList());
+                statuses = validationStatus.getHistoricValidationStatusByShas(wrapper, r.getCommits().keySet().stream().toList());
             }
 
             // get projects for use in queries + UI
@@ -186,6 +189,8 @@ public class StatusResource extends GithubAdjacentResource {
                             .data("project", ps.isEmpty() ? null : ps.get(0))
                             .data(REPO_URL_PARAMETER, repoUrl)
                             .data("installationId", installationId)
+                            .data("currentUser", getUserForLoggedInAccount())
+                            .data("redirectUri", info.getPath())
                             .render())
                     .build();
         } catch (BadRequestException e) {
@@ -212,4 +217,5 @@ public class StatusResource extends GithubAdjacentResource {
                     .build();
         }
     }
+
 }
diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
index d2bb2ed1a71c1f651986a1e4dbc5469391975390..a32f36b7c8261315e1f5a6d662c6cb63dfe3da4d 100644
--- a/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
+++ b/src/main/java/org/eclipsefoundation/git/eca/resource/ValidationResource.java
@@ -16,67 +16,60 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
-import jakarta.inject.Inject;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.NotFoundException;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
 import org.apache.commons.lang3.StringUtils;
 import org.eclipsefoundation.core.exception.FinalForbiddenException;
 import org.eclipsefoundation.core.helper.TransformationHelper;
-import org.eclipsefoundation.core.model.RequestWrapper;
 import org.eclipsefoundation.core.service.CachingService;
 import org.eclipsefoundation.git.eca.api.models.EclipseUser;
 import org.eclipsefoundation.git.eca.helper.ProjectHelper;
 import org.eclipsefoundation.git.eca.model.ValidationRequest;
 import org.eclipsefoundation.git.eca.model.ValidationResponse;
 import org.eclipsefoundation.git.eca.namespace.APIStatusCode;
-import org.eclipsefoundation.git.eca.service.UserService;
 import org.eclipsefoundation.git.eca.service.ValidationService;
 import org.jboss.resteasy.annotations.jaxrs.QueryParam;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import io.quarkus.security.Authenticated;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
 /**
- * ECA validation endpoint for Git commits. Will use information from the bots, projects, and accounts API to validate
- * commits passed to this endpoint. Should be as system agnostic as possible to allow for any service to request
- * validation with less reliance on services external to the Eclipse foundation.
+ * ECA validation endpoint for Git commits. Will use information from the bots, projects, and accounts API to validate commits passed to
+ * this endpoint. Should be as system agnostic as possible to allow for any service to request validation with less reliance on services
+ * external to the Eclipse foundation.
  *
  * @author Martin Lowe, Zachary Sabourin
  */
 @Path("/eca")
 @Consumes({ MediaType.APPLICATION_JSON })
 @Produces({ MediaType.APPLICATION_JSON })
-public class ValidationResource {
+public class ValidationResource extends CommonResource {
     private static final Logger LOGGER = LoggerFactory.getLogger(ValidationResource.class);
 
-    @Inject
-    RequestWrapper wrapper;
-
     // external API/service harnesses
     @Inject
     CachingService cache;
     @Inject
     ProjectHelper projects;
     @Inject
-    UserService users;
-    @Inject
     ValidationService validation;
 
     /**
-     * Consuming a JSON request, this method will validate all passed commits, using the repo URL and the repository
-     * provider. These commits will be validated to ensure that all users are covered either by an ECA, or are committers on
-     * the project. In the case of ECA-only contributors, an additional sign off footer is required in the body of the
-     * commit.
+     * Consuming a JSON request, this method will validate all passed commits, using the repo URL and the repository provider. These commits
+     * will be validated to ensure that all users are covered either by an ECA, or are committers on the project. In the case of ECA-only
+     * contributors, an additional sign off footer is required in the body of the commit.
      *
      * @param req the request containing basic data plus the commits to be validated
-     * @return a web response indicating success or failure for each commit, along with standard messages that may be used
-     * to give users context on failure.
+     * @return a web response indicating success or failure for each commit, along with standard messages that may be used to give users
+     * context on failure.
      */
     @POST
     public Response validate(ValidationRequest req) {
@@ -95,7 +88,14 @@ public class ValidationResource {
 
     @GET
     @Path("/lookup")
+    @Authenticated
     public Response getUserStatus(@QueryParam("email") String email) {
+        // check that the user has committer level access
+        EclipseUser loggedInUser = getUserForLoggedInAccount();
+        if (loggedInUser == null || !loggedInUser.getIsCommitter()) {
+            throw new FinalForbiddenException("User must be logged in and have committer level access to use this endpoint.");
+        }
+        // do the lookup of the passed email
         EclipseUser user = users.getUser(email);
         if (Objects.isNull(user)) {
             throw new NotFoundException(String.format("No user found with mail '%s'", TransformationHelper.formatLog(email)));
@@ -108,8 +108,7 @@ public class ValidationResource {
     }
 
     /**
-     * Check if there are any issues with the validation request, returning error messages if there are issues with the
-     * request.
+     * Check if there are any issues with the validation request, returning error messages if there are issues with the request.
      * 
      * @param req the current validation request
      * @return a list of error messages to report, or an empty list if there are no errors with the request.
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 92e68594ce659190fc527833c2ea34e990b66be4..f40b05a96e5e03284274971f812e842d1fb2e0d4 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -21,8 +21,11 @@ quarkus.hibernate-orm.packages=org.eclipsefoundation.git.eca.dto
 quarkus.hibernate-orm.datasource=<default>
 
 ## Security configs
-quarkus.oauth2.enabled=false
-quarkus.oidc.enabled=false
+quarkus.oidc.application-type=web-app
+quarkus.oidc.token.refresh-expired=true
+quarkus.oidc.authentication.session-age-extension=60m
+quarkus.oidc.discovery-enabled=true
+quarkus.oidc.roles.source=accesstoken
 eclipse.security.oauth2.token-generation.scope=eclipsefdn_view_all_profiles
 eclipse.security.oauth2.token-generation.client-id=placeholder
 eclipse.security.oauth2.token-generation.client-secret=placeholder
diff --git a/src/main/resources/templates/simple_fingerprint_ui.html b/src/main/resources/templates/simple_fingerprint_ui.html
index 932e7027c34f8c21bfe2c00efec898c973ac57b8..a84fd87568fff5412371467670997fc8adfae0a6 100644
--- a/src/main/resources/templates/simple_fingerprint_ui.html
+++ b/src/main/resources/templates/simple_fingerprint_ui.html
@@ -179,6 +179,7 @@
         <section id="block-site-login-eclipse-eca-sle-eca-lookup-tool"
           class="margin-bottom-30 clearfix">
           <h2>ECA Validation Tool</h2>
+          {#if currentUser and currentUser.isCommitter}
           <form id="eclipse-eca-lookup-form" accept-charset="UTF-8">
             <div class="form-item form-item-input form-type-textfield form-group">
               <input placeholder="Enter email address" class="form-control form-text" type="text" id="email-input"
@@ -187,6 +188,12 @@
             </div>
             <button class="btn-success btn form-submit" type="submit" id="edit-submit">Verify ECA</button>
           </form>
+          {#else if currentUser}
+          <p>Logged in users must have committer level access to use the ECA Validation tool.</p>
+          {#else}
+          <p>Please login to use the ECA Validation tool. Please note that only committers are able to use this tool.</p>
+          <a class="btn btn-primary" href="/git/login?redirect={redirectUri}">Login</a>
+          {/if}
         </section>
         <section id="block-eclipse-api-github-eclipse-api-github-links" class="main-sidebar-default-margin">
             <ul id="leftnav" class="ul-left-nav fa-ul hidden-print" role="tablist">
diff --git a/src/test/java/org/eclipsefoundation/git/eca/resource/ValidationResourceTest.java b/src/test/java/org/eclipsefoundation/git/eca/resource/ValidationResourceTest.java
index 315f9d2ee9706becb19ce3f79c411af0d3bc226e..ba26d06fb6c1b6af6197f98c38e4ef6f43ad0b35 100644
--- a/src/test/java/org/eclipsefoundation/git/eca/resource/ValidationResourceTest.java
+++ b/src/test/java/org/eclipsefoundation/git/eca/resource/ValidationResourceTest.java
@@ -23,8 +23,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import jakarta.inject.Inject;
-
 import org.eclipsefoundation.core.exception.ApplicationException;
 import org.eclipsefoundation.core.service.CachingService;
 import org.eclipsefoundation.git.eca.model.Commit;
@@ -33,8 +31,8 @@ import org.eclipsefoundation.git.eca.model.ValidationRequest;
 import org.eclipsefoundation.git.eca.namespace.APIStatusCode;
 import org.eclipsefoundation.git.eca.namespace.ProviderType;
 import org.eclipsefoundation.git.eca.test.namespaces.SchemaNamespaceHelper;
+import org.eclipsefoundation.testing.helpers.AuthHelper;
 import org.eclipsefoundation.testing.helpers.TestCaseHelper;
-
 import org.eclipsefoundation.testing.models.EndpointTestBuilder;
 import org.eclipsefoundation.testing.models.EndpointTestCase;
 import org.junit.jupiter.api.Assertions;
@@ -45,10 +43,15 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.security.TestSecurity;
+import io.quarkus.test.security.oidc.Claim;
+import io.quarkus.test.security.oidc.OidcSecurity;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.core.Response.Status;
 
 /**
- * Tests for verifying end to end validation via the endpoint. Uses restassured to create pseudo requests, and Mock API
- * endpoints to ensure that all data is kept internal for test checks.
+ * Tests for verifying end to end validation via the endpoint. Uses restassured to create pseudo requests, and Mock API endpoints to ensure
+ * that all data is kept internal for test checks.
  *
  * @author Martin Lowe
  * @author Zachary Sabourin
@@ -115,6 +118,10 @@ class ValidationResourceTest {
      */
     public static final EndpointTestCase LOOKUP_SUCCESS_CASE = TestCaseHelper
             .buildSuccessCase(LOOKUP_URL, new String[] { "slom@eclipse-foundation.org" }, "");
+    public static final EndpointTestCase LOOKUP_ANONYMOUS_CASE = TestCaseHelper
+            .prepareTestCase(LOOKUP_URL, new String[] { "slom@eclipse-foundation.org" }, "")
+            .setStatusCode(Status.UNAUTHORIZED.getStatusCode())
+            .build();
     public static final EndpointTestCase LOOKUP_FORBIDDEN_CASE = TestCaseHelper
             .buildForbiddenCase(LOOKUP_URL, new String[] { "newbie@important.co" }, "");
     public static final EndpointTestCase LOOKUP_NOT_FOUND_CASE = TestCaseHelper
@@ -869,16 +876,34 @@ class ValidationResourceTest {
      * USER LOOKUP TESTS
      */
     @Test
+    void validateUserLookup_failure_anonymous() {
+        EndpointTestBuilder.from(LOOKUP_ANONYMOUS_CASE).run();
+    }
+
+    @Test
+    @TestSecurity(user = "newbieAnon", roles = AuthHelper.DEFAULT_ROLE)
+    @OidcSecurity(claims = { @Claim(key = "email", value = "newbie@important.co") })
+    void validateUserLookup_failure_nonCommitter() {
+        EndpointTestBuilder.from(LOOKUP_FORBIDDEN_CASE).run();
+    }
+
+    @Test
+    @TestSecurity(user = AuthHelper.TEST_USER_NAME, roles = AuthHelper.DEFAULT_ROLE)
+    @OidcSecurity(claims = { @Claim(key = "email", value = "opearson@important.co") })
     void validateUserLookup_userNotFound() {
         EndpointTestBuilder.from(LOOKUP_NOT_FOUND_CASE).run();
     }
 
     @Test
+    @TestSecurity(user = AuthHelper.TEST_USER_NAME, roles = AuthHelper.DEFAULT_ROLE)
+    @OidcSecurity(claims = { @Claim(key = "email", value = "opearson@important.co") })
     void validateUserLookup_userNoECA() {
         EndpointTestBuilder.from(LOOKUP_FORBIDDEN_CASE).run();
     }
 
     @Test
+    @TestSecurity(user = AuthHelper.TEST_USER_NAME, roles = AuthHelper.DEFAULT_ROLE)
+    @OidcSecurity(claims = { @Claim(key = "email", value = "opearson@important.co") })
     void validateUserLookup_userSuccess() {
         EndpointTestBuilder.from(LOOKUP_NOT_FOUND_CASE).run();
     }
diff --git a/src/test/java/org/eclipsefoundation/git/eca/test/api/MockAccountsAPI.java b/src/test/java/org/eclipsefoundation/git/eca/test/api/MockAccountsAPI.java
index ef1d5b0729c2fc4516d3acbf165bb9605b8fbc70..69ca77bc6bf89cef43eb904107d78546b6075dbf 100644
--- a/src/test/java/org/eclipsefoundation/git/eca/test/api/MockAccountsAPI.java
+++ b/src/test/java/org/eclipsefoundation/git/eca/test/api/MockAccountsAPI.java
@@ -26,8 +26,8 @@ import org.eclipsefoundation.git.eca.api.models.EclipseUser.ECA;
 import io.quarkus.test.Mock;
 
 /**
- * Simple stub for accounts API. Allows for easy testing of users that don't really exist upstream, and so that we don't
- * need a real auth token for data.
+ * Simple stub for accounts API. Allows for easy testing of users that don't really exist upstream, and so that we don't need a real auth
+ * token for data.
  * 
  * @author Martin Lowe
  *
@@ -104,7 +104,18 @@ public class MockAccountsAPI implements AccountsAPI {
                                 .setName("sumAnalyst")
                                 .setECA(ECA.builder().setCanContributeSpecProject(false).setSigned(true).build())
                                 .build());
-
+        users
+                .put("opearson@important.co",
+                        EclipseUser
+                                .builder()
+                                .setIsCommitter(true)
+                                .setUid(id++)
+                                .setMail("opearson@important.co")
+                                .setName("opearson")
+                                .setECA(ECA.builder().setCanContributeSpecProject(false).setSigned(true).build())
+                                .setGithubHandle("opearson")
+                                .setIsCommitter(true)
+                                .build());
     }
 
     @Override