diff --git a/agent-swagger.json b/agent-swagger.json
index 36a7939c1d8ff5118882a4bfcb80090733e8be13..29bddefdf9535ff4d2ad7cb4b5feb722bd1ad2d0 100644
--- a/agent-swagger.json
+++ b/agent-swagger.json
@@ -96,7 +96,14 @@
         ],
         "responses": {
           "200": {
-            "description": ""
+            "description": "",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/CreateInvitationResponseDto"
+                }
+              }
+            }
           }
         }
       },
@@ -924,6 +931,27 @@
         }
       }
     },
+    "/api/v1/created-dids": {
+      "get": {
+        "operationId": "RestController_getCreatedDids",
+        "parameters": [],
+        "responses": {
+          "200": {
+            "description": "",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/DidRecordDto"
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/api/v1/resolve-did": {
       "post": {
         "operationId": "RestController_resolveDid",
@@ -1567,6 +1595,44 @@
           "proofId",
           "proofUrl"
         ]
+      },
+      "DidRecordDto": {
+        "type": "object",
+        "properties": {
+          "did": {
+            "type": "string"
+          },
+          "role": {
+            "type": "string",
+            "enum": [
+              "created",
+              "received"
+            ]
+          },
+          "method": {
+            "type": "string"
+          },
+          "tags": {
+            "type": "object"
+          },
+          "id": {
+            "type": "string"
+          },
+          "createdAt": {
+            "format": "date-time",
+            "type": "string"
+          },
+          "updatedAt": {
+            "format": "date-time",
+            "type": "string"
+          }
+        },
+        "required": [
+          "did",
+          "role",
+          "method",
+          "tags"
+        ]
       }
     }
   }
diff --git a/libs/askar/src/agent.utils.ts b/libs/askar/src/agent.utils.ts
index 61333fba9816d15ffa9c7cefc95702e1405d50d3..ca9c060d64bf1601ed07a70028a4fcd25da17b17 100644
--- a/libs/askar/src/agent.utils.ts
+++ b/libs/askar/src/agent.utils.ts
@@ -27,6 +27,10 @@ import {
   CredentialEventTypes,
   CredentialState,
   ProofExchangeRecord,
+  JsonTransformer,
+  DidDocument,
+  WebDidResolver,
+  JwkDidResolver,
 } from "@aries-framework/core";
 import {
   AnonCredsCredentialFormatService,
@@ -45,7 +49,7 @@ import { anoncreds } from "@hyperledger/anoncreds-nodejs";
 import { indyVdr } from "@hyperledger/indy-vdr-nodejs";
 import { AskarModule } from "@aries-framework/askar";
 import { ariesAskar } from "@hyperledger/aries-askar-nodejs";
-import { Key as C, KeyAlgs } from "@hyperledger/aries-askar-shared";
+import { Key as AskarKey, KeyAlgs } from "@hyperledger/aries-askar-shared";
 import { IConfAgent } from "@ocm-engine/config";
 import axios from "axios";
 import {
@@ -68,6 +72,7 @@ export type SubjectMessage = {
   replySubject?: Subject<SubjectMessage>;
 };
 import { Request, Response, Express } from "express";
+import url from "url";
 
 export const importDidsToWallet = async (
   agent: Agent,
@@ -96,18 +101,18 @@ export const generateKey = async ({
     throw Error("No seed provided");
   }
 
-  const privateKey = TypedArrayEncoder.fromString(seed);
+  const seedBuffer = TypedArrayEncoder.fromString(seed);
 
   try {
     return await agent.wallet.createKey({
-      seed: privateKey,
+      seed: seedBuffer,
       keyType: KeyType.Ed25519,
     });
   } catch (e) {
     if (e instanceof WalletKeyExistsError) {
-      const c = C.fromSecretBytes({
+      const c = AskarKey.fromSeed({
         algorithm: KeyAlgs.Ed25519,
-        secretKey: TypedArrayEncoder.fromString(seed),
+        seed: seedBuffer,
       });
 
       return Key.fromPublicKey(c.publicBytes, KeyType.Ed25519);
@@ -121,6 +126,83 @@ export const generateKey = async ({
   }
 };
 
+export const generateDidWeb = async ({
+  seed,
+  agent,
+  peerAddress
+}: {
+  seed: string;
+  agent: Agent;
+  peerAddress: string;
+}) => {
+  console.log("Generating did web");
+  const pubKey = await generateKey({ seed, agent });
+
+  const parsedUrl = url.parse(peerAddress);
+  let hostname = parsedUrl.hostname!;
+  const port = parsedUrl.port;
+  let pathname = parsedUrl.pathname?.replace(/^\/+|\/+$/g, '');
+
+  // If port is specified, encode it
+  if (port) {
+    hostname += `%3A${port}`;
+  }
+  // Convert URLs to 'did:web' form
+  let didWeb = `did:web:${hostname}`;
+  if (pathname) {
+    didWeb += `:${pathname.replace(/\//g, ':')}`;
+  }
+
+  const verificationMethodKey0Id = `${didWeb}#jwt-key0`;
+
+  const jsonDidDoc = {
+    "@context": [
+      "https://www.w3.org/ns/did/v1",
+      "https://w3id.org/security/suites/ed25519-2018/v1"
+    ],
+    "id": didWeb,
+    "verificationMethod": [
+      {
+        "id": verificationMethodKey0Id,
+        "type": "Ed25519VerificationKey2018",
+        "controller": didWeb,
+        "publicKeyBase58": pubKey.publicKeyBase58
+      },
+    ],
+    "authentication": [
+      verificationMethodKey0Id
+    ],
+    "assertionMethod": [
+      verificationMethodKey0Id
+    ],
+    "keyAgreement": [
+      verificationMethodKey0Id
+    ]
+  };
+
+  const didDocumentInstance = JsonTransformer.fromJSON(jsonDidDoc, DidDocument)
+
+  const recordId = "did:web";
+  const existingRecord = await agent.genericRecords.findById(recordId);
+  if (existingRecord) {
+    await agent.genericRecords.deleteById(recordId);
+  }
+  await agent.genericRecords.save({
+    id: recordId,
+    content: jsonDidDoc
+  });
+
+  await agent.dids.import({
+    did: didWeb,
+    didDocument: didDocumentInstance,
+    overwrite: false
+  });
+
+  console.log("Generated did:web");
+  console.log(didWeb);
+  console.log(JSON.stringify(didDocumentInstance.toJSON(), null, 2));
+};
+
 export const generateDidFromKey = (key: Key): string => {
   if (!key) {
     throw new Error("Key not provided");
@@ -171,6 +253,8 @@ export const getAskarAnonCredsIndyModules = (networks: any) => {
         new IndyVdrIndyDidResolver(),
         new KeyDidResolver(),
         new PeerDidResolver(),
+        new WebDidResolver(),
+        new JwkDidResolver()
       ],
     }),
     askar: new AskarModule({
@@ -486,3 +570,38 @@ export const attachShortUrlHandler = (server: Express, agent: Agent): void => {
     },
   );
 };
+
+export const attachDidWebHandler = (server: Express, agent: Agent, agentPeerAddress: string): void => {
+  const parsedUrl = url.parse(agentPeerAddress);
+  const pathname = parsedUrl.pathname?.replace(/^\/+|\/+$/g, '');
+
+  let serverDidWebPath: string;
+  if (pathname) {
+    serverDidWebPath = `/did.json`;
+  } else {
+    serverDidWebPath = "/.well-known/did.json";
+  }
+
+  console.log('Listen did web requests on path ' + serverDidWebPath);
+  server.get(
+    serverDidWebPath,
+    async (req: Request, res: Response) => {
+      try {
+        const didWebRecord = await agent.genericRecords.findById("did:web");
+
+        if (!didWebRecord) {
+          return res.status(404).send("Not found");
+        }
+
+        const didWebDoc = didWebRecord.content;
+
+        return res
+          .header("Content-Type", "application/json")
+          .send(didWebDoc);
+      } catch (error) {
+        console.error(error);
+        return res.status(500).send("Internal Server Error");
+      }
+    },
+  );
+};
diff --git a/libs/askar/src/askar-rest/rest.controller.ts b/libs/askar/src/askar-rest/rest.controller.ts
index a2fc06e3d1134ca81392622af07aeb7a11137fab..29c8cf037dedac4f40620a23f43a641bb4b8da7d 100644
--- a/libs/askar/src/askar-rest/rest.controller.ts
+++ b/libs/askar/src/askar-rest/rest.controller.ts
@@ -25,6 +25,7 @@ import {
   CreateInvitationRequestDto,
   InvitationFilterDto,
   AcceptInvitationRequestDto,
+  DidRecordDto,
 } from "@ocm-engine/dtos";
 import { AllExceptionsHandler } from "./exception.handler";
 import { DidResolutionResult } from "@aries-framework/core";
@@ -215,6 +216,11 @@ export class RestController {
     return this.agentService.deleteProofById(proofRecordId);
   }
 
+  @Get("/created-dids")
+  async getCreatedDids(): Promise<DidRecordDto[]> {
+    return this.agentService.getCreatedDids();
+  }
+
   @Post("/resolve-did")
   async resolveDid(@Body() dto: IdReqDto): Promise<DidResolutionResult> {
     return this.agentService.resolve(dto.id);
diff --git a/libs/askar/src/askar/agent.service.ts b/libs/askar/src/askar/agent.service.ts
index 0dd9a78f93f685060e9f9ba11ac5b9142361f4eb..11605cd6e83caf8db1056c2a6683da82df247e23 100644
--- a/libs/askar/src/askar/agent.service.ts
+++ b/libs/askar/src/askar/agent.service.ts
@@ -27,6 +27,7 @@ import {
   ProofFormatDataDto,
   CreateInvitationRequestDto,
   InvitationFilterDto,
+  DidRecordDto,
 } from "@ocm-engine/dtos";
 import {
   AutoAcceptCredential,
@@ -979,4 +980,19 @@ export class AgentService {
   deleteMessageById = async (id: string): Promise<void> => {
     await this.askar.agent.basicMessages.deleteById(id);
   };
+
+  getCreatedDids = async (): Promise<DidRecordDto[]> => {
+    const didRecords = await this.askar.agent.dids.getCreatedDids();
+    return didRecords.map(p => {
+      const dto = new DidRecordDto();
+      const tags = p.getTags();
+
+      dto.did = p.did;
+      dto.role = p.role;
+      dto.method = tags.method;
+      dto.tags = tags;
+
+      return dto;
+    });
+  };
 }
diff --git a/libs/askar/src/askar/askar.service.ts b/libs/askar/src/askar/askar.service.ts
index f8f8664ae3ea09a2a84c6209bb469c48854e9e88..846af0559433776f1533c7bff2221fc92e740e9e 100644
--- a/libs/askar/src/askar/askar.service.ts
+++ b/libs/askar/src/askar/askar.service.ts
@@ -26,8 +26,10 @@ import {
   getAskarAnonCredsIndyModules,
   importDidsToWallet,
   attachShortUrlHandler,
+  attachDidWebHandler,
   setupEventBehaviorSubjects,
   setupSubjectTransports,
+  generateDidWeb,
 } from "../agent.utils";
 import { IConfAgent } from "@ocm-engine/config";
 import { BehaviorSubject } from "rxjs";
@@ -78,6 +80,7 @@ export class AskarService implements OnModuleInit, OnModuleDestroy {
 
     //handler for short url invitations, look at agent service createInvitation
     attachShortUrlHandler(this.server, this.agent);
+    attachDidWebHandler(this.server, this.agent, this.agentConfig.agentPeerAddress);
 
     this.agent.registerInboundTransport(
       new HttpInboundTransport({
@@ -111,6 +114,19 @@ export class AskarService implements OnModuleInit, OnModuleDestroy {
       throw new Error("agent not initialized");
     }
 
+    const didWebs = await this.agent.dids.getCreatedDids({ method: "web" });
+    if (didWebs.length) {
+      for (const didsKey in didWebs) {
+        this.logger.debug(`agent already have ${didWebs[didsKey].did} registered`);
+      }
+    } else {
+      await generateDidWeb({
+        agent: this.agent,
+        seed: this.agentConfig.agentDidSeed,
+        peerAddress: this.agentConfig.agentPeerAddress
+      });
+    }
+
     const dids = await this.agent.dids.getCreatedDids({ method: "indy" });
 
     if (dids.length) {
diff --git a/libs/dtos/src/dtos/generics/did.record.dto.ts b/libs/dtos/src/dtos/generics/did.record.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a3eac934bdc46718415f94fdc0ea4a371e86f2b
--- /dev/null
+++ b/libs/dtos/src/dtos/generics/did.record.dto.ts
@@ -0,0 +1,19 @@
+import { IsNotEmpty, IsString } from "class-validator";
+import { BaseRecordDto } from "./base.record.dto";
+import { DidDocumentRole } from "@aries-framework/core";
+
+export class DidRecordDto extends BaseRecordDto {
+  @IsNotEmpty()
+  @IsString()
+  did: string;
+
+  @IsNotEmpty()
+  @IsString()
+  role: DidDocumentRole;
+
+  @IsString()
+  @IsNotEmpty()
+  method: string;
+
+  tags: unknown;
+}
diff --git a/libs/dtos/src/index.ts b/libs/dtos/src/index.ts
index 8589661be71e8dc7b9363e6a29083e6eaa5b2df3..f5ff5ecf5c5b62b31923e102469da191a3c06f3f 100644
--- a/libs/dtos/src/index.ts
+++ b/libs/dtos/src/index.ts
@@ -12,6 +12,7 @@ export * from "./dtos/generics/schema.record.dto";
 export * from "./dtos/generics/message.record.dto";
 export * from "./dtos/generics/message.filter.dto";
 export * from "./dtos/generics/invitation.filter.dto";
+export * from "./dtos/generics/did.record.dto";
 
 export * from "./dtos/requests/accept.proof.dto";
 export * from "./dtos/requests/accept.credential.dto";