diff --git a/bridge/core/token.go b/bridge/core/token.go
index 186b9ff49c7688c7f2e49249c0b83e2452d05f37..28c64f5c4f9ea5edc7fee5fb8f7d01463e58923a 100644
--- a/bridge/core/token.go
+++ b/bridge/core/token.go
@@ -237,12 +237,12 @@ func TokenExist(repo repository.RepoCommon, value string) bool {
 
 // TokenExistWithTarget same as TokenExist but restrict search for a given target
 func TokenExistWithTarget(repo repository.RepoCommon, value string, target string) bool {
-	tokens, err := LoadTokens(repo)
+	tokens, err := LoadTokensWithTarget(repo, target)
 	if err != nil {
 		return false
 	}
 	for _, token := range tokens {
-		if token.Value == value && token.Target == target {
+		if token.Value == value {
 			return true
 		}
 	}
diff --git a/bridge/gitlab/config.go b/bridge/gitlab/config.go
index f2e667a85ea84f39ed131e799fe3cc7eb8092e89..88ba7db85f409ca5165ea8513fe343a10bec87d8 100644
--- a/bridge/gitlab/config.go
+++ b/bridge/gitlab/config.go
@@ -13,6 +13,7 @@ import (
 	"github.com/xanzy/go-gitlab"
 
 	"github.com/MichaelMure/git-bug/bridge/core"
+	"github.com/MichaelMure/git-bug/entity"
 	"github.com/MichaelMure/git-bug/repository"
 )
 
@@ -32,6 +33,8 @@ func (g *Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams)
 	var err error
 	var url string
 	var token string
+	var tokenId entity.Id
+	var tokenObj *core.Token
 
 	if (params.Token != "" || params.TokenStdin) && params.URL == "" {
 		return nil, fmt.Errorf("you must provide a project URL to configure this bridge with a token")
@@ -65,21 +68,38 @@ func (g *Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams)
 			return nil, fmt.Errorf("reading from stdin: %v", err)
 		}
 		token = strings.TrimSuffix(token, "\n")
+	} else if params.TokenId != "" {
+		tokenId = entity.Id(params.TokenId)
 	} else {
-		token, err = promptToken()
+		tokenObj, err = promptTokenOptions(repo)
 		if err != nil {
 			return nil, errors.Wrap(err, "token prompt")
 		}
 	}
 
+	if token != "" {
+		tokenObj, err = core.LoadOrCreateToken(repo, target, token)
+		if err != nil {
+			return nil, err
+		}
+	} else if tokenId != "" {
+		tokenObj, err = core.LoadToken(repo, entity.Id(tokenId))
+		if err != nil {
+			return nil, err
+		}
+		if tokenObj.Target != target {
+			return nil, fmt.Errorf("token target is incompatible %s", tokenObj.Target)
+		}
+	}
+
 	// validate project url and get its ID
-	id, err := validateProjectURL(url, token)
+	id, err := validateProjectURL(url, tokenObj.Value)
 	if err != nil {
 		return nil, errors.Wrap(err, "project validation")
 	}
 
 	conf[keyProjectID] = strconv.Itoa(id)
-	conf[keyToken] = token
+	conf[core.ConfigKeyTokenId] = tokenObj.ID().String()
 	conf[core.ConfigKeyTarget] = target
 
 	err = g.ValidateConfig(conf)
@@ -108,6 +128,54 @@ func (g *Gitlab) ValidateConfig(conf core.Configuration) error {
 	return nil
 }
 
+func promptTokenOptions(repo repository.RepoCommon) (*core.Token, error) {
+	for {
+		tokens, err := core.LoadTokensWithTarget(repo, target)
+		if err != nil {
+			return nil, err
+		}
+
+		fmt.Println()
+		fmt.Println("[1]: user provided token")
+
+		if len(tokens) > 0 {
+			fmt.Println("known tokens for Gitlab:")
+			for i, token := range tokens {
+				if token.Target == target {
+					fmt.Printf("[%d]: %s\n", i+2, token.ID())
+				}
+			}
+		}
+		fmt.Print("Select option: ")
+
+		line, err := bufio.NewReader(os.Stdin).ReadString('\n')
+		fmt.Println()
+		if err != nil {
+			return nil, err
+		}
+
+		line = strings.TrimRight(line, "\n")
+		index, err := strconv.Atoi(line)
+		if err != nil || index < 1 || index > len(tokens)+1 {
+			fmt.Println("invalid input")
+			continue
+		}
+
+		var token string
+		switch index {
+		case 1:
+			token, err = promptToken()
+			if err != nil {
+				return nil, err
+			}
+		default:
+			return tokens[index-2], nil
+		}
+
+		return core.LoadOrCreateToken(repo, target, token)
+	}
+}
+
 func promptToken() (string, error) {
 	fmt.Println("You can generate a new token by visiting https://gitlab.com/profile/personal_access_tokens.")
 	fmt.Println("Choose 'Create personal access token' and set the necessary access scope for your repository.")
diff --git a/bridge/gitlab/export.go b/bridge/gitlab/export.go
index 7c00e39de58b1fdc28b0d186985728509b6dff24..092434a5e73e7808f81c39151b765f9fc5135b23 100644
--- a/bridge/gitlab/export.go
+++ b/bridge/gitlab/export.go
@@ -79,7 +79,7 @@ func (ge *gitlabExporter) ExportAll(ctx context.Context, repo *cache.RepoCache,
 		return nil, err
 	}
 
-	ge.identityToken[user.Id().String()] = ge.conf[keyToken]
+	ge.identityToken[user.Id().String()] = ge.conf[core.ConfigKeyToken]
 
 	// get repository node id
 	ge.repositoryID = ge.conf[keyProjectID]
diff --git a/bridge/gitlab/import.go b/bridge/gitlab/import.go
index 92e9952ec52fe5f80655744514b709521688887b..4fcf8568ffbdb73a1d7f7dc61a1e58a35def2a54 100644
--- a/bridge/gitlab/import.go
+++ b/bridge/gitlab/import.go
@@ -34,7 +34,7 @@ func (gi *gitlabImporter) Init(conf core.Configuration) error {
 // ImportAll iterate over all the configured repository issues (notes) and ensure the creation
 // of the missing issues / comments / label events / title changes ...
 func (gi *gitlabImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan core.ImportResult, error) {
-	gi.iterator = NewIterator(ctx, 10, gi.conf[keyProjectID], gi.conf[keyToken], since)
+	gi.iterator = NewIterator(ctx, 10, gi.conf[keyProjectID], gi.conf[core.ConfigKeyToken], since)
 	out := make(chan core.ImportResult)
 	gi.out = out