diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html
index f9f6573f38f14c261b0d6c431ad1fb0a1cd327c5..d75f9414d1097d6d62358170a21086cb916e3412 100644
--- a/alfa-client/apps/admin/src/app/app.component.html
+++ b/alfa-client/apps/admin/src/app/app.component.html
@@ -1,4 +1,4 @@
-<ng-container *ngIf="(apiRoot$ | async)?.resource as apiRoot">
+<ng-container *ngIf="(apiRootStateResource$ | async)?.resource as apiRoot">
   <header class="flex items-center justify-between bg-white p-6" data-test-id="admin-header">
     <div class="text-ozgblue font-extrabold">OZG-Cloud Administration</div>
     <div>
diff --git a/alfa-client/apps/admin/src/app/app.component.spec.ts b/alfa-client/apps/admin/src/app/app.component.spec.ts
index 0fd3f5bb0cc54356d34ab02ddcff92a344d730bc..45e077a4ecea2d2e7e5429e8bab0ef4591ebf0cb 100644
--- a/alfa-client/apps/admin/src/app/app.component.spec.ts
+++ b/alfa-client/apps/admin/src/app/app.component.spec.ts
@@ -3,7 +3,7 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { AppComponent } from './app.component';
 import { AuthService } from '../common/auth/auth.service';
 import { Mock, mock, existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils';
-import { ApiRootService } from '@alfa-client/api-root-shared';
+import { ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
 import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
 import { of } from 'rxjs';
@@ -21,7 +21,10 @@ describe('AppComponent', () => {
   const userProfileButton: string = getDataTestIdOf('user-profile-button');
   const postfachNavigationItem: string = getDataTestIdOf('postfach-navigation-item');
 
-  const authService: Mock<AuthService> = mock(AuthService);
+  const authService: Mock<AuthService> = {
+    ...mock(AuthService),
+    login: jest.fn().mockResolvedValue(Promise.resolve()),
+  };
   const apiRootService: Mock<ApiRootService> = mock(ApiRootService);
 
   beforeEach(async () => {
@@ -65,10 +68,10 @@ describe('AppComponent', () => {
     });
 
     it('should call doAfterLoggedIn', async () => {
-      authService.login.mockImplementation(() => Promise.resolve());
       component.doAfterLoggedIn = jest.fn();
 
-      await component.ngOnInit();
+      component.ngOnInit();
+      await fixture.whenStable();
 
       expect(component.doAfterLoggedIn).toHaveBeenCalled();
     });
@@ -83,14 +86,14 @@ describe('AppComponent', () => {
   });
 
   it('show not show header if apiRoot is not loaded', () => {
-    component.apiRoot$ = of(createEmptyStateResource());
+    component.apiRootStateResource$ = of(createEmptyStateResource<ApiRootResource>());
 
     notExistsAsHtmlElement(fixture, adminHeader);
   });
 
   describe('user profile button', () => {
     beforeEach(() => {
-      component.apiRoot$ = of(createStateResource(createApiRootResource()));
+      component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
     });
 
     it('should show if apiRoot exists', () => {
@@ -102,7 +105,7 @@ describe('AppComponent', () => {
 
   describe('navigation', () => {
     beforeEach(() => {
-      component.apiRoot$ = of(createStateResource(createApiRootResource()));
+      component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
     });
     it('should have postfach item', () => {
       fixture.detectChanges();
@@ -113,7 +116,7 @@ describe('AppComponent', () => {
 
   describe('build version', () => {
     beforeEach(() => {
-      component.apiRoot$ = of(createStateResource(createApiRootResource()));
+      component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
     });
 
     it('should show after apiRoot loaded', () => {
diff --git a/alfa-client/apps/admin/src/app/app.component.ts b/alfa-client/apps/admin/src/app/app.component.ts
index 2e3c2a3e66b5ec5da01f6ff99f389c19b4b20f6d..8186bcabb4cfb9214a367603177ba8e94886cddd 100644
--- a/alfa-client/apps/admin/src/app/app.component.ts
+++ b/alfa-client/apps/admin/src/app/app.component.ts
@@ -1,7 +1,8 @@
-import { ApiRootService } from '@alfa-client/api-root-shared';
+import { ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
 import { Component, OnInit } from '@angular/core';
 import { Observable } from 'rxjs';
 import { AuthService } from '../common/auth/auth.service';
+import { StateResource } from '@alfa-client/tech-shared';
 
 @Component({
   selector: 'app-root',
@@ -11,18 +12,21 @@ import { AuthService } from '../common/auth/auth.service';
 export class AppComponent implements OnInit {
   readonly title = 'admin';
 
-  public apiRoot$: Observable<any>;
+  public apiRootStateResource$: Observable<StateResource<ApiRootResource>>;
 
   constructor(
     public authService: AuthService,
     private apiRootService: ApiRootService,
   ) {}
 
-  public async ngOnInit(): Promise<void> {
-    await this.authService.login().then(() => this.doAfterLoggedIn());
+  ngOnInit(): void {
+    this.authService.login().then(() => this.doAfterLoggedIn());
   }
 
   doAfterLoggedIn(): void {
-    this.apiRoot$ = this.apiRootService.getApiRoot();
+    this.apiRootStateResource$ = this.apiRootService.getApiRoot();
+  }
+  public reloadApiRoot(): void {
+    this.apiRootService.loadApiRoot();
   }
 }
diff --git a/alfa-client/apps/admin/src/app/app.module.ts b/alfa-client/apps/admin/src/app/app.module.ts
index e13deaf980ec4811058fd72666bd6a47659f2c47..60f1bd08c21cb15c805333ce5c3c481fa6b17895 100644
--- a/alfa-client/apps/admin/src/app/app.module.ts
+++ b/alfa-client/apps/admin/src/app/app.module.ts
@@ -1,8 +1,8 @@
 import { ApiRootModule } from '@alfa-client/api-root-shared';
-import { ENVIRONMENT_CONFIG, EnvironmentModule } from '@alfa-client/environment-shared';
+import { EnvironmentModule } from '@alfa-client/environment-shared';
 import { CommonModule } from '@angular/common';
-import { HttpClientModule } from '@angular/common/http';
-import { APP_INITIALIZER, NgModule } from '@angular/core';
+import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
+import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterModule } from '@angular/router';
@@ -11,16 +11,16 @@ import { StoreRouterConnectingModule } from '@ngrx/router-store';
 import { StoreModule } from '@ngrx/store';
 import { StoreDevtoolsModule } from '@ngrx/store-devtools';
 import { TestbtnComponent } from 'design-system';
-import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
 import { environment } from '../environments/environment';
 import { AppComponent } from './app.component';
-import { initializeKeycloak } from './app.config';
 import { appRoutes } from './app.routes';
 import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component';
 import { AdminSettingsModule } from '@admin-client/admin-settings';
 import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navigation-item/postfach-navigation-item.component';
+import { OAuthModule } from 'angular-oauth2-oidc';
+import { HttpUnauthorizedInterceptor } from '../common/interceptor/http-unauthorized.interceptor';
 
 @NgModule({
   declarations: [
@@ -36,7 +36,6 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi
     BrowserModule,
     BrowserAnimationsModule,
     HttpClientModule,
-    KeycloakAngularModule,
     ApiRootModule,
     EnvironmentModule,
     environment.production ? [] : StoreDevtoolsModule.instrument(),
@@ -46,13 +45,17 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi
     FormsModule,
     ReactiveFormsModule,
     AdminSettingsModule,
+    OAuthModule.forRoot({
+      resourceServer: {
+        sendAccessToken: true,
+      },
+    }),
   ],
   providers: [
     {
-      provide: APP_INITIALIZER,
-      useFactory: initializeKeycloak,
+      provide: HTTP_INTERCEPTORS,
+      useClass: HttpUnauthorizedInterceptor,
       multi: true,
-      deps: [KeycloakService, ENVIRONMENT_CONFIG],
     },
   ],
   bootstrap: [AppComponent],
diff --git a/alfa-client/apps/admin/src/common/auth/auth.service.spec.ts b/alfa-client/apps/admin/src/common/auth/auth.service.spec.ts
index 8d44ffa2b0eb2c1d0d5853bd506f846ba5920454..4cfb03ac88b573a851db79bfc90552306436d009 100644
--- a/alfa-client/apps/admin/src/common/auth/auth.service.spec.ts
+++ b/alfa-client/apps/admin/src/common/auth/auth.service.spec.ts
@@ -1,164 +1,122 @@
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
 import { AuthService } from './auth.service';
-import { KeycloakService, KeycloakEvent, KeycloakEventType } from 'keycloak-angular';
-import { of } from 'rxjs';
-import { KeycloakProfile } from 'keycloak-js';
-import { StateResource, createStateResource } from '@alfa-client/tech-shared';
 import { UserProfileResource } from '@alfa-client/user-profile-shared';
 import { createUserProfileResource } from '../../../../../libs/user-profile-shared/test/user-profile';
+import { JwksValidationHandler, OAuthService } from 'angular-oauth2-oidc';
 
 describe('AuthService', () => {
   let service: AuthService;
-  let keycloakService: Mock<KeycloakService>;
-
-  const event: KeycloakEvent = <any>{};
+  let oAuthService: Mock<OAuthService>;
+  let environmentConfig;
 
   beforeEach(() => {
-    keycloakService = { ...mock(KeycloakService), keycloakEvents$: <any>of(event) };
+    oAuthService = mock(OAuthService);
+    environmentConfig = {};
 
-    service = new AuthService(useFromMock(keycloakService));
+    service = new AuthService(useFromMock(oAuthService), environmentConfig);
   });
 
-  describe('listenToKeycloakEvent', () => {
-    it('should call handleEvent', () => {
-      service.handleEvent = jest.fn();
+  describe('login', () => {
+    it('should call proceedWithLogin', () => {
+      service.proceedWithLogin = jest.fn().mockImplementation(() => Promise.resolve());
 
-      service.listenToKeycloakEvent();
+      service.login();
 
-      expect(service.handleEvent).toHaveBeenCalledWith(event);
+      expect(service.proceedWithLogin).toHaveBeenCalled();
     });
-  });
-
-  describe('handleEvent', () => {
-    describe('on token expired event', () => {
-      const tokenExpiredEvent: KeycloakEvent = { type: KeycloakEventType.OnTokenExpired };
-
-      it('should updateToken', () => {
-        service.handleEvent(tokenExpiredEvent);
 
-        expect(keycloakService.updateToken).toHaveBeenCalledWith(10);
+    describe.skip('FIXME(proper mock of then)proceed with login', () => {
+      beforeEach(() => {
+        oAuthService.loadDiscoveryDocumentAndTryLogin.mockImplementation(() => Promise.resolve());
       });
 
-      it('should call handleTokenExpireEvent', async () => {
-        const updateTokenReturnValue: boolean = true;
-        service.handleTokenExpiredEvent = jest.fn();
-        keycloakService.updateToken.mockImplementation(() =>
-          Promise.resolve(updateTokenReturnValue),
-        );
-
-        await service.handleEvent(tokenExpiredEvent);
+      it('should configure service', () => {
+        service.proceedWithLogin(Promise.resolve);
 
-        expect(service.handleTokenExpiredEvent).toHaveBeenCalledWith(updateTokenReturnValue);
+        expect(oAuthService.configure).toHaveBeenCalled();
       });
-    });
-  });
-
-  describe('handleTokenExpiredEvent', () => {
-    it('should getToken if refresh was success', () => {
-      service.handleTokenExpiredEvent(true);
 
-      expect(keycloakService.getToken).toHaveBeenCalled();
-    });
-
-    it('should store token', async () => {
-      const token: string = 'tokenDummy';
-      service.storeAccessToken = jest.fn();
-      keycloakService.getToken.mockImplementation(() => Promise.resolve(token));
-
-      await service.handleTokenExpiredEvent(true);
-
-      expect(service.storeAccessToken).toHaveBeenCalledWith(token);
-    });
-  });
+      it('should setup automatic silent refresh', () => {
+        service.proceedWithLogin(Promise.resolve);
 
-  describe('login', () => {
-    it('should call isLoggedIn', () => {
-      service.login();
+        expect(oAuthService.setupAutomaticSilentRefresh).toHaveBeenCalled();
+      });
 
-      expect(keycloakService.isLoggedIn());
-    });
+      it('should set tokenValidator', () => {
+        oAuthService.tokenValidationHandler = null;
 
-    describe('after loggedIn', () => {
-      const isLoggedIn: boolean = true;
+        service.proceedWithLogin(Promise.resolve);
 
-      beforeEach(() => {
-        keycloakService.isLoggedIn.mockImplementation(() => Promise.resolve(isLoggedIn));
-        service.setCurrentUser = jest.fn();
+        expect(oAuthService.tokenValidationHandler).toEqual(new JwksValidationHandler());
       });
-      it('should store token', async () => {
-        const token: string = 'tokenDummy';
-        keycloakService.getToken.mockImplementation(() => Promise.resolve(token));
-        service.storeAccessToken = jest.fn();
 
-        await service.login();
+      it('should load discovery document and login', () => {
+        service.proceedWithLogin(Promise.resolve);
 
-        expect(service.storeAccessToken).toHaveBeenCalledWith(token);
+        expect(oAuthService.loadDiscoveryDocumentAndLogin).toHaveBeenCalled();
       });
 
-      it('should set currentUser', async () => {
-        await service.login();
+      it('should set current user', () => {
+        service.setCurrentUser = jest.fn();
+
+        service.proceedWithLogin(Promise.resolve);
 
         expect(service.setCurrentUser).toHaveBeenCalled();
       });
-    });
-    describe('if not logged in yet', () => {
-      it('should call login', async () => {
-        const isLoggedIn: boolean = false;
-        keycloakService.isLoggedIn.mockImplementation(() => Promise.resolve(isLoggedIn));
 
-        await service.login();
+      it('should resolve', () => {
+        const resolve = Promise.resolve;
+
+        service.proceedWithLogin(resolve);
 
-        expect(keycloakService.login).toHaveBeenCalledWith({ scope: 'offline_access' });
+        expect(resolve).toHaveBeenCalled();
       });
     });
   });
 
-  describe('store access token', () => {
-    it('should put token in sessionStorage', () => {
-      const token: string = 'tokenDummy';
-
-      service.storeAccessToken(token);
-
-      const accessTokenInSessionStorage: string = sessionStorage.getItem('access_token');
+  describe('set current user', () => {
+    const identityClaims: Record<string, any> = {
+      ['given_name']: 'Marco',
+      ['family_name']: 'Polo',
+    };
 
-      expect(accessTokenInSessionStorage).toStrictEqual(token);
+    beforeEach(() => {
+      oAuthService.getIdentityClaims.mockReturnValue(identityClaims);
     });
-  });
-  describe('logout', () => {
-    it('should call keycloakservice logout', () => {
-      service.logout();
+    it('should call oAuthservice to get claims', () => {
+      service.setCurrentUser();
 
-      expect(keycloakService.logout).toHaveBeenCalled();
+      expect(oAuthService.getIdentityClaims).toHaveBeenCalled();
     });
-  });
 
-  describe('set current user', () => {
-    it('should load user profile', () => {
+    it('should update currentUser', () => {
       service.setCurrentUser();
 
-      expect(keycloakService.loadUserProfile).toHaveBeenCalled();
+      expect(service.currentUserResource().firstName).toEqual('Marco');
+      expect(service.currentUserResource().lastName).toEqual('Polo');
     });
-    it('should update current user state resource', async () => {
-      const profile: KeycloakProfile = { firstName: 'blubb', lastName: 'blabb' };
-      keycloakService.loadUserProfile.mockImplementation(() => Promise.resolve(profile));
+  });
 
-      await service.setCurrentUser();
+  describe('getCurrentUserInitials', () => {
+    it('should return currentUserResource', () => {
+      const userProfile: UserProfileResource = {
+        ...createUserProfileResource(),
+        firstName: 'Marco',
+        lastName: 'Polo',
+      };
+      service.currentUserResource.set(userProfile);
 
-      expect(service.currentUserStateResource()).toEqual(createStateResource(profile));
+      const currentUserInitials: string = service.getCurrentUserInitials();
+
+      expect(currentUserInitials).toEqual('MP');
     });
   });
 
-  describe('getCurrentUserInitials', () => {
-    it('should return currentUserStateResource', () => {
-      const userProfile: UserProfileResource = createUserProfileResource();
-      const userStateResource: StateResource<UserProfileResource> =
-        createStateResource(userProfile);
-      service.currentUserStateResource.set(userStateResource);
-      const currentUserInitials: string = service.getCurrentUserInitials();
+  describe('logout', () => {
+    it('should call oAuthService revokeTokenAndLogout', () => {
+      service.logout();
 
-      const initials: string =
-        userProfile.firstName.substring(0, 1) + '' + userProfile.lastName.substring(0, 1);
-      expect(currentUserInitials).toEqual(initials);
+      expect(oAuthService.revokeTokenAndLogout).toHaveBeenCalled();
     });
   });
 });
diff --git a/alfa-client/apps/admin/src/common/auth/auth.service.ts b/alfa-client/apps/admin/src/common/auth/auth.service.ts
index 6f7ceb589abc8064c61f878dda5494f2051c5d52..0f6a345310573367899352c09fef9ca97cd7ab25 100644
--- a/alfa-client/apps/admin/src/common/auth/auth.service.ts
+++ b/alfa-client/apps/admin/src/common/auth/auth.service.ts
@@ -1,77 +1,66 @@
-import {
-  StateResource,
-  createEmptyStateResource,
-  createStateResource,
-} from '@alfa-client/tech-shared';
-import { Injectable, WritableSignal, signal } from '@angular/core';
-import { KeycloakEvent, KeycloakEventType, KeycloakService } from 'keycloak-angular';
-import { KeycloakProfile } from 'keycloak-js';
+import { ENVIRONMENT_CONFIG, Environment } from '@alfa-client/environment-shared';
+import { Inject, Injectable, WritableSignal, signal } from '@angular/core';
+import { OAuthService, AuthConfig } from 'angular-oauth2-oidc';
+import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';
 import { UserProfileResource } from 'libs/user-profile-shared/src/lib/user-profile.model';
 import { getUserNameInitials } from 'libs/user-profile-shared/src/lib/user-profile.util';
 
 @Injectable({ providedIn: 'root' })
 export class AuthService {
-  currentUserStateResource: WritableSignal<StateResource<UserProfileResource>> = signal<
-    StateResource<UserProfileResource>
-  >(createEmptyStateResource());
+  currentUserResource: WritableSignal<UserProfileResource> = signal<UserProfileResource>(undefined);
 
-  public isLoggedIn = false;
-
-  constructor(private keycloak: KeycloakService) {
-    this.listenToKeycloakEvent();
-  }
-
-  listenToKeycloakEvent(): void {
-    this.keycloak.keycloakEvents$.subscribe((event: KeycloakEvent) => this.handleEvent(event));
-  }
-
-  async handleEvent(event: KeycloakEvent): Promise<void> {
-    if (event.type === KeycloakEventType.OnTokenExpired) {
-      await this.keycloak
-        .updateToken(10)
-        .then((refreshed) => this.handleTokenExpiredEvent(refreshed));
-    }
-  }
-
-  async handleTokenExpiredEvent(refreshed: boolean): Promise<void> {
-    if (refreshed) {
-      await this.keycloak.getToken().then((token) => this.storeAccessToken(token));
-    }
-  }
+  constructor(
+    private oAuthService: OAuthService,
+    @Inject(ENVIRONMENT_CONFIG) private envConfig: Environment,
+  ) {}
 
   public async login(): Promise<void> {
-    this.isLoggedIn = await this.keycloak.isLoggedIn();
-    if (this.isLoggedIn) {
-      const token: string = await this.keycloak.getToken();
-      this.storeAccessToken(token);
-      await this.setCurrentUser();
-    } else {
-      this.keycloak.login({ scope: 'offline_access' });
-    }
+    return new Promise<void>((resolve: (value: void | PromiseLike<void>) => void) =>
+      this.proceedWithLogin(resolve),
+    );
   }
 
-  storeAccessToken(token: string): void {
-    sessionStorage.setItem('access_token', token);
+  proceedWithLogin(resolve: (value: void | PromiseLike<void>) => void): void {
+    this.oAuthService.configure(this.buildConfiguration());
+    this.oAuthService.setupAutomaticSilentRefresh();
+    this.oAuthService.tokenValidationHandler = new JwksValidationHandler();
+    this.oAuthService.loadDiscoveryDocumentAndLogin().then(() => {
+      this.setCurrentUser();
+      resolve();
+    });
   }
 
-  async setCurrentUser(): Promise<void> {
-    const profile: KeycloakProfile = await this.keycloak.loadUserProfile();
-
-    this.currentUserStateResource.set(createStateResource(this.buildUserProfileResource(profile)));
+  private buildConfiguration(): AuthConfig {
+    return {
+      issuer: this.envConfig.authServer + '/realms/' + this.envConfig.realm,
+      tokenEndpoint:
+        this.envConfig.authServer +
+        '/realms/' +
+        this.envConfig.realm +
+        '/protocol/openid-connect/token',
+      redirectUri: window.location.origin + '/',
+      clientId: this.envConfig.clientId,
+      scope: 'openid profile',
+      requireHttps: false,
+      responseType: 'code',
+      showDebugInformation: true,
+    };
   }
 
-  private buildUserProfileResource(profile: KeycloakProfile): UserProfileResource {
-    return <any>{
-      firstName: profile.firstName,
-      lastName: profile.lastName,
+  setCurrentUser(): void {
+    const claims: Record<string, any> = this.oAuthService.getIdentityClaims();
+    const userResource: UserProfileResource = <any>{
+      firstName: claims['given_name'],
+      lastName: claims['family_name'],
     };
+    this.currentUserResource.set(userResource);
   }
 
-  public logout(): void {
-    this.keycloak.logout();
+  public getCurrentUserInitials(): string {
+    return getUserNameInitials(this.currentUserResource());
   }
 
-  public getCurrentUserInitials(): string {
-    return getUserNameInitials(this.currentUserStateResource().resource);
+  public logout(): void {
+    this.oAuthService.revokeTokenAndLogout();
   }
 }
diff --git a/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.spec.ts b/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..09cc8f5549c05cb34203c8c0b92fc64efa984496
--- /dev/null
+++ b/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.spec.ts
@@ -0,0 +1,79 @@
+import { Mock, mock } from '@alfa-client/test-utils';
+import { TestBed } from '@angular/core/testing';
+import { MatDialogModule } from '@angular/material/dialog';
+import { HttpUnauthorizedInterceptor } from './http-unauthorized.interceptor';
+import { AuthService } from '../auth/auth.service';
+import { HttpErrorResponse, HttpHandler, HttpRequest } from '@angular/common/http';
+import { Subject, isEmpty } from 'rxjs';
+
+describe('HttpUnauthorizedInterceptor', () => {
+  let interceptor: HttpUnauthorizedInterceptor;
+
+  const authService: Mock<AuthService> = mock(AuthService);
+
+  beforeEach(() =>
+    TestBed.configureTestingModule({
+      imports: [MatDialogModule],
+      providers: [
+        HttpUnauthorizedInterceptor,
+        {
+          provide: AuthService,
+          useValue: authService,
+        },
+      ],
+    }),
+  );
+
+  beforeEach(() => {
+    interceptor = TestBed.inject(HttpUnauthorizedInterceptor);
+  });
+
+  it('should be created', () => {
+    expect(interceptor).toBeTruthy();
+  });
+
+  describe('intercept', () => {
+    const error: HttpErrorResponse = new HttpErrorResponse({});
+
+    const handleSubject: Subject<any> = new Subject();
+    const httpHandler: HttpHandler = { handle: () => handleSubject };
+    const request: HttpRequest<unknown> = new HttpRequest('GET', '/test');
+
+    it('should call handleError with error', () => {
+      interceptor.handleError = jest.fn();
+
+      interceptor.intercept(request, httpHandler).subscribe();
+      handleSubject.error(error);
+
+      expect(interceptor.handleError).toHaveBeenCalledWith(error);
+    });
+  });
+
+  describe('handleError', () => {
+    describe('on unauthorized status', () => {
+      const unauthorizedError: any = new HttpErrorResponse({ status: 401 });
+
+      it('should call logout on authService ', () => {
+        interceptor.handleError(unauthorizedError);
+
+        expect(authService.logout).toHaveBeenCalled();
+      });
+
+      it('should return EMPTY', (done) => {
+        interceptor
+          .handleError(unauthorizedError)
+          .pipe(isEmpty())
+          .subscribe((res) => {
+            expect(res).toBeTruthy;
+            done();
+          });
+      });
+    });
+
+    it('should rethrow error if not unauthorized status', () => {
+      const anyError: any = new HttpErrorResponse({ status: 500 });
+
+      expect(() => interceptor.handleError(anyError)).toThrowError();
+    });
+  });
+});
diff --git a/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.ts b/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5c36e97cd331ea6e7ab4b6f26187d641c09674a5
--- /dev/null
+++ b/alfa-client/apps/admin/src/common/interceptor/http-unauthorized.interceptor.ts
@@ -0,0 +1,34 @@
+import {
+  HttpErrorResponse,
+  HttpEvent,
+  HttpHandler,
+  HttpInterceptor,
+  HttpRequest,
+} from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { isUnauthorized } from '@alfa-client/tech-shared';
+import { EMPTY, Observable } from 'rxjs';
+import { catchError } from 'rxjs/operators';
+import { AuthService } from '../auth/auth.service';
+
+@Injectable()
+export class HttpUnauthorizedInterceptor implements HttpInterceptor {
+  constructor(private authService: AuthService) {}
+
+  public intercept(
+    request: HttpRequest<unknown>,
+    next: HttpHandler,
+  ): Observable<HttpEvent<unknown>> {
+    return next
+      .handle(request)
+      .pipe(catchError((error: HttpErrorResponse) => this.handleError(error)));
+  }
+
+  handleError(error: HttpErrorResponse): Observable<any> {
+    if (isUnauthorized(error.status)) {
+      this.authService.logout();
+      return EMPTY;
+    }
+    throw error;
+  }
+}