diff --git a/remediation/workflow/hardenrunner/addaction.go b/remediation/workflow/hardenrunner/addaction.go
index e8afbf506..f35df4fd6 100644
--- a/remediation/workflow/hardenrunner/addaction.go
+++ b/remediation/workflow/hardenrunner/addaction.go
@@ -47,7 +47,8 @@ func AddAction(inputYaml, action string, pinActions, pinToImmutable bool) (strin
 	}
 
 	if updated && pinActions {
-		out, _ = pin.PinAction(action, out, nil, pinToImmutable)
+		immutableMap := pin.GetSemanticActionsImmutableMap([]string{action}, pinToImmutable)
+		out, _ = pin.PinAction(action, out, nil, immutableMap)
 	}
 
 	return out, updated, nil
diff --git a/remediation/workflow/pin/action_image_manifest.go b/remediation/workflow/pin/action_image_manifest.go
index 16e3a1ad8..2f52a6e5d 100644
--- a/remediation/workflow/pin/action_image_manifest.go
+++ b/remediation/workflow/pin/action_image_manifest.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"regexp"
 	"strings"
+	"sync"
 
 	"net/http"
 
@@ -22,6 +23,44 @@ type ociManifest struct {
 	ArtifactType string `json:"artifactType"`
 }
 
+// immutableResult holds the result for an image reference.
+type immutableResult struct {
+	action      string
+	isImmutable bool
+}
+
+// Run isImmutableAction concurrently for all the actions simultaneously
+// Individual runs takes up to 600 ms with concurrency it can be achieved under 1000 ms for all actions present
+func IsImmutableActionConcurrently(actions []string) map[string]bool {
+	var wg sync.WaitGroup
+	// Buffered channel to hold one result per image.
+	resultChan := make(chan immutableResult, len(actions))
+
+	for _, action := range actions {
+		wg.Add(1)
+		go func(a string) {
+			defer wg.Done()
+			isImmutable := IsImmutableAction(a)
+			resultChan <- immutableResult{
+				action:      a,
+				isImmutable: isImmutable,
+			}
+		}(action)
+	}
+
+	// Wait for all goroutines to finish.
+	wg.Wait()
+	close(resultChan)
+
+	// Collect the results.
+	results := make(map[string]bool)
+	for res := range resultChan {
+		results[res.action] = res.isImmutable
+	}
+
+	return results
+}
+
 // isImmutableAction checks if the action is an immutable action or not
 // It queries the OCI manifest for the action and checks if the artifact type is "application/vnd.github.actions.package.v1+json"
 //
diff --git a/remediation/workflow/pin/pinactions.go b/remediation/workflow/pin/pinactions.go
index 0b66e63ad..4a4ca8cc8 100644
--- a/remediation/workflow/pin/pinactions.go
+++ b/remediation/workflow/pin/pinactions.go
@@ -17,6 +17,7 @@ import (
 func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool) (string, bool, error) {
 	workflow := metadata.Workflow{}
 	updated := false
+	var allActions []string
 	err := yaml.Unmarshal([]byte(inputYaml), &workflow)
 	if err != nil {
 		return inputYaml, updated, fmt.Errorf("unable to parse yaml %v", err)
@@ -24,12 +25,24 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
 
 	out := inputYaml
 
+	// get all jobs present in the workflow
+	for _, job := range workflow.Jobs {
+		for _, step := range job.Steps {
+			if strings.Contains(step.Uses, "@") && !strings.HasPrefix(step.Uses, "docker://") && !isAbsolute(step.Uses) {
+				allActions = append(allActions, step.Uses)
+			}
+		}
+	}
+
+	// get immutable map for the semantic versions of the actions present in the workflow
+	immutableMap := GetSemanticActionsImmutableMap(allActions, pinToImmutable)
+
 	for _, job := range workflow.Jobs {
 
 		for _, step := range job.Steps {
 			if len(step.Uses) > 0 {
 				localUpdated := false
-				out, localUpdated = PinAction(step.Uses, out, exemptedActions, pinToImmutable)
+				out, localUpdated = PinAction(step.Uses, out, exemptedActions, immutableMap)
 				updated = updated || localUpdated
 			}
 		}
@@ -38,14 +51,15 @@ func PinActions(inputYaml string, exemptedActions []string, pinToImmutable bool)
 	return out, updated, nil
 }
 
-func PinAction(action, inputYaml string, exemptedActions []string, pinToImmutable bool) (string, bool) {
+func PinAction(action, inputYaml string, exemptedActions []string, immutableMap map[string]bool) (string, bool) {
 
 	updated := false
 	if !strings.Contains(action, "@") || strings.HasPrefix(action, "docker://") {
 		return inputYaml, updated // Cannot pin local actions and docker actions
 	}
 
-	if isAbsolute(action) || (pinToImmutable && IsImmutableAction(action)) {
+	// if already semantic than the action must be present in immutableMap
+	if isAbsolute(action) || immutableMap[action] {
 		return inputYaml, updated
 	}
 	leftOfAt := strings.Split(action, "@")
@@ -84,7 +98,8 @@ func PinAction(action, inputYaml string, exemptedActions []string, pinToImmutabl
 
 	// if the action with version is immutable, then pin the action with version instead of sha
 	pinnedActionWithVersion := fmt.Sprintf("%s@%s", leftOfAt[0], tagOrBranch)
-	if pinToImmutable && semanticTagRegex.MatchString(tagOrBranch) && IsImmutableAction(pinnedActionWithVersion) {
+	// if found update pinned action with immutable pinned version
+	if semanticTagRegex.MatchString(tagOrBranch) && immutableMap[pinnedActionWithVersion] {
 		pinnedAction = pinnedActionWithVersion
 	}
 
@@ -211,3 +226,49 @@ func ActionExists(actionName string, patterns []string) bool {
 	}
 	return false
 }
+
+func GetSemanticActionsImmutableMap(allActions []string, pinToImmutable bool) map[string]bool {
+	var allSemanticActions []string
+	immutableMap := make(map[string]bool)
+
+	// return if pinToImmutable is set to false
+	if !pinToImmutable {
+		return immutableMap
+	}
+
+	PAT := os.Getenv("PAT")
+
+	ctx := context.Background()
+	ts := oauth2.StaticTokenSource(
+		&oauth2.Token{AccessToken: PAT},
+	)
+	tc := oauth2.NewClient(ctx, ts)
+
+	client := github.NewClient(tc)
+
+	// get corresponding semantic actions for the actions present in the workflow
+	for _, action := range allActions {
+		leftOfAt := strings.Split(action, "@")
+		tagOrBranch := leftOfAt[1]
+
+		splitOnSlash := strings.Split(leftOfAt[0], "/")
+		owner := splitOnSlash[0]
+		repo := splitOnSlash[1]
+
+		commitSHA, _, err := client.Repositories.GetCommitSHA1(ctx, owner, repo, tagOrBranch, "")
+		if err != nil {
+			return immutableMap
+		}
+
+		tagOrBranch, err = getSemanticVersion(client, owner, repo, tagOrBranch, commitSHA)
+		if err != nil {
+			return immutableMap
+		}
+
+		pinnedActionWithSemanticVersion := fmt.Sprintf("%s@%s", leftOfAt[0], tagOrBranch)
+
+		allSemanticActions = append(allSemanticActions, pinnedActionWithSemanticVersion)
+	}
+
+	return IsImmutableActionConcurrently(allSemanticActions)
+}