diff --git a/alfa-client/apps/alfa-e2e/docker-compose.yml b/alfa-client/apps/alfa-e2e/docker-compose.yml
index c1084ee33bd694659129af4a90e59dc5d1b0c288..e541a7eef1c009fcd890726f87fb35cb11b50868 100644
--- a/alfa-client/apps/alfa-e2e/docker-compose.yml
+++ b/alfa-client/apps/alfa-e2e/docker-compose.yml
@@ -211,10 +211,7 @@ services:
       - 7080:8080
       - 7081:8081
     healthcheck:
-      test: [
-             'CMD-SHELL',
-             "wget --spider localhost:8081/version",
-      ]
+      test: ['CMD-SHELL', 'wget --spider localhost:8081/version']
       interval: 5s
       timeout: 5s
       retries: 5
@@ -228,4 +225,4 @@ services:
             curl -X POST http://smocker:8081/mocks -H 'Content-Type: application/x-yaml' --data-binary @/mocks/mocks.yaml"
     depends_on:
       smocker:
-        condition: service_healthy
\ No newline at end of file
+        condition: service_healthy
diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-zusammenarbeit.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-zusammenarbeit.e2e.component.ts
index 9433275b79fafd874af6f7fbef835e5ad2deb76f..9197f6bc89b181b3cfb5851d03d86083b60704ed 100644
--- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-zusammenarbeit.e2e.component.ts
+++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-zusammenarbeit.e2e.component.ts
@@ -1,4 +1,4 @@
-import { enterWith } from '../../support/cypress.util';
+import { contains, enterWith, haveValue } from '../../support/cypress.util';
 
 export class VorgangZusammenarbeitE2EComponent {
   private readonly anfrageButton: string = 'anfrage-erstellen-button';
@@ -7,6 +7,12 @@ export class VorgangZusammenarbeitE2EComponent {
   private readonly messageText: string = 'Nachricht-textarea';
   private readonly sendButton: string = 'collaboration-request-submit-button';
   private readonly cancelButton: string = 'collaboration-request-cancel-button';
+  private readonly searchText: string = 'instant_search-text-input';
+  private readonly closeSearchButton: string = 'close-search-dialog';
+  private readonly clearSearchButton: string = 'clear-instant-search';
+  private readonly searchEntry: string = 'item-button';
+  private readonly orgaAddress: string = 'organisations-einheit-in-collaboration';
+  private readonly anfrageResult: string = 'collaboration-request-result';
 
   public getAnfrageButton(): Cypress.Chainable<JQuery<HTMLElement>> {
     return cy.getTestElement(this.anfrageButton);
@@ -64,4 +70,60 @@ export class VorgangZusammenarbeitE2EComponent {
   public cancelAnfrage(): void {
     this.getCancelButton().click();
   }
+
+  public getCloseSearchButton(): Cypress.Chainable<JQuery<HTMLElement>> {
+    return cy.getTestElement(this.closeSearchButton);
+  }
+
+  public closeSearch(): void {
+    this.getCloseSearchButton().click();
+  }
+
+  public getSearchText(): Cypress.Chainable<JQuery<HTMLElement>> {
+    return cy.getTestElement(this.searchText);
+  }
+
+  public hasSearchText(text: string): void {
+    haveValue(this.getSearchText(), text);
+  }
+
+  public enterSearchInput(text: string): void {
+    this.getSearchText().clear().type(text);
+  }
+
+  public getClearSearchButton(): Cypress.Chainable<JQuery<HTMLElement>> {
+    return cy.getTestElement(this.clearSearchButton);
+  }
+
+  public clearSearch(): void {
+    this.getClearSearchButton().click();
+  }
+
+  public countSearchEntries(): Cypress.Chainable<number> {
+    return cy.getTestElement(this.searchEntry).then((entries) => {
+      return Cypress.$(entries).length;
+    });
+  }
+
+  public expectNumberOfEntriesToBe(entries: number): void {
+    this.countSearchEntries().then((count) => {
+      expect(count).to.equal(entries);
+    });
+  }
+
+  public clickSearchEntry(index: number): void {
+    cy.getTestElement(this.searchEntry).eq(index).click();
+  }
+
+  public addressContains(address: string): void {
+    contains(cy.getTestElement(this.orgaAddress), address);
+  }
+
+  public getAnfrageResult(): Cypress.Chainable<JQuery<HTMLElement>> {
+    return cy.getTestElement(this.anfrageResult);
+  }
+
+  public anfrageResultContains(anfrage: string): void {
+    contains(this.getAnfrageResult(), anfrage);
+  }
 }
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
index eca73b26f756e3a3610b82f62299ddbde612e5a3..10a58ba9be2022445c7f3bbae826a7388a88ca3b 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/postfach-mail/postfach-nachricht-reply-button.cy.ts
@@ -44,7 +44,7 @@ describe('Postfach Nachricht reply button', () => {
     header: {
       collaborationLevel: 0,
       serviceKonto: {
-        type: 'BayernId',
+        type: 'BAYERN_ID',
         postfachAddress: [
           {
             type: 1,
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-ungelesen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-ungelesen.cy.ts
index 323803e5693ea60d476d70aff45717143b624cc4..f81145752792b75c1f19e7169f42dbc0a9c5e54c 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-ungelesen.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-list/vorgang-list-ungelesen.cy.ts
@@ -32,7 +32,7 @@ import {
   objectIds,
 } from '../../../support/vorgang-util';
 
-describe('Ungelesene Nachrichten', () => {
+describe('VorgangList Ungelesene Nachrichten', () => {
   const mainPage: MainPage = new MainPage();
   const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList();
   const vorgangPage: VorgangPage = new VorgangPage();
diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-zusammenarbeit/vorgang-zusammenarbeit-anfragen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-zusammenarbeit/vorgang-zusammenarbeit-anfragen.cy.ts
index e02c7bed2c4080d6b8fa7d227f826722c67699ce..ff47d4f57c44947ca091adfd2b7075fa92013942 100644
--- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-zusammenarbeit/vorgang-zusammenarbeit-anfragen.cy.ts
+++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-zusammenarbeit/vorgang-zusammenarbeit-anfragen.cy.ts
@@ -1,14 +1,15 @@
 import { registerLocaleData } from '@angular/common';
 import localeDe from '@angular/common/locales/de';
 import localeDeExtra from '@angular/common/locales/extra/de';
+import { SnackBarE2EComponent } from 'apps/alfa-e2e/src/components/ui/snackbar.e2e.component';
 import { VorgangZusammenarbeitE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-zusammenarbeit.e2e.component';
-import { VorgangE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang';
+import { VorgangE2E, VorgangMessagesE2E, VorgangStatusE2E } from 'apps/alfa-e2e/src/model/vorgang';
 import 'cypress-real-events/support';
 import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component';
 import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po';
 import { VorgangPage } from '../../../page-objects/vorgang.po';
 import { dropCollections } from '../../../support/cypress-helper';
-import { exist, notExist } from '../../../support/cypress.util';
+import { contains, exist, notExist } from '../../../support/cypress.util';
 import { initUsermanagerUsers, loginAsSabine } from '../../../support/user-util';
 import { buildVorgang, initVorgaenge, objectIds } from '../../../support/vorgang-util';
 
@@ -30,6 +31,9 @@ describe('Vorgang Zusammenarbeit anfragen', () => {
   const titleText: string = 'Dies ist ein Test-Titel !"§$%&';
   const messageText: string =
     'Sehr geehrter Tester\n\n Dies ist ein !"§$%& Test\n zum Testen der Nachricht.\n\n\n\nhier sollte eine \nScrollbar\nangezeigt\nwerden!\n\nMfG!';
+  const stelleSearch1: string = 'k';
+  const stelleSearch2: string = 'Kiel';
+  const snackBar: SnackBarE2EComponent = mainPage.getSnackBar();
 
   before(() => {
     initVorgaenge([zusammenarbeitVorgang]);
@@ -76,48 +80,66 @@ describe('Vorgang Zusammenarbeit anfragen', () => {
 
     it('should open new search label for Zustaendige Stelle', () => {
       zusammenarbeitContainer.createAnfrage();
-      //button click
-      //Layer wird angezeigt
+      zusammenarbeitContainer.searchZustaendigeStelle();
+
+      exist(zusammenarbeitContainer.getCloseSearchButton());
+      exist(zusammenarbeitContainer.getSearchText());
     });
 
     it('should close layer on Cancel click', () => {
-      //click Abbrechen
+      zusammenarbeitContainer.closeSearch();
+
+      notExist(zusammenarbeitContainer.getCloseSearchButton());
+      notExist(zusammenarbeitContainer.getSearchText());
+      exist(zusammenarbeitContainer.getZustaendigeStelleButton());
     });
 
-    it('should show no search on entering 1 element', () => {
-      //1 Zeichen in Suche eingeben
-      //keine Vorschau
+    it('should delete search term on clicking X', () => {
+      zusammenarbeitContainer.searchZustaendigeStelle();
+      zusammenarbeitContainer.enterSearchInput(stelleSearch1);
+      zusammenarbeitContainer.clearSearch();
+
+      zusammenarbeitContainer.hasSearchText('');
     });
 
-    it('should show results on entering 2 elements', () => {
-      //2 Zeichen in Suche eingeben
-      //Vorschau kontrollieren
+    it.skip('TODO: Setup Jenkins --- should find 2 results after entering kiel', () => {
+      zusammenarbeitContainer.enterSearchInput(stelleSearch2);
+
+      zusammenarbeitContainer.expectNumberOfEntriesToBe(2);
     });
 
-    it('should delete search term on clicking X', () => {
-      //X in Suche klicken
-      //Suche ist leer
-      //keine Vorschau
+    it.skip('should close layer after click on search entry', () => {
+      zusammenarbeitContainer.clickSearchEntry(0);
+
+      exist(zusammenarbeitContainer.getSendButton());
+      notExist(zusammenarbeitContainer.getSearchText());
     });
 
-    it('should copy and paste Zustaendige Stelle after selection', () => {
-      //click Suchergebnis
-      //Adresse und Name wird übernommen
-      //Layer ist geschlossen
+    it.skip('should show part of address in Zufi header', () => {
+      zusammenarbeitContainer.addressContains(stelleSearch2);
     });
 
-    it('should be able to enter title and message, and show scrollbar on long text', () => {
+    it.skip('should be able to enter title and message, and show scrollbar on long text', () => {
       zusammenarbeitContainer.enterTitel(titleText);
       zusammenarbeitContainer.enterMessage(messageText);
 
       zusammenarbeitContainer.messageScrollbarIsPresent();
     });
 
-    it('should show title and message read-only and remove buttons after sending', () => {
-      //Button klicken
-      //Titel und Datum werden angezeigt
-      //Nachricht wird angezeigt
-      //Buttons werden ausgeblendet
+    it.skip('should show title and message, show snackbar, and remove buttons after sending', () => {
+      zusammenarbeitContainer.sendAnfrage();
+
+      notExist(zusammenarbeitContainer.getSendButton());
+      notExist(zusammenarbeitContainer.getCancelButton());
+
+      zusammenarbeitContainer.anfrageResultContains(titleText);
+
+      //TODO: Zeilenumbrüche (OZG-6682)
+      //zusammenarbeitContainer.anfrageResultContains(messageText);
+
+      //TODO: Datum wird angezeigt (OZG-6675)
+
+      contains(snackBar.getMessage(), VorgangMessagesE2E.ZUARBEIT_ANGEFRAGT);
     });
   });
 });
diff --git a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml
index 0c58eb6aae1455fb57339185833c48b0e3c1eee9..58e0660e0f37cba42cc6ab8ed1b0c824d5e3902d 100644
--- a/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml
+++ b/alfa-client/apps/alfa-e2e/src/fixtures/argocd/by-ea-dev.yaml
@@ -20,6 +20,8 @@ alfa:
         first_name: Emil
         last_name: Ansprechpartner
         password: 'Y9nk43yrQ_zzIPpfFU-I'
+        update_user: true
+        email: emil.ansprechpartner@ozg-sh.de
         client_roles:
           - name: alfa
             role: EINHEITLICHER_ANSPRECHPARTNER
diff --git a/alfa-client/apps/alfa-e2e/src/model/vorgang.ts b/alfa-client/apps/alfa-e2e/src/model/vorgang.ts
index 7fdbcfd62b93935aef7f35cb4a4f7fc1858c4422..472bf861d161a81067038844cd3adbcf27c02f71 100644
--- a/alfa-client/apps/alfa-e2e/src/model/vorgang.ts
+++ b/alfa-client/apps/alfa-e2e/src/model/vorgang.ts
@@ -157,6 +157,7 @@ export enum VorgangMessagesE2E {
   LOESCHEN_ANFORDERN = 'Für den Vorgang wurde eine Löschanforderung gestellt.',
   ENDGUELTIG_LOESCHEN = 'Der Vorgang wurde gelöscht.',
   WIEDERVORLAGE_BEARBEITEN_NICHT_MOEGLICH = 'Im Status "Zu löschen" ist die Bearbeitung von Wiedervorlagen nicht möglich.',
+  ZUARBEIT_ANGEFRAGT = 'Die Zuarbeit wurde angefragt.',
 }
 
 export const NO_AKTENZEICHEN: string = 'kein Aktenzeichen zugewiesen';
diff --git a/alfa-client/apps/demo/src/app/app.component.html b/alfa-client/apps/demo/src/app/app.component.html
index 7dbdd36d8134a9a38fdd859b1371c5a0362820df..4c187c3b809d118c8bc9bb2a3fed9b29534338ff 100644
--- a/alfa-client/apps/demo/src/app/app.component.html
+++ b/alfa-client/apps/demo/src/app/app.component.html
@@ -54,6 +54,17 @@
       </div>
 
       <form id="antrag_bescheiden_form" [formGroup]="exampleForm">
+        <div class="my-4">
+          <ods-fieldset legend="Checkboxes!" name="Checkboxes group">
+            <ods-checkbox label="Brand new checkbox" inputId="chckbx1" />
+            <ods-checkbox label="Disabled checkbox" inputId="chckbx2" [disabled]="true" />
+            <ods-checkbox
+              label="Checkbox with error"
+              inputId="chckbx3"
+              [fieldControl]="checkboxControl"
+            />
+          </ods-fieldset>
+        </div>
         <div class="my-4">
           <ods-text-input id="test-input-id1" label="Betreff" placeholder="Betreff hier eingeben" />
         </div>
diff --git a/alfa-client/apps/demo/src/app/app.component.ts b/alfa-client/apps/demo/src/app/app.component.ts
index fbd58a87093ed57b19c83b1e1c78151e75ca1b66..fe9bea7b9e284ee8c47c36bb051a6e682f991b84 100644
--- a/alfa-client/apps/demo/src/app/app.component.ts
+++ b/alfa-client/apps/demo/src/app/app.component.ts
@@ -11,8 +11,10 @@ import {
   BescheidUploadIconComponent,
   ButtonCardComponent,
   ButtonComponent,
+  CheckboxComponent,
   CloseIconComponent,
   ErrorMessageComponent,
+  FieldsetComponent,
   FileIconComponent,
   FileUploadButtonComponent,
   InstantSearchComponent,
@@ -40,6 +42,8 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com
 @Component({
   standalone: true,
   imports: [
+    CheckboxComponent,
+    FieldsetComponent,
     CommonModule,
     AttachmentComponent,
     AttachmentWrapperComponent,
@@ -101,6 +105,7 @@ export class AppComponent {
     },
   ];
   instantSearchFormControl = new FormControl(EMPTY_STRING);
+  checkboxControl = new FormControl(false);
 
   getInstantSearchResults() {
     if (this.instantSearchFormControl.value.length < 2) return [];
@@ -127,6 +132,7 @@ export class AppComponent {
     effect(() => {
       window.localStorage.setItem('darkMode', JSON.stringify(this.darkMode()));
     });
+    this.checkboxControl.setErrors({ 1: 'error' });
   }
 
   public onSearchQueryChanged(searchQuery: InstantSearchQuery) {
diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.html b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.html
index a0d251c9e393b6755b2705705da3e049a2271e55..91f5982d6a2e93f317b7a301d4177ec9c59482df 100644
--- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.html
+++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component.html
@@ -1,4 +1,4 @@
-<form [formGroup]="formService.form">
+<form [formGroup]="formService.form" class="max-w-[960px]">
   <h2 class="heading-2">Signatur</h2>
   <p id="signatur-desc">
     Diese Signatur wird bei allen Nachrichten an den Antragsteller angezeigt.
@@ -6,8 +6,9 @@
   <ods-textarea-editor
     [formControlName]="formServiceClass.SIGNATUR_FIELD"
     [isResizable]="false"
+    [showLabel]="false"
     data-test-id="signatur-text"
-    label=""
+    label="signature"
     rows="6"
     class="w-full"
     aria-describedby="signatur-desc"
diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.spec.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.spec.ts
index 0d8fd6b5eb2d724ff31293252d1b3d10a2c8937b..d787449be4be3621a443ff9cd4a9824613fbc167 100644
--- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.spec.ts
@@ -91,7 +91,7 @@ describe('PostfachService', () => {
       tick();
 
       expect(snackbarService.showInfo).toHaveBeenCalledWith(
-        'Die Signatur wird erfolgreich gespeichert.',
+        'Die Signatur wurde erfolgreich gespeichert.',
       );
     }));
   });
diff --git a/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.ts b/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.ts
index 2fc6ec706f41b554a0a9812034f45cb596edf9f8..1ff867073051235829114ca5cba89d9c227128ad 100644
--- a/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.ts
+++ b/alfa-client/libs/admin/settings/src/lib/postfach/postfach.service.ts
@@ -28,7 +28,7 @@ export class PostfachService {
 
   private showInfoAfterSave(stateResource: StateResource<PostfachResource>) {
     if (!stateResource.loading) {
-      this.snackbarService.showInfo('Die Signatur wird erfolgreich gespeichert.');
+      this.snackbarService.showInfo('Die Signatur wurde erfolgreich gespeichert.');
     }
   }
 
diff --git a/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.html b/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.html
index 9252326a5bdcc9d9c25ec164981bd0e24915bafa..f8858992626b2be8a4dc43e07f7947e3b0a84735 100644
--- a/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.html
+++ b/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.html
@@ -7,6 +7,7 @@
   [attr.data-test-id]="(label | convertForDataTest) + '-text-editor'"
   [required]="isRequired"
   [focus]="focus"
+  [showLabel]="showLabel"
 >
   <ods-validation-error
     error
diff --git a/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.ts
index c40849cf31e2279a3727527898213567bab07c4c..d6a19c8b70cac1f11b73038b321b1fc79fa2af58 100644
--- a/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.ts
+++ b/alfa-client/libs/design-component/src/lib/form/text-editor/text-editor.component.ts
@@ -24,6 +24,7 @@ export class TextEditorComponent extends FormControlEditorAbstractComponent {
   @Input() placeholder: string = '';
   @Input() isRequired: boolean = false;
   @Input() focus: boolean = false;
+  @Input() showLabel: boolean = true;
 
   get variant(): string {
     return this.invalidParams.length > 0 ? 'error' : 'default';
diff --git a/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.html b/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.html
index baa159622243b8c03783314ee0f27e17cf6c78a4..22a5c192844d111ff69b4ed90f1be4b7108fcee8 100644
--- a/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.html
+++ b/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.html
@@ -8,6 +8,7 @@
   [required]="isRequired"
   [focus]="focus"
   [isResizable]="isResizable"
+  [showLabel]="showLabel"
 >
   <ods-validation-error
     error
diff --git a/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.ts
index 5dea452149b2facd76f03b209835786e7af4b970..ef615ae42c6b31689a63ce85d22613537190588e 100644
--- a/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.ts
+++ b/alfa-client/libs/design-component/src/lib/form/textarea-editor/textarea-editor.component.ts
@@ -25,6 +25,7 @@ export class TextareaEditorComponent extends FormControlEditorAbstractComponent
   @Input() isRequired: boolean = false;
   @Input() focus: boolean = false;
   @Input() isResizable: boolean = true;
+  @Input() showLabel: boolean = true;
 
   get variant(): string {
     return this.invalidParams.length > 0 ? 'error' : 'default';
diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts
index 8adc00f2d8215c5f947d879874ed17e6f190184a..117e400441f35a9a21750521457c1c7537a808d0 100644
--- a/alfa-client/libs/design-system/src/index.ts
+++ b/alfa-client/libs/design-system/src/index.ts
@@ -5,6 +5,8 @@ export * from './lib/bescheid-status-text/bescheid-status-text.component';
 export * from './lib/bescheid-wrapper/bescheid-wrapper.component';
 export * from './lib/button-card/button-card.component';
 export * from './lib/button/button.component';
+export * from './lib/checkbox/checkbox.component';
+export * from './lib/fieldset/fieldset.component';
 export * from './lib/form/error-message/error-message.component';
 export * from './lib/form/file-upload-button/file-upload-button.component';
 export * from './lib/form/radio-button-card/radio-button-card.component';
diff --git a/alfa-client/libs/design-system/src/lib/checkbox/checbox.stories.ts b/alfa-client/libs/design-system/src/lib/checkbox/checbox.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2b3954527bc86c75615e36839194754fce3466ef
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/checkbox/checbox.stories.ts
@@ -0,0 +1,67 @@
+import { FormControl } from '@angular/forms';
+import { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
+import { CheckboxComponent } from './checkbox.component';
+
+const formControlWithError = new FormControl(false);
+formControlWithError.setErrors({ error: 404 });
+
+const meta: Meta<CheckboxComponent> = {
+  title: 'Checkbox',
+  component: CheckboxComponent,
+  decorators: [
+    moduleMetadata({
+      imports: [CheckboxComponent],
+    }),
+  ],
+  excludeStories: /.*Data$/,
+  tags: ['autodocs'],
+};
+
+export default meta;
+type Story = StoryObj<CheckboxComponent>;
+
+export const Default: Story = {
+  args: {
+    value: 'Checkbox value',
+    label: 'Basic checkbox',
+    inputId: '1',
+    disabled: false,
+  },
+  argTypes: {
+    label: { description: 'Checkbox label' },
+    disabled: { description: 'Disabled state of checkbox' },
+    inputId: { description: 'Id of checkbox input' },
+    value: { description: 'Value of checkbox' },
+    fieldControl: {
+      description: 'Form control object',
+      table: { type: { summary: 'FormControl' } },
+    },
+  },
+};
+
+export const Error: Story = {
+  args: {
+    label: 'Checkbox with error state',
+    inputId: '2',
+    fieldControl: formControlWithError,
+  },
+};
+
+export const Disabled: Story = {
+  args: {
+    label: 'Disabled checkbox',
+    inputId: '3',
+    disabled: true,
+  },
+};
+
+export const MultiLineLabel: Story = {
+  args: {
+    label: 'Very long label that should break',
+    inputId: '4',
+  },
+  render: (args) => ({
+    props: args,
+    template: `<div class="w-40"><ods-checkbox ${argsToTemplate(args)}/></div>`,
+  }),
+};
diff --git a/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.spec.ts b/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c25c5efdcce199e3c83dfd6adfceed567f2ea5d3
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.spec.ts
@@ -0,0 +1,45 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormControl } from '@angular/forms';
+import { CheckboxComponent } from './checkbox.component';
+
+describe('CheckboxComponent', () => {
+  let component: CheckboxComponent;
+  let fixture: ComponentFixture<CheckboxComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [CheckboxComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(CheckboxComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('hasError', () => {
+      it('should return true', () => {
+        const formControlWithError = new FormControl(false);
+        formControlWithError.setErrors({ 1: 'error' });
+        component.fieldControl = formControlWithError;
+
+        const result: boolean = component.hasError();
+
+        expect(result).toBe(true);
+      });
+
+      it('should return false', () => {
+        const formControl = new FormControl(false);
+        component.fieldControl = formControl;
+
+        const result: boolean = component.hasError();
+
+        expect(result).toBe(false);
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.ts b/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8a6ebfc41ac9fa2903387a0474510f080a3ec306
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/checkbox/checkbox.component.ts
@@ -0,0 +1,52 @@
+import { isNotEmpty } from '@alfa-client/tech-shared';
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+import { FormControl, ReactiveFormsModule } from '@angular/forms';
+
+@Component({
+  selector: 'ods-checkbox',
+  standalone: true,
+  imports: [CommonModule, ReactiveFormsModule],
+  template: `
+    <div class="flex items-start gap-3 text-start">
+      <input
+        type="checkbox"
+        class="peer relative box-border size-5 shrink-0 appearance-none rounded-sm border bg-whitetext
+        outline outline-2 outline-offset-2 outline-transparent hover:border-2 focus-visible:border-background-200
+        disabled:border-disabled-dark disabled:bg-disabled disabled:hover:border"
+        [ngClass]="
+          hasError() ?
+            'border-error hover:border-error focus-visible:outline-error'
+          : 'border-primary hover:border-primary-hover focus-visible:outline-focus'
+        "
+        [value]="value"
+        [checked]="fieldControl.value"
+        [attr.id]="inputId"
+        [disabled]="disabled"
+      />
+      <label class="leading-5 text-text" [attr.for]="inputId">{{ label }}</label>
+      <svg
+        viewBox="0 0 12 9"
+        xmlns="http://www.w3.org/2000/svg"
+        class="pointer-events-none absolute hidden size-5 p-1 outline-none peer-checked:block"
+        [ngClass]="hasError() ? 'fill-error' : 'fill-primary focus-visible:fill-focus'"
+      >
+        <path
+          d="M3.81353 7.10067L0.968732 4.30201L0 5.24832L3.81353
+          9L12 0.946309L11.0381 0L3.81353 7.10067Z"
+        />
+      </svg>
+    </div>
+  `,
+})
+export class CheckboxComponent {
+  @Input() fieldControl: FormControl = new FormControl(false);
+  @Input() value: string;
+  @Input() inputId: string;
+  @Input() label: string;
+  @Input() disabled: boolean = false;
+
+  hasError(): boolean {
+    return isNotEmpty(this.fieldControl.errors);
+  }
+}
diff --git a/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.spec.ts b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3653c1ac3fe9086724750c67dd9a91cb071921f7
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.spec.ts
@@ -0,0 +1,42 @@
+import { existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { FieldsetComponent } from './fieldset.component';
+
+describe('FieldsetComponent', () => {
+  let component: FieldsetComponent;
+  let fixture: ComponentFixture<FieldsetComponent>;
+
+  const legend = getDataTestIdOf('fieldset-legend');
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [FieldsetComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(FieldsetComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('legend element', () => {
+      it('should show', () => {
+        component.legend = 'Test';
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, legend);
+      });
+      it('should hide', () => {
+        component.legend = '';
+        fixture.detectChanges();
+
+        notExistsAsHtmlElement(fixture, legend);
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.ts b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0f5d77a8ae8ab65ea97cfd1a9b1f84177ee92b2
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.component.ts
@@ -0,0 +1,18 @@
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'ods-fieldset',
+  standalone: true,
+  imports: [CommonModule],
+  template: `<fieldset class="flex flex-col gap-2" [name]="name">
+    <legend *ngIf="legend" class="mb-2 font-medium text-text" data-test-id="fieldset-legend">
+      {{ legend }}
+    </legend>
+    <ng-content />
+  </fieldset>`,
+})
+export class FieldsetComponent {
+  @Input() name: string;
+  @Input() legend: string;
+}
diff --git a/alfa-client/libs/design-system/src/lib/fieldset/fieldset.stories.ts b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..616372a4f5f22eba38b1b1995934f5d677c73e63
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/fieldset/fieldset.stories.ts
@@ -0,0 +1,36 @@
+import { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
+import { CheckboxComponent } from '../checkbox/checkbox.component';
+import { FieldsetComponent } from './fieldset.component';
+
+const meta: Meta<FieldsetComponent> = {
+  title: 'Fieldset',
+  component: FieldsetComponent,
+  decorators: [
+    moduleMetadata({
+      imports: [FieldsetComponent, CheckboxComponent],
+    }),
+  ],
+  excludeStories: /.*Data$/,
+  tags: ['autodocs'],
+};
+
+export default meta;
+type Story = StoryObj<FieldsetComponent>;
+
+export const Default: Story = {
+  args: {
+    name: 'checkboxGroup',
+    legend: 'A group of checkboxes',
+  },
+  argTypes: {
+    name: { description: 'The name associated with the group' },
+    legend: { description: 'Title for the fieldset' },
+  },
+  render: (args) => ({
+    props: args,
+    template: `<ods-fieldset ${argsToTemplate(args)}>
+      <ods-checkbox inputId="1" label="First checkbox" />
+      <ods-checkbox inputId="2" label="Second checkbox" />
+    </ods-fieldset>`,
+  }),
+};
diff --git a/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts b/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
index 5c418556063b84c751fd274fbd901f18cd3eb4a3..cc91e16b2345a9f1a578001c60b7b20655ed5598 100644
--- a/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
+++ b/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
@@ -31,7 +31,7 @@ type TextareaVariants = VariantProps<typeof textareaVariants>;
   imports: [CommonModule, ReactiveFormsModule, TechSharedModule],
   template: `
     <div class="mt-2">
-      <label [for]="id" class="text-md mb-2 block font-medium text-text">
+      <label *ngIf="showLabel" [for]="id" class="text-md mb-2 block font-medium text-text">
         {{ inputLabel }}<ng-container *ngIf="required"><i aria-hidden="true">*</i></ng-container>
       </label>
       <textarea
@@ -65,6 +65,7 @@ export class TextareaComponent {
   @Input() fieldControl: FormControl = new FormControl(EMPTY_STRING);
   @Input() required: boolean = false;
   @Input() isResizable: boolean = true;
+  @Input() showLabel: boolean = true;
 
   @Input() set focus(value: boolean) {
     if (value && this.textAreaElement) {
diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
index f33524b795e39fff7585c3829d8094659429afa2..71b3e7c98f8e23d30f056ef4ad65544794294196 100644
--- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
+++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
@@ -61,4 +61,12 @@ describe('NavItemComponent', () => {
       });
     });
   });
+
+  describe('template', () => {
+    describe('host element role attribute', () => {
+      it('should be "menuitem"', () => {
+        expect(fixture.nativeElement.getAttribute('role')).toBe('menuitem');
+      });
+    });
+  });
 });
diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
index d5f54907fe995fa082505d3449a236d89b6f4ecb..14acc1a1b2c6f3c6ca800bc30710d5a7adf48cdc 100644
--- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
+++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
@@ -1,5 +1,5 @@
 import { CommonModule } from '@angular/common';
-import { Component, Input } from '@angular/core';
+import { Component, HostBinding, Input } from '@angular/core';
 import { RouterLink, RouterLinkActive } from '@angular/router';
 
 @Component({
@@ -14,7 +14,6 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
       'border border-transparent hover:border-primary',
       'outline-2 outline-offset-4 outline-focus focus-visible:border-background-200',
     ]"
-    role="menuitem"
     [attr.data-test-id]="'link-to-' + to"
   >
     <ng-content select="[icon]" />
@@ -24,4 +23,6 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
 export class NavItemComponent {
   @Input({ required: true }) caption!: string;
   @Input() to: string;
+
+  @HostBinding('attr.role') role = 'menuitem';
 }
diff --git a/alfa-client/libs/design-system/src/lib/popup/popup/popup.component.ts b/alfa-client/libs/design-system/src/lib/popup/popup/popup.component.ts
index 171397997f1bccc57c87c4a59b014dbd2aa6ed6a..60adf093640b07510296fab35c0a6e4fbb3650e9 100644
--- a/alfa-client/libs/design-system/src/lib/popup/popup/popup.component.ts
+++ b/alfa-client/libs/design-system/src/lib/popup/popup/popup.component.ts
@@ -23,7 +23,7 @@ import { twMerge } from 'tailwind-merge';
       *ngIf="isPopupOpen"
       class="absolute max-h-120 min-w-44 max-w-80 animate-fadeIn overflow-y-auto rounded shadow-lg shadow-grayborder focus:outline-none"
       [ngClass]="alignTo === 'left' ? 'right-0' : 'left-0'"
-      role="dialog"
+      role="menu"
       aria-modal="true"
       tabIndex="-1"
       cdkTrapFocus
diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
index 10ac4b918b2c3e41d10f5a1a0e41036a3cfdfc03..49ba05caeaf723693a01b5dbb9be991b4196afec 100644
--- a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
+++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
@@ -9,6 +9,9 @@
   --color-error: 0 71% 49%;
   --color-focus: 212 64% 47%;
 
+  --color-disabled: 206 14% 95%;
+  --color-disabled-dark: 208 12% 65%;
+
   --color-background-secondary: 0 0% 98%;
   --color-mainbg: 0 0% 100%;
   --text: 0 0% 0%;
@@ -39,6 +42,9 @@
   --color-error: 0 99% 72%;
   --color-focus: 43 100% 48%;
 
+  --color-disabled: 206 14% 15%;
+  --color-disabled-dark: 208 12% 33%;
+
   --color-background-secondary: 0 0% 16%;
   --color-mainbg: 0 0% 14%;
   --text: 0 0% 100%;
diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
index cb8ed07e1d8c25e88620f6a60df143c9e7da8dfb..588bdac521f0d439cd3df6cd7d3ec1228156298a 100644
--- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
+++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
@@ -119,6 +119,10 @@ module.exports = {
         warning: 'hsl(var(--warning))',
         error: 'hsl(var(--color-error))',
         focus: 'hsl(var(--color-focus))',
+        disabled: {
+          dark: 'hsl(var(--color-disabled-dark) / <alpha-value>)',
+          DEFAULT: 'hsl(var(--color-disabled) / <alpha-value>)',
+        },
       },
       backgroundColor: {
         greybackdrop: 'rgb(229, 229, 229, 0.95)',
diff --git a/alfa-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.spec.ts b/alfa-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.spec.ts
index 40d4bc90cda99e87336563376dd405d63298d575..3f25e40be126c663b985d8591d829789743a0b99 100644
--- a/alfa-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.spec.ts
+++ b/alfa-client/libs/postfach/src/lib/postfach-mail-form/postfach-mail-form.component.spec.ts
@@ -21,12 +21,6 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
-import { MAT_DIALOG_DATA } from '@angular/material/dialog';
-import { MatFormFieldModule } from '@angular/material/form-field';
-import { MatInputModule } from '@angular/material/input';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { PostfachService } from '@alfa-client/postfach-shared';
 import { createStateResource } from '@alfa-client/tech-shared';
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
@@ -39,8 +33,14 @@ import {
   TextAreaEditorComponent,
   TextEditorComponent,
 } from '@alfa-client/ui';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
+import { MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { createCommandResource } from 'libs/command-shared/test/command';
-import { PostfachTestFactory } from 'libs/postfach-shared/test/postfach';
+import { PostfachTestFactory, createPostfachSettings } from 'libs/postfach-shared/test/postfach';
 import { MockComponent } from 'ng-mocks';
 import { of } from 'rxjs';
 import { PostfachMailFormComponent } from './postfach-mail-form.component';
@@ -54,7 +54,10 @@ describe('PostfachMailFormComponent', () => {
   let component: PostfachMailFormComponent;
   let fixture: ComponentFixture<PostfachMailFormComponent>;
 
-  const postfachService: Mock<PostfachService> = mock(PostfachService);
+  const postfachService: Mock<PostfachService> = {
+    ...mock(PostfachService),
+    getSettings: jest.fn().mockReturnValue(of(createPostfachSettings())),
+  };
   const formService: PostfachMailFormservice = new PostfachMailFormservice(
     new FormBuilder(),
     useFromMock(postfachService),
diff --git a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.html b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.html
index d07cea93308d33ecfb5af0d917ad1fdfd84629d6..ec5c2b1f2a356d87ce90983eb5206fe24245c0c4 100644
--- a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.html
+++ b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.html
@@ -31,6 +31,7 @@
   "
   [disabled]="isDisabled"
   [matTooltip]="toolTip"
+  [matMenuTriggerFor]="matMenuTriggerFor"
   (click)="clickEmitter.emit($event)"
   type="button"
 >
diff --git a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.spec.ts b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.spec.ts
index cc423f9a8086d18af5fdc13a0db41ab2fae861df..47b9ce82546885a666ae26c46fcff54a7acca36c 100644
--- a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.spec.ts
+++ b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.spec.ts
@@ -24,6 +24,7 @@
 import { createEmptyStateResource } from '@alfa-client/tech-shared';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatIcon } from '@angular/material/icon';
+import { MatMenuModule } from '@angular/material/menu';
 import { MatTooltipModule } from '@angular/material/tooltip';
 import { MockComponent, MockModule } from 'ng-mocks';
 import { SpinnerComponent } from '../spinner/spinner.component';
@@ -43,6 +44,7 @@ describe('IconButtonWithSpinnerComponent', () => {
         MatIcon,
         MockComponent(SpinnerComponent),
         MockModule(MatTooltipModule),
+        MockModule(MatMenuModule),
       ],
     });
   });
diff --git a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.ts b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.ts
index aac12cd1ba42b1995fc8c188498c08f5ab0c7211..aac1f896a23e916e76a4f59e07d6e9294d0f6dc5 100644
--- a/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.ts
+++ b/alfa-client/libs/ui/src/lib/ui/icon-button-with-spinner/icon-button-with-spinner.component.ts
@@ -21,8 +21,8 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { StateResource, createEmptyStateResource } from '@alfa-client/tech-shared';
 import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared';
 import { Resource } from '@ngxp/rest';
 import { isNil } from 'lodash-es';
 
@@ -34,6 +34,7 @@ import { isNil } from 'lodash-es';
 export class IconButtonWithSpinnerComponent {
   @Input() icon: string;
   @Input() svgIcon: string;
+  @Input() matMenuTriggerFor: string;
   @Input() stateResource: StateResource<Resource>;
   @Input() toolTip: string = '';
   @Input() showSpinner: boolean = false;
diff --git a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.html b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.html
index 5fa5cdf3ab2ef420c6aba8fdafb9fe6b64f8dd17..f455cb99443c2e6a9be7146de5e4ed7e15022704 100644
--- a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.html
+++ b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.html
@@ -28,7 +28,7 @@
   [matMenuTriggerFor]="menu.matMenu"
   (menuOpened)="showUserProfileSearch()"
   (menuClosed)="hideUserProfileSearch()"
-  aria-label="Bearbeiter ändern"
+  [attr.aria-label]="userButtonLabel"
   class="user-profile-button"
 >
   <alfa-user-icon
diff --git a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.spec.ts b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.spec.ts
index 4464f2f109503b0424b404266a04c7bd80bee70b..6c12e1395e939a926ad075df0c40159f9ae04cb4 100644
--- a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.spec.ts
+++ b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.spec.ts
@@ -21,10 +21,11 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { createEmptyStateResource, StateResource } from '@alfa-client/tech-shared';
 import { mock } from '@alfa-client/test-utils';
 import { OzgcloudMenuComponent, UiModule } from '@alfa-client/ui';
-import { UserProfileService } from '@alfa-client/user-profile-shared';
+import { UserProfileResource, UserProfileService } from '@alfa-client/user-profile-shared';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MockComponent } from 'ng-mocks';
 import { BehaviorSubject } from 'rxjs';
 import { UserIconComponent } from '../../../user-icon/user-icon.component';
@@ -114,4 +115,31 @@ describe('UserProfileButtonContainerComponent', () => {
       expect(userProfileService.hideUserProfileSearch).toHaveBeenCalled();
     });
   });
+
+  describe('getUserButtonLabel', () => {
+    it('should return label', () => {
+      component.userProfile = createEmptyStateResource();
+
+      const result = component.getUserButtonLabel();
+
+      expect(result).toBe('Bearbeiter ändern. Aktueller Bearbeiter: Unbekannter Benutzer');
+    });
+  });
+
+  describe('set userProfile', () => {
+    const userProfileStateResource: StateResource<UserProfileResource> = createEmptyStateResource();
+    it('should set userProfile', () => {
+      component.userProfile = userProfileStateResource;
+
+      expect(component.userProfile).toBe(userProfileStateResource);
+    });
+
+    it('should get label for user button', () => {
+      component.getUserButtonLabel = jest.fn();
+
+      component.userProfile = userProfileStateResource;
+
+      expect(component.getUserButtonLabel).toHaveBeenCalled();
+    });
+  });
 });
diff --git a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.ts b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.ts
index 1c7451882382e8bdd72e1b6a66b44c48a3b1dc01..e559f74639d522733a7506a840c689091f6460fe 100644
--- a/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.ts
+++ b/alfa-client/libs/user-profile/src/lib/user-profile-in-vorgang-container/user-profile-in-vorgang/user-profile-button-container/user-profile-button-container.component.ts
@@ -21,10 +21,14 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { StateResource } from '@alfa-client/tech-shared';
+import {
+  getUserName,
+  UserProfileResource,
+  UserProfileService,
+} from '@alfa-client/user-profile-shared';
 import { Component, Input, OnInit, ViewChild } from '@angular/core';
 import { MatMenuTrigger } from '@angular/material/menu';
-import { StateResource } from '@alfa-client/tech-shared';
-import { UserProfileResource, UserProfileService } from '@alfa-client/user-profile-shared';
 import { Observable, tap } from 'rxjs';
 
 @Component({
@@ -33,11 +37,21 @@ import { Observable, tap } from 'rxjs';
   styleUrls: ['./user-profile-button-container.component.scss'],
 })
 export class UserProfileButtonContainerComponent implements OnInit {
-  @Input() userProfile: StateResource<UserProfileResource>;
+  @Input()
+  set userProfile(value: StateResource<UserProfileResource>) {
+    this._userProfile = value;
+    this.userButtonLabel = this.getUserButtonLabel();
+  }
+
+  get userProfile() {
+    return this._userProfile;
+  }
 
   @ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger;
 
   showUserProfileSearch$: Observable<boolean>;
+  private _userProfile: StateResource<UserProfileResource>;
+  userButtonLabel: string;
 
   constructor(public userProfileService: UserProfileService) {}
 
@@ -64,4 +78,8 @@ export class UserProfileButtonContainerComponent implements OnInit {
   public hideUserProfileSearch(): void {
     this.userProfileService.hideUserProfileSearch();
   }
+
+  public getUserButtonLabel(): string {
+    return `Bearbeiter ändern. Aktueller Bearbeiter: ${getUserName(this.userProfile.resource)}`;
+  }
 }
diff --git a/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.html b/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.html
index b5c75e65e763c68cd0300190f8c1ff422738c3fc..b13bac6befba485ab93860d409d3f1b79492ebec 100644
--- a/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.html
+++ b/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.html
@@ -27,4 +27,5 @@
   icon="settings"
   toolTip="Einstellungen"
   data-test-id="menu-button"
+  [matMenuTriggerFor]="matMenuTriggerFor"
 ></ozgcloud-icon-button-with-spinner>
diff --git a/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.ts b/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.ts
index 5151de3ca312af3db73cc04385d649a4d3c7ee92..e952c3b73d18d4ee756c56cabfc23f2a3d2cb5d5 100644
--- a/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.ts
+++ b/alfa-client/libs/user-settings/src/lib/user-settings-container/user-settings/user-settings-menu-button/user-settings-menu-button.component.ts
@@ -21,11 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
 
 @Component({
   selector: 'alfa-user-settings-menu-button',
   templateUrl: './user-settings-menu-button.component.html',
   styleUrls: ['./user-settings-menu-button.component.scss'],
 })
-export class UserSettingsMenuButtonComponent {}
+export class UserSettingsMenuButtonComponent {
+  @Input() matMenuTriggerFor: string;
+}
diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.spec.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.spec.ts
index 4c85845d2178b7a2faadd81cc18a0ee8371f092a..31b6f8e0de9bc3cfa18c45e1ad5860f747589982 100644
--- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.spec.ts
+++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.spec.ts
@@ -21,9 +21,9 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { EnumToLabelPipe } from '@alfa-client/tech-shared';
 import { VorgangResource, VorgangStatusLabel } from '@alfa-client/vorgang-shared';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
 import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang';
 import { VorgangStatusTextComponent } from './vorgang-status-text.component';
@@ -51,7 +51,7 @@ describe('VorgangStatusTextComponent', () => {
     expect(component).toBeTruthy();
   });
 
-  it('should show status dot', () => {
+  it('should show status text', () => {
     component.status = vorgang.status;
     const statusText: string = VorgangStatusLabel[vorgang.status];
 
diff --git a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.ts b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.ts
index 4a46a08223176794182bf46222f0f8fe829de4fb..a1c90fd8afdb3114a17086f359b36ee5110a4f42 100644
--- a/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.ts
+++ b/alfa-client/libs/vorgang-shared-ui/src/lib/vorgang-status-text/vorgang-status-text.component.ts
@@ -21,8 +21,8 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { Component, Input } from '@angular/core';
 import { VorgangStatus, VorgangStatusLabel } from '@alfa-client/vorgang-shared';
+import { Component, Input } from '@angular/core';
 
 @Component({
   selector: 'alfa-vorgang-status-text',
diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts b/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts
index 13b574ef5c2fcdc6d993803208437cb01bb5ce3c..6015354498a4860c7c4bfabd7feb57ce2f9c7a93 100644
--- a/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts
+++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.spec.ts
@@ -21,12 +21,24 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { convertForDataTest, ConvertForDataTestPipe, EnumToLabelPipe, HasLinkPipe, ToResourceUriPipe } from '@alfa-client/tech-shared';
-import { getElementFromFixture } from '@alfa-client/test-utils';
+import {
+  ConvertForDataTestPipe,
+  createStateResource,
+  EnumToLabelPipe,
+  HasLinkPipe,
+  ToResourceUriPipe,
+} from '@alfa-client/tech-shared';
+import { getElementFromFixture, mock } from '@alfa-client/test-utils';
 import { PostfachIconComponent } from '@alfa-client/ui';
 import { UserProfileInVorgangListItemContainerComponent } from '@alfa-client/user-profile';
-import { VorgangHeaderLinkRel } from '@alfa-client/vorgang-shared';
-import { AktenzeichenComponent, VorgangNummerComponent, VorgangStatusDotComponent, VorgangStatusTextComponent } from '@alfa-client/vorgang-shared-ui';
+import { UserProfileResource, UserProfileService } from '@alfa-client/user-profile-shared';
+import { VorgangHeaderLinkRel, VorgangStatus } from '@alfa-client/vorgang-shared';
+import {
+  AktenzeichenComponent,
+  VorgangNummerComponent,
+  VorgangStatusDotComponent,
+  VorgangStatusTextComponent,
+} from '@alfa-client/vorgang-shared-ui';
 import { WiedervorlageListInVorgangListContainerComponent } from '@alfa-client/wiedervorlage';
 import { registerLocaleData } from '@angular/common';
 import localeDe from '@angular/common/locales/de';
@@ -39,8 +51,10 @@ import { MatIconTestingModule } from '@angular/material/icon/testing';
 import { MatTooltipModule } from '@angular/material/tooltip';
 import { RouterTestingModule } from '@angular/router/testing';
 import { getDataTestClassOf, getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
 import { createVorgangResource } from 'libs/vorgang-shared/test/vorgang';
 import { MockComponent, MockModule } from 'ng-mocks';
+import { of } from 'rxjs';
 import { VorgangBescheidStatusComponent } from './vorgang-bescheid-status/vorgang-bescheid-status.component';
 import { VorgangCreatedAtComponent } from './vorgang-created-at/vorgang-created-at.component';
 import { VorgangListItemComponent } from './vorgang-list-item.component';
@@ -52,10 +66,14 @@ describe('VorgangListItemComponent', () => {
   let component: VorgangListItemComponent;
   let fixture: ComponentFixture<VorgangListItemComponent>;
 
+  const userProfileService = mock(UserProfileService);
+
   const user: string = getDataTestIdOf('vorgang-user-icon');
   const postfachStatus: string = getDataTestClassOf('postfach-icon');
   const bescheidStatus: string = getDataTestIdOf('vorgang-list-item-bescheid-status');
 
+  const userProfile: UserProfileResource = createUserProfileResource();
+
   beforeEach(async () => {
     await TestBed.configureTestingModule({
       imports: [RouterTestingModule, MatIconTestingModule],
@@ -79,6 +97,7 @@ describe('VorgangListItemComponent', () => {
         MockModule(MatTooltipModule),
       ],
       providers: [
+        { provide: UserProfileService, useValue: userProfileService },
         { provide: LOCALE_ID, useValue: 'de' },
         { provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
       ],
@@ -96,6 +115,52 @@ describe('VorgangListItemComponent', () => {
     expect(component).toBeTruthy();
   });
 
+  describe('ngOnInit', () => {
+    describe('user profile', () => {
+      beforeEach(() => {
+        component.buildAriaLabel = jest.fn();
+        component.userProfileService.getAssignedUserProfile = jest
+          .fn()
+          .mockReturnValue(of(createStateResource(userProfile)));
+      });
+
+      describe('vorgang has no "assigned to" link', () => {
+        beforeEach(() => {
+          component.vorgang = createVorgangResource();
+        });
+        it('should not get profile', () => {
+          component.ngOnInit();
+
+          expect(component.userProfileService.getAssignedUserProfile).not.toHaveBeenCalled();
+        });
+
+        it('should build aria label without user profile resource', () => {
+          component.ngOnInit();
+
+          expect(component.buildAriaLabel).toHaveBeenCalledWith();
+        });
+      });
+
+      describe('vorgang has "assigned to" link', () => {
+        beforeEach(() => {
+          component.vorgang = createVorgangResource([VorgangHeaderLinkRel.ASSIGNED_TO]);
+        });
+
+        it('should get profile', () => {
+          component.ngOnInit();
+
+          expect(component.userProfileService.getAssignedUserProfile).toHaveBeenCalled();
+        });
+
+        it('should build aria label with user profile resource', () => {
+          component.ngOnInit();
+
+          expect(component.buildAriaLabel).toHaveBeenCalledWith(userProfile);
+        });
+      });
+    });
+  });
+
   describe('bearbeiter/user-icon', () => {
     it('should be visible', () => {
       component.vorgang = createVorgangResource([
@@ -119,142 +184,218 @@ describe('VorgangListItemComponent', () => {
     });
   });
 
-  describe('Aria label', () => {
-    it('should contain Wiedervorlage', () => {
+  describe('mail icon', () => {
+    beforeEach(() => {
       component.vorgang = createVorgangResource([
         VorgangHeaderLinkRel.VORGANG_WITH_EINGANG,
-        VorgangHeaderLinkRel.WIEDERVORLAGEN,
+        VorgangHeaderLinkRel.POSTFACH_MAILS,
       ]);
-      const listItem: string = getDataTestIdOf(
-        `vorgang-list-item-${convertForDataTest(component.vorgang.name)}`,
-      );
-      component.ngOnInit();
+    });
+
+    it('should show mail icon if Vorgang has new Postfachnachricht', () => {
+      component.vorgang.hasPostfachNachricht = true;
       fixture.detectChanges();
 
-      const element: HTMLDivElement = fixture.nativeElement.querySelector(listItem);
-      const ariaLabel: string = element.getAttribute('aria-label');
+      const statusElement = getElementFromFixture(fixture, postfachStatus);
 
-      expect(ariaLabel).toContain('Wiedervorlage');
+      expect(statusElement).toBeInstanceOf(HTMLElement);
     });
 
-    it('should not contain Wiedervorlage if no nextFrist but LinkRel.WIEDERVORLAGEN', () => {
-      component.vorgang = {
-        ...createVorgangResource([
-          VorgangHeaderLinkRel.VORGANG_WITH_EINGANG,
-          VorgangHeaderLinkRel.WIEDERVORLAGEN,
-        ]),
-        nextFrist: null,
-      };
-      const listItem: string = getDataTestIdOf(
-        `vorgang-list-item-${convertForDataTest(component.vorgang.name)}`,
-      );
-      component.ngOnInit();
+    it('should not show mail icon if Vorgang has no new Postfachnachricht', () => {
+      component.vorgang.hasPostfachNachricht = false;
       fixture.detectChanges();
 
-      const element: HTMLDivElement = fixture.nativeElement.querySelector(listItem);
-      const ariaLabel: string = element.getAttribute('aria-label');
+      const statusElement = getElementFromFixture(fixture, postfachStatus);
 
-      expect(ariaLabel).not.toContain('Wiedervorlage');
+      expect(statusElement).not.toBeInstanceOf(HTMLElement);
     });
+  });
 
-    it('should not contain Wiedervorlage if no LinkRel.WIEDERVORLAGEN', () => {
-      component.vorgang = createVorgangResource([VorgangHeaderLinkRel.VORGANG_WITH_EINGANG]);
-      const listItem: string = getDataTestIdOf(
-        `vorgang-list-item-${convertForDataTest(component.vorgang.name)}`,
-      );
-      component.ngOnInit();
+  describe('Bescheid-Status', () => {
+    it('should show bescheid status if Vorgang has antragBewilligt true', () => {
+      component.vorgang.antragBewilligt = true;
       fixture.detectChanges();
 
-      const element: HTMLDivElement = fixture.nativeElement.querySelector(listItem);
-      const ariaLabel: string = element.getAttribute('aria-label');
+      const element = getElementFromFixture(fixture, bescheidStatus);
 
-      expect(ariaLabel).not.toContain('Wiedervorlage');
+      expect(element).toBeInstanceOf(HTMLElement);
     });
 
-    it('should contain hasPostfachnachricht text if vorgang has Postfachnachricht', () => {
-      component.vorgang.hasPostfachNachricht = true;
-      component.vorgang.hasNewPostfachNachricht = false;
-      const listItem: string = getDataTestIdOf(
-        `vorgang-list-item-${convertForDataTest(component.vorgang.name)}`,
-      );
-      component.ngOnInit();
+    it('should show bescheid status if Vorgang has antragBewilligt false', () => {
+      component.vorgang.antragBewilligt = false;
       fixture.detectChanges();
 
-      const element: HTMLDivElement = fixture.nativeElement.querySelector(listItem);
-      const ariaLabel: string = element.getAttribute('aria-label');
+      const element = getElementFromFixture(fixture, bescheidStatus);
 
-      expect(ariaLabel).toContain('enthält Postfachnachrichten');
+      expect(element).toBeInstanceOf(HTMLElement);
     });
 
-    it('should contain hasNewPostfachnachricht text if vorgang has new Postfachnachricht', () => {
-      component.vorgang.hasPostfachNachricht = true;
-      component.vorgang.hasNewPostfachNachricht = true;
-      const listItem: string = getDataTestIdOf(
-        `vorgang-list-item-${convertForDataTest(component.vorgang.name)}`,
-      );
-      component.ngOnInit();
+    it('should not show bescheid status if Vorgang has no antragBewilligt', () => {
+      component.vorgang.antragBewilligt = null;
       fixture.detectChanges();
 
-      const element: HTMLDivElement = fixture.nativeElement.querySelector(listItem);
-      const ariaLabel: string = element.getAttribute('aria-label');
+      const element = getElementFromFixture(fixture, bescheidStatus);
 
-      expect(ariaLabel).toContain('enthält neue Postfachnachrichten');
+      expect(element).not.toBeInstanceOf(HTMLElement);
     });
   });
 
-  describe('mail icon', () => {
+  describe('buildAriaLabel', () => {
     beforeEach(() => {
+      component.getWiedervorlageText = jest.fn();
+      component.getPostfachNachricht = jest.fn();
+    });
+    it('should get status', () => {
+      component.getStatus = jest.fn();
+
+      component.buildAriaLabel();
+
+      expect(component.getStatus).toHaveBeenCalled();
+    });
+
+    it('should get approval text', () => {
+      component.getApprovalText = jest.fn();
+
+      component.buildAriaLabel();
+
+      expect(component.getApprovalText).toHaveBeenCalled();
+    });
+
+    it('should get user text', () => {
+      component.getUserText = jest.fn();
+
+      component.buildAriaLabel(userProfile);
+
+      expect(component.getUserText).toHaveBeenCalledWith(userProfile);
+    });
+
+    it('should get Wiedervorlage', () => {
       component.vorgang = createVorgangResource([
         VorgangHeaderLinkRel.VORGANG_WITH_EINGANG,
-        VorgangHeaderLinkRel.POSTFACH_MAILS,
+        VorgangHeaderLinkRel.WIEDERVORLAGEN,
       ]);
+
+      component.buildAriaLabel();
+
+      expect(component.getWiedervorlageText).toHaveBeenCalled();
     });
 
-    it('should show mail icon if Vorgang has new Postfachnachricht', () => {
+    it('should not get Wiedervorlage if no nextFrist but LinkRel.WIEDERVORLAGEN', () => {
+      component.vorgang = {
+        ...createVorgangResource([
+          VorgangHeaderLinkRel.VORGANG_WITH_EINGANG,
+          VorgangHeaderLinkRel.WIEDERVORLAGEN,
+        ]),
+        nextFrist: null,
+      };
+
+      component.buildAriaLabel();
+
+      expect(component.getWiedervorlageText).not.toHaveBeenCalled();
+    });
+
+    it('should not get Wiedervorlage if no LinkRel.WIEDERVORLAGEN', () => {
+      component.vorgang = createVorgangResource([VorgangHeaderLinkRel.VORGANG_WITH_EINGANG]);
+
+      component.buildAriaLabel();
+
+      expect(component.getWiedervorlageText).not.toHaveBeenCalled();
+    });
+
+    it('should get message text if vorgang has message', () => {
       component.vorgang.hasPostfachNachricht = true;
-      fixture.detectChanges();
 
-      const statusElement = getElementFromFixture(fixture, postfachStatus);
+      component.buildAriaLabel();
 
-      expect(statusElement).toBeInstanceOf(HTMLElement);
+      expect(component.getPostfachNachricht).toHaveBeenCalled();
     });
 
-    it('should not show mail icon if Vorgang has no new Postfachnachricht', () => {
+    it('should not get message text if vorgang has no messages', () => {
       component.vorgang.hasPostfachNachricht = false;
-      fixture.detectChanges();
 
-      const statusElement = getElementFromFixture(fixture, postfachStatus);
+      component.buildAriaLabel();
 
-      expect(statusElement).not.toBeInstanceOf(HTMLElement);
+      expect(component.getPostfachNachricht).not.toHaveBeenCalled();
     });
   });
 
-  describe('Bescheid-Status', () => {
-    it('should show bescheid status if Vorgang has antragBewilligt true', () => {
+  describe('getWiedervorlageText', () => {
+    it('should return text for next resubmission', () => {
+      component.vorgang.nextFrist = new Date('07.02.1977');
+
+      const result: string = component.getWiedervorlageText();
+
+      expect(result).toBe(', Nächste Wiedervorlage am 02.07.1977');
+    });
+  });
+
+  describe('getPostfachNachricht', () => {
+    it('should return "contains new messages"', () => {
+      component.vorgang.hasNewPostfachNachricht = true;
+
+      const result: string = component.getPostfachNachricht();
+
+      expect(result).toBe(', enthält neue Postfachnachrichten');
+    });
+
+    it('should return "contains messages"', () => {
+      component.vorgang.hasNewPostfachNachricht = false;
+
+      const result: string = component.getPostfachNachricht();
+
+      expect(result).toBe(', enthält Postfachnachrichten');
+    });
+  });
+
+  describe('getStatus', () => {
+    it('should return status', () => {
+      component.vorgang.status = VorgangStatus.NEU;
+
+      const result: string = component.getStatus();
+
+      expect(result).toBe('Neu');
+    });
+  });
+
+  describe('getApprovalText', () => {
+    it('should return empty string', () => {
+      component.vorgang.antragBewilligt = undefined;
+
+      const result: string = component.getApprovalText();
+
+      expect(result).toBe('');
+    });
+
+    it('should return "approved" text', () => {
       component.vorgang.antragBewilligt = true;
-      fixture.detectChanges();
 
-      const element = getElementFromFixture(fixture, bescheidStatus);
+      const result: string = component.getApprovalText();
 
-      expect(element).toBeInstanceOf(HTMLElement);
+      expect(result).toBe('bewilligt');
     });
 
-    it('should show bescheid status if Vorgang has antragBewilligt false', () => {
+    it('should return "not approved" text', () => {
       component.vorgang.antragBewilligt = false;
-      fixture.detectChanges();
 
-      const element = getElementFromFixture(fixture, bescheidStatus);
+      const result: string = component.getApprovalText();
 
-      expect(element).toBeInstanceOf(HTMLElement);
+      expect(result).toBe('abgelehnt');
     });
+  });
 
-    it('should not show bescheid status if Vorgang has no antragBewilligt', () => {
-      component.vorgang.antragBewilligt = null;
-      fixture.detectChanges();
+  describe('getUserText', () => {
+    it('should return no assigned user text', () => {
+      const result: string = component.getUserText(undefined);
 
-      const element = getElementFromFixture(fixture, bescheidStatus);
+      expect(result).toBe('Kein Bearbeiter zugewiesen');
+    });
 
-      expect(element).not.toBeInstanceOf(HTMLElement);
+    it('should return assigned user text', () => {
+      const result: string = component.getUserText(userProfile);
+
+      expect(result).toBe(
+        `Aktuell zugewiesener Nutzer: ${userProfile.firstName} ${userProfile.lastName}`,
+      );
     });
   });
 });
diff --git a/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.ts b/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.ts
index bdf00833cb720c671cf9bc6ec4b6a0026ea64e1d..b8cbab9cabd6479cc85550faf03fd35dc9550a9c 100644
--- a/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.ts
+++ b/alfa-client/libs/vorgang/src/lib/vorgang-list-container/vorgang-list/vorgang-list-item/vorgang-list-item.component.ts
@@ -21,11 +21,28 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { formatToPrettyDate } from '@alfa-client/tech-shared';
-import { VorgangHeaderLinkRel, VorgangResource } from '@alfa-client/vorgang-shared';
+import {
+  EnumToLabelPipe,
+  formatFullDateWithTimeWithoutSeconds,
+  formatToPrettyDate,
+  isNotNull,
+  StateResource,
+} from '@alfa-client/tech-shared';
+import {
+  getUserName,
+  UserProfileResource,
+  UserProfileService,
+} from '@alfa-client/user-profile-shared';
+import {
+  VorgangHeaderLinkRel,
+  VorgangResource,
+  VorgangStatusLabel,
+} from '@alfa-client/vorgang-shared';
 import { getAktenzeichenText } from '@alfa-client/vorgang-shared-ui';
 import { Component, Input, OnInit } from '@angular/core';
 import { hasLink } from '@ngxp/rest';
+import { isNil } from 'lodash-es';
+import { first } from 'rxjs';
 
 @Component({
   selector: 'alfa-vorgang-list-item',
@@ -38,18 +55,33 @@ export class VorgangListItemComponent implements OnInit {
 
   public ariaLabel: string = '';
 
+  constructor(public userProfileService: UserProfileService) {}
+
   ngOnInit(): void {
-    this.buildAriaLabel();
+    if (hasLink(this.vorgang, VorgangHeaderLinkRel.ASSIGNED_TO)) {
+      this.userProfileService
+        .getAssignedUserProfile(this.vorgang, VorgangHeaderLinkRel.ASSIGNED_TO)
+        .pipe(
+          first((userProfile: StateResource<UserProfileResource>) =>
+            isNotNull(userProfile.resource),
+          ),
+        )
+        .subscribe((userProfileStateResource: StateResource<UserProfileResource>) => {
+          this.buildAriaLabel(userProfileStateResource.resource);
+        });
+    } else this.buildAriaLabel();
   }
 
-  buildAriaLabel() {
+  buildAriaLabel(userProfileResource: UserProfileResource = undefined) {
     const name: string = this.vorgang.name;
     const aktenzeichen: string = getAktenzeichenText(this.vorgang);
     const nummer: string = this.vorgang.nummer;
-    const status: string = this.vorgang.status;
-    const createdAt: string = formatToPrettyDate(this.vorgang.createdAt);
+    const status: string = this.getStatus();
+    const approvalStatus: string = this.getApprovalText();
+    const createdAt: string = formatFullDateWithTimeWithoutSeconds(this.vorgang.createdAt);
+    const userText: string = this.getUserText(userProfileResource);
 
-    this.ariaLabel = `Vorgang: ${name}, Aktenzeichen: ${aktenzeichen}, Nummer: ${nummer} Status: ${status}, Eingang: ${createdAt}`;
+    this.ariaLabel = `Vorgang: ${name}, Aktenzeichen: ${aktenzeichen}, Nummer: ${nummer} Status: ${status} ${approvalStatus}, Eingang: ${createdAt}, ${userText}`;
 
     if (
       hasLink(this.vorgang, VorgangHeaderLinkRel.WIEDERVORLAGEN) &&
@@ -68,11 +100,28 @@ export class VorgangListItemComponent implements OnInit {
     return `, Nächste Wiedervorlage am ${nextFrist}`;
   }
 
-  getPostfachNachricht() {
+  getPostfachNachricht(): string {
     if (this.vorgang.hasNewPostfachNachricht) {
       return ', enthält neue Postfachnachrichten';
     }
 
     return ', enthält Postfachnachrichten';
   }
+
+  getStatus(): string {
+    const enumToLabel = new EnumToLabelPipe();
+    return enumToLabel.transform(this.vorgang.status, VorgangStatusLabel);
+  }
+
+  getApprovalText(): string {
+    if (isNil(this.vorgang.antragBewilligt)) return '';
+
+    return this.vorgang.antragBewilligt ? 'bewilligt' : 'abgelehnt';
+  }
+
+  getUserText(userProfileResource: UserProfileResource): string {
+    return userProfileResource ?
+        `Aktuell zugewiesener Nutzer: ${getUserName(userProfileResource)}`
+      : 'Kein Bearbeiter zugewiesen';
+  }
 }
diff --git a/alfa-client/package-lock.json b/alfa-client/package-lock.json
index b551b3e5a341ab04c060b67cf3b84a262f0e74d4..50747ff0743d33211bbf4255b761c6b5f013f61d 100644
--- a/alfa-client/package-lock.json
+++ b/alfa-client/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "alfa",
-  "version": "1.0.0-SNAPSHOT",
+  "version": "1.1.0-SNAPSHOT",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "alfa",
-      "version": "1.0.0-SNAPSHOT",
+      "version": "1.1.0-SNAPSHOT",
       "license": "MIT",
       "dependencies": {
         "@angular/animations": "17.3.10",
diff --git a/alfa-client/package.json b/alfa-client/package.json
index e1523dd25e7b7786a77adf6d0fe52760d69516fe..4c807787822c57a9f17c83def17fd5bc69a31235 100644
--- a/alfa-client/package.json
+++ b/alfa-client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "alfa",
-  "version": "1.0.0-SNAPSHOT",
+  "version": "1.1.0-SNAPSHOT",
   "license": "MIT",
   "scripts": {
     "start": "nx run alfa:serve --port 4300 --disable-host-check",
diff --git a/alfa-client/pom.xml b/alfa-client/pom.xml
index 576dd79ddd4c0ab6fb8adbf86fcb0e631b3aab55..8e8395494a1b55f9399a9d7c997e6697e19ebb14 100644
--- a/alfa-client/pom.xml
+++ b/alfa-client/pom.xml
@@ -29,7 +29,7 @@
 	<parent>
 		<groupId>de.ozgcloud.alfa</groupId>
 		<artifactId>alfa</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.14.0-SNAPSHOT</version>
 	</parent>
 
     <modelVersion>4.0.0</modelVersion>
diff --git a/alfa-server/pom.xml b/alfa-server/pom.xml
index 8310c3d2875b5bd9052d1a8704a958ecb3957786..2e9313095672888c2e1a95fedb74f716eb0dd417 100644
--- a/alfa-server/pom.xml
+++ b/alfa-server/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>de.ozgcloud.alfa</groupId>
 		<artifactId>alfa</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.14.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>alfa-server</artifactId>
@@ -131,4 +131,4 @@
 		</plugins>
 	</build>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/alfa-service/pom.xml b/alfa-service/pom.xml
index 86daeeea0530386f5a9b708e593c5b46362e622d..e7ae7b5424b45b6d10d3e854e64ad139859a03ef 100644
--- a/alfa-service/pom.xml
+++ b/alfa-service/pom.xml
@@ -24,16 +24,14 @@
     unter der Lizenz sind dem Lizenztext zu entnehmen.
 
 -->
-<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">
+<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>de.ozgcloud.alfa</groupId>
 		<artifactId>alfa</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.14.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>alfa-service</artifactId>
@@ -239,4 +237,4 @@
 		</plugins>
 	</build>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a5d37676d95578418ebba3385ddb8f5f7287e99
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResource.java
@@ -0,0 +1,8 @@
+package de.ozgcloud.alfa.resource;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown=true)
+public class OzgcloudResource {
+
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0ccfcd416ac66767589bc373197b2238d4e99c5
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java
@@ -0,0 +1,47 @@
+package de.ozgcloud.alfa.resource;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.RepresentationModel;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import jakarta.validation.constraints.NotBlank;
+import lombok.RequiredArgsConstructor;
+
+@RestController
+@RequestMapping(OzgcloudResourceController.PATH)
+@RequiredArgsConstructor
+public class OzgcloudResourceController {
+
+	static final String PATH = "/api/resources";
+	static final String PARAM_URI = "uri";
+
+	private final Collection<OzgcloudResourceURIResolver> resolvers;
+	private final OzgcloudResourceModelAssembler assembler;
+
+	@GetMapping(params = PARAM_URI)
+	public RepresentationModel<EntityModel<OzgcloudResource>> getOzgcloudResource(@RequestParam @NotBlank String uri) {
+		var resourceLink = resolveUri(uri);
+		if (resourceLink.isEmpty()) {
+			throw new ResourceNotFoundException(OzgcloudResource.class, uri);
+		}
+		return assembler.toModel(new OzgcloudResourceURIResolveResult(uri, resourceLink.get()));
+	}
+
+	private Optional<Link> resolveUri(String uri) {
+		return resolvers.stream()
+				.map(resolver -> resolver.resolve(uri))
+				.flatMap(Optional::stream)
+				.reduce((r1, r2) -> {
+					throw new TechnicalException("Multiple resolvers accepted uri " + uri);
+				});
+	}
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3e83cf3a97ba6615974c72667fb32b976b6a733
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java
@@ -0,0 +1,24 @@
+package de.ozgcloud.alfa.resource;
+
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.server.RepresentationModelAssembler;
+import org.springframework.stereotype.Component;
+
+import lombok.RequiredArgsConstructor;
+
+@Component
+@RequiredArgsConstructor
+class OzgcloudResourceModelAssembler implements RepresentationModelAssembler<OzgcloudResourceURIResolveResult, EntityModel<OzgcloudResource>> {
+
+	@Override
+	public EntityModel<OzgcloudResource> toModel(OzgcloudResourceURIResolveResult uriResolveResult) {
+		return EntityModel.of(new OzgcloudResource()).add(getSelfLink(uriResolveResult.getResourceURI())).add(uriResolveResult.getResourceLink());
+	}
+
+	private Link getSelfLink(String uri) {
+		return linkTo(methodOn(OzgcloudResourceController.class).getOzgcloudResource(uri)).withSelfRel();
+	}
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebe46beb467ae69720dafe31da6121fcd4b4a956
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java
@@ -0,0 +1,20 @@
+package de.ozgcloud.alfa.resource;
+
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.server.RepresentationModelProcessor;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.alfa.Root;
+
+@Component
+class OzgcloudResourceRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> {
+
+	static final String REL_RESOURCE = "resource";
+
+	@Override
+	public EntityModel<Root> process(EntityModel<Root> model) {
+		return model.add(linkTo(methodOn(OzgcloudResourceController.class).getOzgcloudResource(null)).withRel(REL_RESOURCE));
+	}
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..edcbd9ef072905e7a30930396e1afa0d68a90aa3
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java
@@ -0,0 +1,15 @@
+package de.ozgcloud.alfa.resource;
+
+import org.springframework.hateoas.Link;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+
+@Builder
+@Getter
+@ToString
+public class OzgcloudResourceURIResolveResult {
+	private final String resourceURI;
+	private final Link resourceLink;
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..de38d882ecb8d41c198915eafc20b830798f4fbc
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolver.java
@@ -0,0 +1,10 @@
+package de.ozgcloud.alfa.resource;
+
+import java.util.Optional;
+
+import org.springframework.hateoas.Link;
+
+public interface OzgcloudResourceURIResolver {
+
+	Optional<Link> resolve(String uri);
+}
diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3b6a185dce5c3e3189fabe78e6301c23ccce5a0
--- /dev/null
+++ b/alfa-service/src/main/java/de/ozgcloud/alfa/vorgang/VorgangURIResolver.java
@@ -0,0 +1,29 @@
+package de.ozgcloud.alfa.vorgang;
+
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+import org.springframework.hateoas.Link;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.alfa.resource.OzgcloudResourceURIResolver;
+
+@Component
+class VorgangURIResolver implements OzgcloudResourceURIResolver {
+
+	static final String REL_NAME = "vorgang";
+
+	private final Pattern pattern = Pattern.compile("ozgcloud://[^/]+/vorgangs/([0-9a-fA-F]+)");
+
+	@Override
+	public Optional<Link> resolve(String uri) {
+		var matcher = pattern.matcher(uri);
+		if (!matcher.matches()) {
+			return Optional.empty();
+		}
+		var vorgangId = matcher.group(1);
+		return Optional.of(linkTo(VorgangController.class).slash(vorgangId).withRel(REL_NAME));
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..c4bc47bb1aba700a268c32f282fb569ecb3f909e
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java
@@ -0,0 +1,52 @@
+package de.ozgcloud.alfa;
+
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import org.hamcrest.core.StringEndsWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+
+import de.ozgcloud.alfa.common.user.CurrentUserService;
+import de.ozgcloud.alfa.common.user.UserProfileTestFactory;
+
+@AutoConfigureMockMvc
+@SpringBootTest
+@WithMockUser
+class RootControllerITCase {
+
+	@MockBean
+	private CurrentUserService currentUserService;
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@BeforeEach
+	void init() {
+		when(currentUserService.getUser()).thenReturn(UserProfileTestFactory.create());
+	}
+
+	@Nested
+	class TestProcess {
+
+		@Test
+		void shouldAddResourceLink() throws Exception {
+			var response = doRequest();
+
+			response.andExpect(jsonPath("$._links.resource.href").value(StringEndsWith.endsWith("/api/resources?uri={uri}")));
+		}
+	}
+
+	private ResultActions doRequest() throws Exception {
+		return mockMvc.perform(get(RootController.PATH)).andExpect(status().isOk());
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..a545d2ee05325037544e883b529b7c39d4d9c991
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java
@@ -0,0 +1,90 @@
+package de.ozgcloud.alfa.resource;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+import org.hamcrest.core.StringEndsWith;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+
+import de.ozgcloud.alfa.common.AlfaTestUtils;
+import lombok.SneakyThrows;
+
+@AutoConfigureMockMvc
+@SpringBootTest
+@WithMockUser
+class OzgcloudResourceControllerITCase {
+
+	@Autowired
+	private MockMvc mockMvc;
+
+	@Nested
+	class TestGetOzgcloudResource {
+
+		private static final String VORGANG_ID = AlfaTestUtils.createMongoDbObjectId();
+
+		@Test
+		void shouldReturnStatusOk() throws Exception {
+			var response = doRequest("ozgcloud://test.de/vorgangs/" + VORGANG_ID);
+
+			response.andExpect(status().isOk());
+		}
+
+		@Test
+		void shouldHaveVorgangLink() throws Exception {
+			var response = doRequest("ozgcloud://test.de/vorgangs/" + VORGANG_ID);
+
+			response.andExpect(jsonPath("$._links.vorgang.href").value(StringEndsWith.endsWith("/api/vorgangs/" + VORGANG_ID)));
+		}
+
+		@Test
+		void shouldHaveSelfLink() throws Exception {
+			var uri = "ozgcloud://test.de/vorgangs/" + VORGANG_ID;
+			var encodedUri = URLEncoder.encode(uri, StandardCharsets.UTF_8);
+
+			var response = doRequest(uri);
+
+			response.andExpect(jsonPath("$._links.self.href").value(StringEndsWith.endsWith(OzgcloudResourceController.PATH + "?uri=" + encodedUri)));
+		}
+
+		@Test
+		void shouldReturnStatusNotFound() throws Exception {
+			var response = doRequest("dummy://test.de");
+
+			response.andExpect(status().isNotFound());
+		}
+
+		@Test
+		void shouldReturnBadRequestOnNoRequestParam() throws Exception {
+			var response = doRequestWithQueryString("");
+
+			response.andExpect(status().isBadRequest());
+		}
+
+		@Test
+		void shouldReturnBadRequestOnEmptyUri() throws Exception {
+			var response = doRequestWithQueryString("?uri=");
+
+			response.andExpect(status().isBadRequest());
+		}
+
+		@SneakyThrows
+		private ResultActions doRequest(String uri) {
+			return doRequestWithQueryString("?uri=" + uri);
+		}
+
+		@SneakyThrows
+		private ResultActions doRequestWithQueryString(String queryString) {
+			return mockMvc.perform(get(OzgcloudResourceController.PATH + queryString));
+		}
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ea5e3d62933188bc4a839a69b7b3cb4d2c63cb1
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java
@@ -0,0 +1,130 @@
+package de.ozgcloud.alfa.resource;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.RepresentationModel;
+
+import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException;
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import lombok.SneakyThrows;
+
+class OzgcloudResourceControllerTest {
+
+	@Mock
+	private OzgcloudResourceURIResolver resourceAResolver;
+	@Mock
+	private OzgcloudResourceURIResolver resourceBResolver;
+	@Spy
+	private Collection<OzgcloudResourceURIResolver> resourceResolvers = new ArrayList<>();
+	@Mock
+	private OzgcloudResourceModelAssembler assembler;
+	@InjectMocks
+	private OzgcloudResourceController controller;
+
+	@BeforeEach
+	void init() {
+		resourceResolvers.add(resourceAResolver);
+		resourceResolvers.add(resourceBResolver);
+	}
+
+	@Nested
+	class TestGetOzgcloudResource {
+
+		@Nested
+		class OnUriCouldBeResolved {
+
+			private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_URI = mapping -> mapping.getResourceURI().equals(
+					OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI);
+			private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_LINK = mapping -> mapping.getResourceLink().equals(
+					OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK);
+
+			@BeforeEach
+			void init() {
+				when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of(
+						OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK));
+			}
+
+			@Test
+			void shouldCallResolver() {
+				callController();
+
+				verify(resourceBResolver).resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI);
+			}
+
+			@Test
+			void shouldCallAssemblerWithUri() {
+				callController();
+
+				verify(assembler).toModel(argThat(HAS_MATCHING_RESOURCE_URI));
+			}
+
+			@Test
+			void shouldCallAssemblerWithResourceLink() {
+				callController();
+
+				verify(assembler).toModel(argThat(HAS_MATCHING_RESOURCE_LINK));
+			}
+
+			@Test
+			void shouldReturnModelFromAssembler() {
+				EntityModel<OzgcloudResource> modelFromAssembler = EntityModel.of(new OzgcloudResource());
+				when(assembler.toModel(argThat(mapping -> HAS_MATCHING_RESOURCE_URI.matches(mapping) && HAS_MATCHING_RESOURCE_LINK.matches(mapping))))
+						.thenReturn(modelFromAssembler);
+
+				var model = callController();
+
+				assertThat(model).isEqualTo(modelFromAssembler);
+			}
+		}
+
+		@Nested
+		class OnUriCouldNotBeResolved {
+
+			@BeforeEach
+			void init() {
+				when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty());
+				when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty());
+			}
+
+			@Test
+			void shouldThrowResourceNotFoundException() {
+				assertThatThrownBy(TestGetOzgcloudResource.this::callController).isInstanceOf(ResourceNotFoundException.class);
+			}
+		}
+
+		@Nested
+		class OnMultipleResolveResults {
+
+			@BeforeEach
+			void init() {
+				when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of(
+						OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK));
+				when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of(
+						OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK));
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThatThrownBy(TestGetOzgcloudResource.this::callController).isInstanceOf(TechnicalException.class);
+			}
+		}
+
+		@SneakyThrows
+		private RepresentationModel<EntityModel<OzgcloudResource>> callController() {
+			return controller.getOzgcloudResource(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI);
+		}
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed144040a39978e418d2248ca496007c4c4f05ac
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java
@@ -0,0 +1,43 @@
+package de.ozgcloud.alfa.resource;
+
+import static de.ozgcloud.alfa.resource.OzgcloudResourceController.*;
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.IanaLinkRelations;
+import org.springframework.hateoas.Link;
+
+class OzgcloudResourceModelAssemblerTest {
+
+	@InjectMocks
+	private OzgcloudResourceModelAssembler assembler;
+
+	@Nested
+	class TestToModel {
+
+		private final OzgcloudResourceURIResolveResult uriResolveResult = OzgcloudResourceURIResolveResultTestFactory.create();
+
+		@Test
+		void shouldHaveSelfLink() {
+			var model = callAssembler();
+
+			assertThat(model.getLink(IanaLinkRelations.SELF_VALUE)).isPresent().get().extracting(Link::getHref)
+					.isEqualTo(OzgcloudResourceController.PATH + "?" + PARAM_URI + "=" + OzgcloudResourceURIResolveResultTestFactory.ENCODED_RESOURCE_URI);
+		}
+
+		@Test
+		void shouldHaveResourceLink() {
+			var model = callAssembler();
+
+			assertThat(model.getLink(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK.getRel())).isPresent().get().isEqualTo(
+					OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK);
+		}
+
+		private EntityModel<OzgcloudResource> callAssembler() {
+			return assembler.toModel(uriResolveResult);
+		}
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..71d60de1e746dd5f801b5d0a4f87b0d93493bcc7
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java
@@ -0,0 +1,39 @@
+package de.ozgcloud.alfa.resource;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.hateoas.EntityModel;
+import org.springframework.hateoas.Link;
+
+import de.ozgcloud.alfa.Root;
+import de.ozgcloud.alfa.RootTestFactory;
+
+class OzgcloudResourceRootProcessorTest {
+
+	private final OzgcloudResourceRootProcessor processor = new OzgcloudResourceRootProcessor();
+
+	@Nested
+	class TestProcess {
+
+		private final EntityModel<Root> model = EntityModel.of(RootTestFactory.create());
+
+		@Test
+		void shouldReturnOriginalModel() {
+			var result = processor.process(model);
+
+			assertThat(result).isEqualTo(model);
+		}
+
+		@Test
+		void shouldAddResourceLink() {
+			processor.process(model);
+
+			assertThat(model.getLink(OzgcloudResourceRootProcessor.REL_RESOURCE)).isPresent().get().extracting(Link::getHref)
+					.isEqualTo(OzgcloudResourceController.PATH + "?uri={uri}");
+		}
+	}
+}
+
+
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd0ea565f584133ece1265c2c2a9782135a65a74
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.alfa.resource;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+import org.springframework.hateoas.Link;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+class OzgcloudResourceURIResolveResultTestFactory {
+
+	public static final String RESOURCE_URI = String.format("%s://%s.%s/%s", (Object[]) LoremIpsum.getInstance().getWords(4).split("\\s"));
+	public static final String ENCODED_RESOURCE_URI = URLEncoder.encode(RESOURCE_URI, StandardCharsets.UTF_8);
+	public static final Link RESOURCE_LINK = Link.of(LoremIpsum.getInstance().getUrl()).withRel(LoremIpsum.getInstance().getWords(1));
+
+	public static OzgcloudResourceURIResolveResult create() {
+		return createBuilder().build();
+	}
+
+	public static OzgcloudResourceURIResolveResult.OzgcloudResourceURIResolveResultBuilder createBuilder() {
+		return OzgcloudResourceURIResolveResult.builder().resourceURI(RESOURCE_URI).resourceLink(RESOURCE_LINK);
+	}
+}
diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d691c621cc7e42d207861ccb6503bd04026a74c
--- /dev/null
+++ b/alfa-service/src/test/java/de/ozgcloud/alfa/vorgang/VorgangURIResolverTest.java
@@ -0,0 +1,61 @@
+package de.ozgcloud.alfa.vorgang;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.springframework.hateoas.Link;
+import org.springframework.hateoas.LinkRelation;
+
+import de.ozgcloud.alfa.common.AlfaTestUtils;
+
+class VorgangURIResolverTest {
+
+	private VorgangURIResolver resolver = new VorgangURIResolver();
+
+	@Nested
+	class TestResolve {
+
+		private final String VORGANG_ID = AlfaTestUtils.createMongoDbObjectId();
+		private final String VORGANG_URI = "ozgcloud://dummy.de/vorgangs/" + VORGANG_ID;
+
+		@ParameterizedTest
+		@ValueSource(strings = {
+				"http://dummy.de/vorgangs/123",
+				"ozgcloud://dummy.de/res-a/123",
+				"ozgcloud://dummy.de/xyz/vorgangs/123",
+				"ozgcloud://dummy.de/vorgangs/xyz/123" })
+		void shouldReturnEmptyIfUriIsNotRecognized(String uri) {
+			var result = resolver.resolve(uri);
+
+			assertThat(result).isEmpty();
+		}
+
+		@Test
+		void shouldReturnLink() {
+			var result = resolver.resolve(VORGANG_URI);
+
+			assertThat(result).isPresent();
+		}
+
+		@Nested
+		class TestVorgangLink {
+
+			@Test
+			void shouldHaveCorrectRelValue() {
+				var result = resolver.resolve(VORGANG_URI);
+
+				assertThat(result).get().extracting(Link::getRel).extracting(LinkRelation::value).isEqualTo(VorgangURIResolver.REL_NAME);
+			}
+
+			@Test
+			void shouldHaveHrefOfVorgang() {
+				var result = resolver.resolve(VORGANG_URI);
+
+				assertThat(result).get().extracting(Link::getHref).isEqualTo("/api/vorgangs/" + VORGANG_ID);
+			}
+		}
+	}
+}
diff --git a/alfa-xdomea/pom.xml b/alfa-xdomea/pom.xml
index 4bd9cb9cc3356d4ff4484bfd957150d964526142..ce932acc53706fb904954f17bc19ea7c52c29b22 100644
--- a/alfa-xdomea/pom.xml
+++ b/alfa-xdomea/pom.xml
@@ -31,7 +31,7 @@
 	<parent>
 		<groupId>de.ozgcloud.alfa</groupId>
 		<artifactId>alfa</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.14.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>alfa-xdomea</artifactId>
diff --git a/pom.xml b/pom.xml
index 5c3018e62bf6370472aba1576215d06d0e43067d..e05df380d5db04e9031bf6d4d0c59d49253bc3d9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,9 +24,7 @@
     unter der Lizenz sind dem Lizenztext zu entnehmen.
 
 -->
-<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 
 	<parent>
@@ -37,7 +35,7 @@
 
 	<groupId>de.ozgcloud.alfa</groupId>
 	<artifactId>alfa</artifactId>
-	<version>2.13.0-SNAPSHOT</version>
+	<version>2.14.0-SNAPSHOT</version>
 	<name>Alfa Parent</name>
 	<packaging>pom</packaging>
 
@@ -52,11 +50,11 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 
-		<vorgang-manager.version>2.8.0</vorgang-manager.version>
-		<nachrichten-manager.version>2.7.0</nachrichten-manager.version>
+		<vorgang-manager.version>2.13.0</vorgang-manager.version>
+		<nachrichten-manager.version>2.11.0</nachrichten-manager.version>
 		<ozgcloud-common-pdf.version>3.0.1</ozgcloud-common-pdf.version>
-		<user-manager.version>2.2.0</user-manager.version>
-		<zufi-manager.version>1.2.0</zufi-manager.version>
+		<user-manager.version>2.8.0</user-manager.version>
+		<zufi-manager.version>1.3.0</zufi-manager.version>
 		<spring-cloud-config-client.version>4.1.3</spring-cloud-config-client.version>
 
 		<!-- TODO: die Version über ozgcloud-common ziehen -->
@@ -179,4 +177,4 @@
 			<url>https://nexus.ozg-sh.de/repository/ozg-snapshots/</url>
 		</snapshotRepository>
 	</distributionManagement>
-</project>
\ No newline at end of file
+</project>
diff --git a/src/main/helm/templates/_helpers.tpl b/src/main/helm/templates/_helpers.tpl
index a20881dd0de555971004516d03a0a3767809c394..fde4a4e14938c745ee8972e5a8c9781a7f5c0669 100644
--- a/src/main/helm/templates/_helpers.tpl
+++ b/src/main/helm/templates/_helpers.tpl
@@ -50,7 +50,7 @@ app.kubernetes.io/namespace: {{ include "app.namespace" . }}
 {{- end -}}
 
 {{- define "app.grpc_client_vorgang_manager_address" -}}
-{{ printf "%s.%s:9090" ( coalesce .Values.vorgangManagerName "vorgang-manager" ) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{ printf "dns:///%s.%s:9090" ( coalesce .Values.vorgangManagerName "vorgang-manager" ) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" }}
 {{- end -}}
 
 {{- define "app.grpc_client_user-manager_address" -}}
diff --git a/src/test/helm/deployment_defaults_env_test.yaml b/src/test/helm/deployment_defaults_env_test.yaml
index 0bf3a7adbf32e293791d0af1a2804bf7c8c4d6df..f02a3b9989743688a6baa2527e7376ca7c9945f4 100644
--- a/src/test/helm/deployment_defaults_env_test.yaml
+++ b/src/test/helm/deployment_defaults_env_test.yaml
@@ -48,7 +48,7 @@ tests:
           path: spec.template.spec.containers[0].env
           content:
             name: grpc_client_vorgang-manager_address
-            value: vorgang-manager.sh-helm-test:9090
+            value: dns:///vorgang-manager.sh-helm-test:9090
       - contains:
           path: spec.template.spec.containers[0].env
           content:
diff --git a/src/test/helm/deployment_vorgang_manager_address_env_test.yaml b/src/test/helm/deployment_vorgang_manager_address_env_test.yaml
index 794e933ec92b521e7664244bae38f8b5b05b6469..9c0e685c4e9256e0053ebe3b4203e392f816e271 100644
--- a/src/test/helm/deployment_vorgang_manager_address_env_test.yaml
+++ b/src/test/helm/deployment_vorgang_manager_address_env_test.yaml
@@ -46,4 +46,4 @@ tests:
           path: spec.template.spec.containers[0].env
           content:
             name: grpc_client_vorgang-manager_address
-            value: my-test-vorgang-manager-name.sh-helm-test:9090
+            value: dns:///my-test-vorgang-manager-name.sh-helm-test:9090