diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 63bd9d07be7a5962517b0fb2c33b24d714822c09..b2048c1984351b48488ecf0ae152a0e9b6558eaa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,7 +16,7 @@ include:
   - template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'
 
 lint:
-  image: golangci/golangci-lint:v1.44.2
+  image: golangci/golangci-lint:v1.50.1
   stage: test
   tags:
     - amd64-docker
@@ -28,12 +28,27 @@ lint:
     - cd /go/src/gitlab.com/${CI_PROJECT_PATH}
 
 unit tests:
-  image: golang:1.17.7
+  image: golang:1.19.3
   extends: .gotest
   stage: test
   tags:
     - amd64-docker
   before_script: []
+  coverage: '/total:\s+\(statements\)\s+(\d+.\d+\%)/'
+
+govulncheck:
+  image: golang:1.19.3
+  stage: test
+  tags:
+    - amd64-docker
+  before_script:
+    - ln -s /builds /go/src/gitlab.com
+    - cd /go/src/gitlab.com/${CI_PROJECT_PATH}
+  script:
+    - go version
+    - go install golang.org/x/vuln/cmd/govulncheck@latest
+    - govulncheck ./...
+
 
 amd64:
   extends: .docker-build
diff --git a/.golangci.yml b/.golangci.yml
index e6ba71d0fff71ba18fa18f4bd0f55fbaad679ab2..a31b66b24000f23ec82f765c828a26cf2bef07bd 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -12,7 +12,6 @@ linters:
   enable:
     - megacheck
     - govet
-    - deadcode
     - errcheck
     - goconst
     - gocyclo
@@ -22,10 +21,9 @@ linters:
     - ineffassign
     - nakedret
     - staticcheck
-    - structcheck
     - unconvert
-    - varcheck
     - vet
     - vetshadow
     - misspell
     - staticcheck
+    - unused
diff --git a/cmd/infohub/main.go b/cmd/infohub/main.go
index 528254cf4f2f73c582ebd5a154cc74e66ba260b6..138bf4b4048dca2abf3a4e207b1f53deb9b3b27c 100644
--- a/cmd/infohub/main.go
+++ b/cmd/infohub/main.go
@@ -239,7 +239,7 @@ func exposeMetrics(addr string, logger *zap.Logger) {
 	promMux := http.NewServeMux()
 	promMux.Handle("/metrics", promhttp.Handler())
 	logger.Info(fmt.Sprintf("exposing prometheus metrics at %s/metrics", addr))
-	if err := http.ListenAndServe(addr, promMux); err != nil {
+	if err := http.ListenAndServe(addr, promMux); err != nil { //nolint:gosec
 		logger.Error("error exposing prometheus metrics", zap.Error(err))
 	}
 }
diff --git a/deployment/ci/Dockerfile b/deployment/ci/Dockerfile
index f216cd5e2b25e435f20d4dab62067745c42a64c4..0a90d092da2c9ed30a876e3a60458d037c0280ad 100644
--- a/deployment/ci/Dockerfile
+++ b/deployment/ci/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.19-alpine3.15 as builder
+FROM golang:1.19.3-alpine3.15 as builder
 
 RUN apk add git
 
diff --git a/deployment/compose/Dockerfile b/deployment/compose/Dockerfile
index 2bc21f6f0019826613955241677f8c091c70d933..6e4ef22aac6a1bde7022d47c3fe69c67e96ca345 100644
--- a/deployment/compose/Dockerfile
+++ b/deployment/compose/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.19
+FROM golang:1.19.3
 
 ENV GO111MODULE=on
 
diff --git a/internal/clients/signer/client.go b/internal/clients/signer/client.go
index c75c5064004f550d8db50b266481ce0b3a5bd25e..1550511dcf6763b6e76670a14fb9ad6aef2d8843 100644
--- a/internal/clients/signer/client.go
+++ b/internal/clients/signer/client.go
@@ -4,19 +4,16 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 
-	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
 	"github.com/piprate/json-gold/ld"
 
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors"
 )
 
 const (
-	presentationProofPath  = "/v1/presentation/proof"
+	createPresentationPath = "/v1/presentation"
 	presentationVerifyPath = "/v1/presentation/verify"
 )
 
@@ -41,13 +38,20 @@ func New(addr string, opts ...ClientOption) *Client {
 	return c
 }
 
-func (c *Client) PresentationProof(ctx context.Context, vp *verifiable.Presentation) (*verifiable.Presentation, error) {
-	vpBytes, err := json.Marshal(vp)
+func (c *Client) CreatePresentation(ctx context.Context, issuer, namespace, key string, data []map[string]interface{}) (map[string]interface{}, error) {
+	payload := map[string]interface{}{
+		"issuer":    issuer,
+		"namespace": namespace,
+		"key":       key,
+		"data":      data,
+	}
+
+	payloadJSON, err := json.Marshal(payload)
 	if err != nil {
 		return nil, err
 	}
 
-	req, err := http.NewRequestWithContext(ctx, "POST", c.addr+presentationProofPath, bytes.NewReader(vpBytes))
+	req, err := http.NewRequestWithContext(ctx, "POST", c.addr+createPresentationPath, bytes.NewReader(payloadJSON))
 	if err != nil {
 		return nil, err
 	}
@@ -59,19 +63,15 @@ func (c *Client) PresentationProof(ctx context.Context, vp *verifiable.Presentat
 	defer resp.Body.Close()
 
 	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("unexpected response from signer: %s", resp.Status)
+		return nil, errors.New(errors.GetKind(resp.StatusCode), getErrorBody(resp))
 	}
 
-	respBytes, err := io.ReadAll(resp.Body)
-	if err != nil {
-		return nil, err
+	var presentation map[string]interface{}
+	if err := json.NewDecoder(resp.Body).Decode(&presentation); err != nil {
+		return nil, errors.New("error decoding signer response as verifiable presentation", err)
 	}
 
-	return verifiable.ParsePresentation(
-		respBytes,
-		verifiable.WithPresJSONLDDocumentLoader(c.docLoader),
-		verifiable.WithPresDisabledProofCheck(),
-	)
+	return presentation, nil
 }
 
 func (c *Client) VerifyPresentation(ctx context.Context, vp []byte) error {
@@ -105,7 +105,7 @@ func (c *Client) VerifyPresentation(ctx context.Context, vp []byte) error {
 }
 
 func getErrorBody(resp *http.Response) string {
-	body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 2<<20))
+	body, err := io.ReadAll(io.LimitReader(resp.Body, 2<<20))
 	if err != nil {
 		return ""
 	}
diff --git a/internal/clients/signer/client_test.go b/internal/clients/signer/client_test.go
index 2ea0ca6559d2da63aa312215ce3c040ac162bb69..065ce82afbc585508495b2f4bc7695ac48ab2c64 100644
--- a/internal/clients/signer/client_test.go
+++ b/internal/clients/signer/client_test.go
@@ -6,125 +6,107 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
-	"github.com/piprate/json-gold/ld"
 	"github.com/stretchr/testify/assert"
 
+	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/golib/errors"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/clients/signer"
 )
 
-const invalidPresentation = `{"invalid":"verifiable_presentation"}`
-
-const validPresentation = `{
-  "@context": [
-    "https://www.w3.org/2018/credentials/v1",
-    "https://www.w3.org/2018/credentials/examples/v1"
-  ],
-  "id": "did:123",
-  "type": "VerifiablePresentation",
-  "verifiableCredential": [
-    {
-      "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://www.w3.org/2018/credentials/examples/v1"
-      ],
-      "credentialSubject": {
-        "allow": true,
-        "id": "example/example/1.0",
-        "taskID": "0123456789abcdef"
-      },
-      "issuanceDate": "2022-06-14T08:43:22.78309334Z",
-      "issuer": "https://example.com",
-      "type": "VerifiableCredential"
-    },
-    {
-      "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://www.w3.org/2018/credentials/examples/v1"
-      ],
-      "credentialSubject": {
-        "id": "example/example/2.0",
-        "result": {
-          "hello": "world"
-        }
-      },
-      "issuanceDate": "2022-06-14T08:43:22.783102173Z",
-      "issuer": "https://example.com",
-      "type": "VerifiableCredential"
-    }
-  ]
-}`
-
-func TestClient_PresentationProof(t *testing.T) {
+func TestClient_CreatePresentation(t *testing.T) {
 	tests := []struct {
 		name    string
-		ctx     context.Context
-		vp      *verifiable.Presentation
+		data    []map[string]interface{}
 		handler http.HandlerFunc
 
-		result  *verifiable.Presentation
+		result  map[string]interface{}
+		errkind errors.Kind
 		errtext string
 	}{
 		{
-			name:    "error creating http request because of nil context",
-			errtext: "net/http: nil Context",
+			name: "signer returns error",
+			data: []map[string]interface{}{{"hello": "world"}},
+			handler: func(w http.ResponseWriter, r *http.Request) {
+				w.WriteHeader(http.StatusInternalServerError)
+				_, _ = w.Write([]byte("some error"))
+			},
+			errkind: errors.Internal,
+			errtext: "some error",
 		},
 		{
-			name: "signer server returns unexpected response code",
-			ctx:  context.Background(),
+			name: "signer successfully creates verifiable presentation",
+			data: []map[string]interface{}{{"hello": "world"}},
 			handler: func(w http.ResponseWriter, r *http.Request) {
-				w.WriteHeader(http.StatusServiceUnavailable)
+				w.WriteHeader(http.StatusOK)
+				_, _ = w.Write([]byte(`{"id":"did:web:example.com"}`))
 			},
-			errtext: "unexpected response from signer: 503 Service Unavailable",
+			result: map[string]interface{}{"id": "did:web:example.com"},
 		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			srv := httptest.NewServer(test.handler)
+			client := signer.New(srv.URL)
+			result, err := client.CreatePresentation(context.Background(), "issuer", "namespace", "key", test.data)
+			if test.errtext != "" {
+				assert.Error(t, err)
+				assert.Contains(t, err.Error(), test.errtext)
+				assert.Nil(t, result)
+			} else {
+				assert.NotNil(t, result)
+				assert.Equal(t, test.result, result)
+			}
+		})
+	}
+}
+
+func TestClient_VerifyPresentation(t *testing.T) {
+	tests := []struct {
+		name    string
+		vp      []byte
+		handler http.HandlerFunc
+		errkind errors.Kind
+		errtext string
+	}{
 		{
-			name: "signer server returns empty response",
-			ctx:  context.Background(),
+			name: "signer returns error",
+			vp:   []byte(`{"id":"did:web:example.com"}`),
 			handler: func(w http.ResponseWriter, r *http.Request) {
-				w.WriteHeader(http.StatusOK)
+				w.WriteHeader(http.StatusInternalServerError)
+				_, _ = w.Write([]byte("some error"))
 			},
-			errtext: "JSON unmarshalling of verifiable presentation: unexpected end of JSON input",
+			errkind: errors.Internal,
+			errtext: "some error",
 		},
 		{
-			name: "signer server returns invalid verifiable presentation",
-			ctx:  context.Background(),
+			name: "signer returns unexpected response",
+			vp:   []byte(`{"id":"did:web:example.com"}`),
 			handler: func(w http.ResponseWriter, r *http.Request) {
 				w.WriteHeader(http.StatusOK)
-				_, _ = w.Write([]byte(invalidPresentation))
+				_, _ = w.Write([]byte("invalid json"))
 			},
-			errtext: "verifiable presentation is not valid",
+			errkind: errors.Unknown,
+			errtext: "failed to decode response",
 		},
 		{
-			name: "signer server returns valid presentation",
-			ctx:  context.Background(),
+			name: "signer returns successfully",
+			vp:   []byte(`{"id":"did:web:example.com"}`),
 			handler: func(w http.ResponseWriter, r *http.Request) {
 				w.WriteHeader(http.StatusOK)
-				_, _ = w.Write([]byte(validPresentation))
+				_, _ = w.Write([]byte(`{"id":"did:web:example.com"}`))
 			},
 		},
 	}
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			signerSrv := httptest.NewServer(test.handler)
-			client := signer.New(signerSrv.URL, signer.WithHTTPClient(http.DefaultClient))
-			result, err := client.PresentationProof(test.ctx, test.vp)
+			srv := httptest.NewServer(test.handler)
+			client := signer.New(srv.URL)
+			err := client.VerifyPresentation(context.Background(), test.vp)
 			if err != nil {
-				assert.Nil(t, result)
-				assert.NotEmpty(t, test.errtext)
 				assert.Contains(t, err.Error(), test.errtext)
 			} else {
 				assert.Empty(t, test.errtext)
-				assert.NotNil(t, result)
-
-				// parse the string representation to compare with the returned result
-				vp, err := verifiable.ParsePresentation(
-					[]byte(validPresentation),
-					verifiable.WithPresJSONLDDocumentLoader(ld.NewDefaultDocumentLoader(http.DefaultClient)),
-					verifiable.WithPresDisabledProofCheck(),
-				)
-				assert.NoError(t, err)
-				assert.Equal(t, vp, result)
 			}
 		})
 	}
diff --git a/internal/service/infohub/infohubfakes/fake_credentials.go b/internal/service/infohub/infohubfakes/fake_credentials.go
index a66c24875dedb1748d9b4772f30693c332214397..783fab3ebd50afdbf915a4aa2d8d07d46e1bac91 100644
--- a/internal/service/infohub/infohubfakes/fake_credentials.go
+++ b/internal/service/infohub/infohubfakes/fake_credentials.go
@@ -9,36 +9,6 @@ import (
 )
 
 type FakeCredentials struct {
-	NewCredentialStub        func([]string, string, map[string]interface{}, bool) (*verifiable.Credential, error)
-	newCredentialMutex       sync.RWMutex
-	newCredentialArgsForCall []struct {
-		arg1 []string
-		arg2 string
-		arg3 map[string]interface{}
-		arg4 bool
-	}
-	newCredentialReturns struct {
-		result1 *verifiable.Credential
-		result2 error
-	}
-	newCredentialReturnsOnCall map[int]struct {
-		result1 *verifiable.Credential
-		result2 error
-	}
-	NewPresentationStub        func([]string, ...*verifiable.Credential) (*verifiable.Presentation, error)
-	newPresentationMutex       sync.RWMutex
-	newPresentationArgsForCall []struct {
-		arg1 []string
-		arg2 []*verifiable.Credential
-	}
-	newPresentationReturns struct {
-		result1 *verifiable.Presentation
-		result2 error
-	}
-	newPresentationReturnsOnCall map[int]struct {
-		result1 *verifiable.Presentation
-		result2 error
-	}
 	ParsePresentationStub        func([]byte) (*verifiable.Presentation, error)
 	parsePresentationMutex       sync.RWMutex
 	parsePresentationArgsForCall []struct {
@@ -56,148 +26,6 @@ type FakeCredentials struct {
 	invocationsMutex sync.RWMutex
 }
 
-func (fake *FakeCredentials) NewCredential(arg1 []string, arg2 string, arg3 map[string]interface{}, arg4 bool) (*verifiable.Credential, error) {
-	var arg1Copy []string
-	if arg1 != nil {
-		arg1Copy = make([]string, len(arg1))
-		copy(arg1Copy, arg1)
-	}
-	fake.newCredentialMutex.Lock()
-	ret, specificReturn := fake.newCredentialReturnsOnCall[len(fake.newCredentialArgsForCall)]
-	fake.newCredentialArgsForCall = append(fake.newCredentialArgsForCall, struct {
-		arg1 []string
-		arg2 string
-		arg3 map[string]interface{}
-		arg4 bool
-	}{arg1Copy, arg2, arg3, arg4})
-	stub := fake.NewCredentialStub
-	fakeReturns := fake.newCredentialReturns
-	fake.recordInvocation("NewCredential", []interface{}{arg1Copy, arg2, arg3, arg4})
-	fake.newCredentialMutex.Unlock()
-	if stub != nil {
-		return stub(arg1, arg2, arg3, arg4)
-	}
-	if specificReturn {
-		return ret.result1, ret.result2
-	}
-	return fakeReturns.result1, fakeReturns.result2
-}
-
-func (fake *FakeCredentials) NewCredentialCallCount() int {
-	fake.newCredentialMutex.RLock()
-	defer fake.newCredentialMutex.RUnlock()
-	return len(fake.newCredentialArgsForCall)
-}
-
-func (fake *FakeCredentials) NewCredentialCalls(stub func([]string, string, map[string]interface{}, bool) (*verifiable.Credential, error)) {
-	fake.newCredentialMutex.Lock()
-	defer fake.newCredentialMutex.Unlock()
-	fake.NewCredentialStub = stub
-}
-
-func (fake *FakeCredentials) NewCredentialArgsForCall(i int) ([]string, string, map[string]interface{}, bool) {
-	fake.newCredentialMutex.RLock()
-	defer fake.newCredentialMutex.RUnlock()
-	argsForCall := fake.newCredentialArgsForCall[i]
-	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
-}
-
-func (fake *FakeCredentials) NewCredentialReturns(result1 *verifiable.Credential, result2 error) {
-	fake.newCredentialMutex.Lock()
-	defer fake.newCredentialMutex.Unlock()
-	fake.NewCredentialStub = nil
-	fake.newCredentialReturns = struct {
-		result1 *verifiable.Credential
-		result2 error
-	}{result1, result2}
-}
-
-func (fake *FakeCredentials) NewCredentialReturnsOnCall(i int, result1 *verifiable.Credential, result2 error) {
-	fake.newCredentialMutex.Lock()
-	defer fake.newCredentialMutex.Unlock()
-	fake.NewCredentialStub = nil
-	if fake.newCredentialReturnsOnCall == nil {
-		fake.newCredentialReturnsOnCall = make(map[int]struct {
-			result1 *verifiable.Credential
-			result2 error
-		})
-	}
-	fake.newCredentialReturnsOnCall[i] = struct {
-		result1 *verifiable.Credential
-		result2 error
-	}{result1, result2}
-}
-
-func (fake *FakeCredentials) NewPresentation(arg1 []string, arg2 ...*verifiable.Credential) (*verifiable.Presentation, error) {
-	var arg1Copy []string
-	if arg1 != nil {
-		arg1Copy = make([]string, len(arg1))
-		copy(arg1Copy, arg1)
-	}
-	fake.newPresentationMutex.Lock()
-	ret, specificReturn := fake.newPresentationReturnsOnCall[len(fake.newPresentationArgsForCall)]
-	fake.newPresentationArgsForCall = append(fake.newPresentationArgsForCall, struct {
-		arg1 []string
-		arg2 []*verifiable.Credential
-	}{arg1Copy, arg2})
-	stub := fake.NewPresentationStub
-	fakeReturns := fake.newPresentationReturns
-	fake.recordInvocation("NewPresentation", []interface{}{arg1Copy, arg2})
-	fake.newPresentationMutex.Unlock()
-	if stub != nil {
-		return stub(arg1, arg2...)
-	}
-	if specificReturn {
-		return ret.result1, ret.result2
-	}
-	return fakeReturns.result1, fakeReturns.result2
-}
-
-func (fake *FakeCredentials) NewPresentationCallCount() int {
-	fake.newPresentationMutex.RLock()
-	defer fake.newPresentationMutex.RUnlock()
-	return len(fake.newPresentationArgsForCall)
-}
-
-func (fake *FakeCredentials) NewPresentationCalls(stub func([]string, ...*verifiable.Credential) (*verifiable.Presentation, error)) {
-	fake.newPresentationMutex.Lock()
-	defer fake.newPresentationMutex.Unlock()
-	fake.NewPresentationStub = stub
-}
-
-func (fake *FakeCredentials) NewPresentationArgsForCall(i int) ([]string, []*verifiable.Credential) {
-	fake.newPresentationMutex.RLock()
-	defer fake.newPresentationMutex.RUnlock()
-	argsForCall := fake.newPresentationArgsForCall[i]
-	return argsForCall.arg1, argsForCall.arg2
-}
-
-func (fake *FakeCredentials) NewPresentationReturns(result1 *verifiable.Presentation, result2 error) {
-	fake.newPresentationMutex.Lock()
-	defer fake.newPresentationMutex.Unlock()
-	fake.NewPresentationStub = nil
-	fake.newPresentationReturns = struct {
-		result1 *verifiable.Presentation
-		result2 error
-	}{result1, result2}
-}
-
-func (fake *FakeCredentials) NewPresentationReturnsOnCall(i int, result1 *verifiable.Presentation, result2 error) {
-	fake.newPresentationMutex.Lock()
-	defer fake.newPresentationMutex.Unlock()
-	fake.NewPresentationStub = nil
-	if fake.newPresentationReturnsOnCall == nil {
-		fake.newPresentationReturnsOnCall = make(map[int]struct {
-			result1 *verifiable.Presentation
-			result2 error
-		})
-	}
-	fake.newPresentationReturnsOnCall[i] = struct {
-		result1 *verifiable.Presentation
-		result2 error
-	}{result1, result2}
-}
-
 func (fake *FakeCredentials) ParsePresentation(arg1 []byte) (*verifiable.Presentation, error) {
 	var arg1Copy []byte
 	if arg1 != nil {
@@ -270,10 +98,6 @@ func (fake *FakeCredentials) ParsePresentationReturnsOnCall(i int, result1 *veri
 func (fake *FakeCredentials) Invocations() map[string][][]interface{} {
 	fake.invocationsMutex.RLock()
 	defer fake.invocationsMutex.RUnlock()
-	fake.newCredentialMutex.RLock()
-	defer fake.newCredentialMutex.RUnlock()
-	fake.newPresentationMutex.RLock()
-	defer fake.newPresentationMutex.RUnlock()
 	fake.parsePresentationMutex.RLock()
 	defer fake.parsePresentationMutex.RUnlock()
 	copiedInvocations := map[string][][]interface{}{}
diff --git a/internal/service/infohub/infohubfakes/fake_signer.go b/internal/service/infohub/infohubfakes/fake_signer.go
index db2c0e1e4937a7162d9e6b180f833fefcf5e5712..556e6de1a5e261d52a65c07667c00b0145d31b30 100644
--- a/internal/service/infohub/infohubfakes/fake_signer.go
+++ b/internal/service/infohub/infohubfakes/fake_signer.go
@@ -5,23 +5,25 @@ import (
 	"context"
 	"sync"
 
-	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/tsa/infohub/internal/service/infohub"
 )
 
 type FakeSigner struct {
-	PresentationProofStub        func(context.Context, *verifiable.Presentation) (*verifiable.Presentation, error)
-	presentationProofMutex       sync.RWMutex
-	presentationProofArgsForCall []struct {
+	CreatePresentationStub        func(context.Context, string, string, string, []map[string]interface{}) (map[string]interface{}, error)
+	createPresentationMutex       sync.RWMutex
+	createPresentationArgsForCall []struct {
 		arg1 context.Context
-		arg2 *verifiable.Presentation
+		arg2 string
+		arg3 string
+		arg4 string
+		arg5 []map[string]interface{}
 	}
-	presentationProofReturns struct {
-		result1 *verifiable.Presentation
+	createPresentationReturns struct {
+		result1 map[string]interface{}
 		result2 error
 	}
-	presentationProofReturnsOnCall map[int]struct {
-		result1 *verifiable.Presentation
+	createPresentationReturnsOnCall map[int]struct {
+		result1 map[string]interface{}
 		result2 error
 	}
 	VerifyPresentationStub        func(context.Context, []byte) error
@@ -40,19 +42,27 @@ type FakeSigner struct {
 	invocationsMutex sync.RWMutex
 }
 
-func (fake *FakeSigner) PresentationProof(arg1 context.Context, arg2 *verifiable.Presentation) (*verifiable.Presentation, error) {
-	fake.presentationProofMutex.Lock()
-	ret, specificReturn := fake.presentationProofReturnsOnCall[len(fake.presentationProofArgsForCall)]
-	fake.presentationProofArgsForCall = append(fake.presentationProofArgsForCall, struct {
+func (fake *FakeSigner) CreatePresentation(arg1 context.Context, arg2 string, arg3 string, arg4 string, arg5 []map[string]interface{}) (map[string]interface{}, error) {
+	var arg5Copy []map[string]interface{}
+	if arg5 != nil {
+		arg5Copy = make([]map[string]interface{}, len(arg5))
+		copy(arg5Copy, arg5)
+	}
+	fake.createPresentationMutex.Lock()
+	ret, specificReturn := fake.createPresentationReturnsOnCall[len(fake.createPresentationArgsForCall)]
+	fake.createPresentationArgsForCall = append(fake.createPresentationArgsForCall, struct {
 		arg1 context.Context
-		arg2 *verifiable.Presentation
-	}{arg1, arg2})
-	stub := fake.PresentationProofStub
-	fakeReturns := fake.presentationProofReturns
-	fake.recordInvocation("PresentationProof", []interface{}{arg1, arg2})
-	fake.presentationProofMutex.Unlock()
+		arg2 string
+		arg3 string
+		arg4 string
+		arg5 []map[string]interface{}
+	}{arg1, arg2, arg3, arg4, arg5Copy})
+	stub := fake.CreatePresentationStub
+	fakeReturns := fake.createPresentationReturns
+	fake.recordInvocation("CreatePresentation", []interface{}{arg1, arg2, arg3, arg4, arg5Copy})
+	fake.createPresentationMutex.Unlock()
 	if stub != nil {
-		return stub(arg1, arg2)
+		return stub(arg1, arg2, arg3, arg4, arg5)
 	}
 	if specificReturn {
 		return ret.result1, ret.result2
@@ -60,47 +70,47 @@ func (fake *FakeSigner) PresentationProof(arg1 context.Context, arg2 *verifiable
 	return fakeReturns.result1, fakeReturns.result2
 }
 
-func (fake *FakeSigner) PresentationProofCallCount() int {
-	fake.presentationProofMutex.RLock()
-	defer fake.presentationProofMutex.RUnlock()
-	return len(fake.presentationProofArgsForCall)
+func (fake *FakeSigner) CreatePresentationCallCount() int {
+	fake.createPresentationMutex.RLock()
+	defer fake.createPresentationMutex.RUnlock()
+	return len(fake.createPresentationArgsForCall)
 }
 
-func (fake *FakeSigner) PresentationProofCalls(stub func(context.Context, *verifiable.Presentation) (*verifiable.Presentation, error)) {
-	fake.presentationProofMutex.Lock()
-	defer fake.presentationProofMutex.Unlock()
-	fake.PresentationProofStub = stub
+func (fake *FakeSigner) CreatePresentationCalls(stub func(context.Context, string, string, string, []map[string]interface{}) (map[string]interface{}, error)) {
+	fake.createPresentationMutex.Lock()
+	defer fake.createPresentationMutex.Unlock()
+	fake.CreatePresentationStub = stub
 }
 
-func (fake *FakeSigner) PresentationProofArgsForCall(i int) (context.Context, *verifiable.Presentation) {
-	fake.presentationProofMutex.RLock()
-	defer fake.presentationProofMutex.RUnlock()
-	argsForCall := fake.presentationProofArgsForCall[i]
-	return argsForCall.arg1, argsForCall.arg2
+func (fake *FakeSigner) CreatePresentationArgsForCall(i int) (context.Context, string, string, string, []map[string]interface{}) {
+	fake.createPresentationMutex.RLock()
+	defer fake.createPresentationMutex.RUnlock()
+	argsForCall := fake.createPresentationArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5
 }
 
-func (fake *FakeSigner) PresentationProofReturns(result1 *verifiable.Presentation, result2 error) {
-	fake.presentationProofMutex.Lock()
-	defer fake.presentationProofMutex.Unlock()
-	fake.PresentationProofStub = nil
-	fake.presentationProofReturns = struct {
-		result1 *verifiable.Presentation
+func (fake *FakeSigner) CreatePresentationReturns(result1 map[string]interface{}, result2 error) {
+	fake.createPresentationMutex.Lock()
+	defer fake.createPresentationMutex.Unlock()
+	fake.CreatePresentationStub = nil
+	fake.createPresentationReturns = struct {
+		result1 map[string]interface{}
 		result2 error
 	}{result1, result2}
 }
 
-func (fake *FakeSigner) PresentationProofReturnsOnCall(i int, result1 *verifiable.Presentation, result2 error) {
-	fake.presentationProofMutex.Lock()
-	defer fake.presentationProofMutex.Unlock()
-	fake.PresentationProofStub = nil
-	if fake.presentationProofReturnsOnCall == nil {
-		fake.presentationProofReturnsOnCall = make(map[int]struct {
-			result1 *verifiable.Presentation
+func (fake *FakeSigner) CreatePresentationReturnsOnCall(i int, result1 map[string]interface{}, result2 error) {
+	fake.createPresentationMutex.Lock()
+	defer fake.createPresentationMutex.Unlock()
+	fake.CreatePresentationStub = nil
+	if fake.createPresentationReturnsOnCall == nil {
+		fake.createPresentationReturnsOnCall = make(map[int]struct {
+			result1 map[string]interface{}
 			result2 error
 		})
 	}
-	fake.presentationProofReturnsOnCall[i] = struct {
-		result1 *verifiable.Presentation
+	fake.createPresentationReturnsOnCall[i] = struct {
+		result1 map[string]interface{}
 		result2 error
 	}{result1, result2}
 }
@@ -175,8 +185,8 @@ func (fake *FakeSigner) VerifyPresentationReturnsOnCall(i int, result1 error) {
 func (fake *FakeSigner) Invocations() map[string][][]interface{} {
 	fake.invocationsMutex.RLock()
 	defer fake.invocationsMutex.RUnlock()
-	fake.presentationProofMutex.RLock()
-	defer fake.presentationProofMutex.RUnlock()
+	fake.createPresentationMutex.RLock()
+	defer fake.createPresentationMutex.RUnlock()
 	fake.verifyPresentationMutex.RLock()
 	defer fake.verifyPresentationMutex.RUnlock()
 	copiedInvocations := map[string][][]interface{}{}
diff --git a/internal/service/infohub/service.go b/internal/service/infohub/service.go
index be44fc97cdec3da754f3c19bb049d41726858a71..56149b5457fe02a7d951250819694e80461aa90f 100644
--- a/internal/service/infohub/service.go
+++ b/internal/service/infohub/service.go
@@ -35,13 +35,11 @@ type Cache interface {
 }
 
 type Credentials interface {
-	NewCredential(contexts []string, subjectID string, subject map[string]interface{}, proof bool) (*verifiable.Credential, error)
-	NewPresentation(contexts []string, credentials ...*verifiable.Credential) (*verifiable.Presentation, error)
 	ParsePresentation(vpBytes []byte) (*verifiable.Presentation, error)
 }
 
 type Signer interface {
-	PresentationProof(ctx context.Context, vp *verifiable.Presentation) (*verifiable.Presentation, error)
+	CreatePresentation(ctx context.Context, issuer, namespace, key string, data []map[string]interface{}) (map[string]interface{}, error)
 	VerifyPresentation(ctx context.Context, vp []byte) error
 }
 
@@ -150,35 +148,26 @@ func (s *Service) Export(ctx context.Context, req *infohub.ExportRequest) (inter
 		return nil, err
 	}
 
-	// wrap each policy result in a verifiable credential
-	var creds []*verifiable.Credential
+	var results []map[string]interface{}
 	for policy, result := range policyResults {
 		var res map[string]interface{}
 		if err := json.Unmarshal(result, &res); err != nil {
-			logger.Error("error decoding policy result as json", zap.Error(err))
+			logger.Error("error decoding policy result as json", zap.Error(err), zap.String("policy", policy))
 			return nil, errors.New("error creating export", err)
 		}
-
-		// credentials do not include proof, because the final VP will include a proof for all
-		cred, err := s.credentials.NewCredential(exportCfg.Contexts, policy, res, false)
-		if err != nil {
-			logger.Error("failed to create verifiable credential", zap.Error(err))
-			return nil, errors.New("error creating export", err)
-		}
-		creds = append(creds, cred)
+		results = append(results, res)
 	}
 
-	// wrap all credentials in a verifiable presentation
-	vp, err := s.credentials.NewPresentation(exportCfg.Contexts, creds...)
-	if err != nil {
-		logger.Error("failed to create verifiable presentation", zap.Error(err))
-		return nil, errors.New("error creating export", err)
-	}
-
-	// get presentation proof from the signer
-	vp, err = s.signer.PresentationProof(ctx, vp)
+	// create verifiable presentation
+	vp, err := s.signer.CreatePresentation(
+		ctx,
+		exportCfg.Issuer,
+		exportCfg.KeyNamespace,
+		exportCfg.Key,
+		results,
+	)
 	if err != nil {
-		logger.Error("fail to get presentation proof", zap.Error(err))
+		logger.Error("error creating verifiable presentation", zap.Error(err))
 		return nil, errors.New("error creating export", err)
 	}
 
@@ -190,6 +179,8 @@ func (s *Service) Export(ctx context.Context, req *infohub.ExportRequest) (inter
 // is returned.
 // If all results are found, they are returned as map, where the key is policyName
 // and the value is the JSON serialized bytes of the policy result.
+//
+// policyNames are formatted as 'group/policy/version' string, e.g. 'example/example/1.0'
 func (s *Service) getExportData(ctx context.Context, exportName string, policyNames []string) (map[string][]byte, error) {
 	results := make(map[string][]byte)
 	for _, policy := range policyNames {
diff --git a/internal/service/infohub/service_test.go b/internal/service/infohub/service_test.go
index c585ea29797dd4d57b2bfa3c644085b5b16db801..b9ad07862eef5c60930c2e30b407cee59bf06b05 100644
--- a/internal/service/infohub/service_test.go
+++ b/internal/service/infohub/service_test.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"testing"
 
-	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
 	"github.com/stretchr/testify/assert"
 	"go.uber.org/zap"
 
@@ -173,7 +172,7 @@ func TestService_Export(t *testing.T) {
 			errtext: "error creating export: invalid character",
 		},
 		{
-			name: "error creating verifiable credential for data",
+			name: "error creating verifiable presentation",
 			req:  &goasigner.ExportRequest{ExportName: "testexport"},
 			storage: &infohubfakes.FakeStorage{
 				ExportConfigurationStub: func(ctx context.Context, s string) (*storage.ExportConfiguration, error) {
@@ -189,77 +188,16 @@ func TestService_Export(t *testing.T) {
 					return []byte(`{"allow":true}`), nil
 				},
 			},
-			cred: &infohubfakes.FakeCredentials{
-				NewCredentialStub: func(contexts []string, policy string, data map[string]interface{}, proof bool) (*verifiable.Credential, error) {
-					return nil, errors.New("cannot create credential")
-				},
-			},
-			errkind: errors.Unknown,
-			errtext: "cannot create credential",
-		},
-		{
-			name: "error creating verifiable presentation for data",
-			req:  &goasigner.ExportRequest{ExportName: "testexport"},
-			storage: &infohubfakes.FakeStorage{
-				ExportConfigurationStub: func(ctx context.Context, s string) (*storage.ExportConfiguration, error) {
-					return &storage.ExportConfiguration{
-						ExportName: "testexport",
-						Contexts:   []string{"https://www.w3.org/2018/credentials/examples/v1"},
-						Policies:   map[string]interface{}{"test/test/1.0": map[string]interface{}{"hello": "test world"}},
-					}, nil
-				},
-			},
-			cache: &infohubfakes.FakeCache{
-				GetStub: func(ctx context.Context, key string, namespace string, scope string) ([]byte, error) {
-					return []byte(`{"allow":true}`), nil
-				},
-			},
-			cred: &infohubfakes.FakeCredentials{
-				NewCredentialStub: func(contexts []string, policy string, data map[string]interface{}, proof bool) (*verifiable.Credential, error) {
-					return &verifiable.Credential{}, nil
-				},
-				NewPresentationStub: func(contexts []string, credentials ...*verifiable.Credential) (*verifiable.Presentation, error) {
-					return nil, errors.New("cannot create presentation")
-				},
-			},
-			errkind: errors.Unknown,
-			errtext: "cannot create presentation",
-		},
-		{
-			name: "error getting verifiable presentation proof",
-			req:  &goasigner.ExportRequest{ExportName: "testexport"},
-			storage: &infohubfakes.FakeStorage{
-				ExportConfigurationStub: func(ctx context.Context, s string) (*storage.ExportConfiguration, error) {
-					return &storage.ExportConfiguration{
-						ExportName: "testexport",
-						Contexts:   []string{"https://www.w3.org/2018/credentials/examples/v1"},
-						Policies:   map[string]interface{}{"test/test/1.0": map[string]interface{}{"hello": "test world"}},
-					}, nil
-				},
-			},
-			cache: &infohubfakes.FakeCache{
-				GetStub: func(ctx context.Context, key string, namespace string, scope string) ([]byte, error) {
-					return []byte(`{"allow":true}`), nil
-				},
-			},
-			cred: &infohubfakes.FakeCredentials{
-				NewCredentialStub: func(contexts []string, policy string, data map[string]interface{}, proof bool) (*verifiable.Credential, error) {
-					return &verifiable.Credential{}, nil
-				},
-				NewPresentationStub: func(contexts []string, credentials ...*verifiable.Credential) (*verifiable.Presentation, error) {
-					return &verifiable.Presentation{}, nil
-				},
-			},
 			signer: &infohubfakes.FakeSigner{
-				PresentationProofStub: func(ctx context.Context, presentation *verifiable.Presentation) (*verifiable.Presentation, error) {
-					return nil, errors.New(errors.ServiceUnavailable, "service unavailable")
+				CreatePresentationStub: func(ctx context.Context, issuer string, namespace string, key string, data []map[string]interface{}) (map[string]interface{}, error) {
+					return nil, errors.New("some error")
 				},
 			},
-			errkind: errors.ServiceUnavailable,
-			errtext: "service unavailable",
+			errkind: errors.Unknown,
+			errtext: "some error",
 		},
 		{
-			name: "exported data is returned successfully",
+			name: "successfully create verifiable presentation",
 			req:  &goasigner.ExportRequest{ExportName: "testexport"},
 			storage: &infohubfakes.FakeStorage{
 				ExportConfigurationStub: func(ctx context.Context, s string) (*storage.ExportConfiguration, error) {
@@ -275,20 +213,12 @@ func TestService_Export(t *testing.T) {
 					return []byte(`{"allow":true}`), nil
 				},
 			},
-			cred: &infohubfakes.FakeCredentials{
-				NewCredentialStub: func(contexts []string, policy string, data map[string]interface{}, proof bool) (*verifiable.Credential, error) {
-					return &verifiable.Credential{}, nil
-				},
-				NewPresentationStub: func(contexts []string, credentials ...*verifiable.Credential) (*verifiable.Presentation, error) {
-					return &verifiable.Presentation{}, nil
-				},
-			},
 			signer: &infohubfakes.FakeSigner{
-				PresentationProofStub: func(ctx context.Context, presentation *verifiable.Presentation) (*verifiable.Presentation, error) {
-					return &verifiable.Presentation{ID: "did:ocm"}, nil
+				CreatePresentationStub: func(ctx context.Context, issuer string, namespace string, key string, data []map[string]interface{}) (map[string]interface{}, error) {
+					return map[string]interface{}{"id": "did:web:example.com"}, nil
 				},
 			},
-			res: &verifiable.Presentation{ID: "did:ocm"},
+			res: map[string]interface{}{"id": "did:web:example.com"},
 		},
 	}
 
diff --git a/internal/storage/storage.go b/internal/storage/storage.go
index 5c6072c86f0ccafe31c50dd33ae993b2d9975fdc..c85b2af5a5faf87471ca880a7ee7a9d27a384247 100644
--- a/internal/storage/storage.go
+++ b/internal/storage/storage.go
@@ -12,10 +12,13 @@ import (
 )
 
 type ExportConfiguration struct {
-	ExportName string
-	Contexts   []string
-	Policies   map[string]interface{}
-	CacheTTL   *int
+	ExportName   string
+	Contexts     []string
+	Policies     map[string]interface{}
+	CacheTTL     *int
+	Issuer       string // issuer DID
+	KeyNamespace string // signing key namespace
+	Key          string // signing key name
 }
 
 type Storage struct {