diff --git a/cmd/frostfs-adm/internal/modules/morph/frostfsid.go b/cmd/frostfs-adm/internal/modules/morph/frostfsid.go
index 938fb1b67..2a6043b7c 100644
--- a/cmd/frostfs-adm/internal/modules/morph/frostfsid.go
+++ b/cmd/frostfs-adm/internal/modules/morph/frostfsid.go
@@ -28,6 +28,8 @@ const (
 	groupIDFlag        = "group-id"
 )
 
+const rootNamespacePlaceholder = "<root>"
+
 var (
 	frostfsidCmd = &cobra.Command{
 		Use:   "frostfsid",
@@ -220,7 +222,7 @@ func initFrostfsIDListGroupSubjectsCmd() {
 }
 
 func frostfsidCreateNamespace(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
+	ns := getFrostfsIDNamespace(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
@@ -241,13 +243,16 @@ func frostfsidListNamespaces(cmd *cobra.Command, _ []string) {
 	sort.Slice(namespaces, func(i, j int) bool { return namespaces[i].Name < namespaces[j].Name })
 
 	for _, namespace := range namespaces {
-		cmd.Printf("%q\n", namespace.Name)
+		if namespace.Name == "" {
+			namespace.Name = rootNamespacePlaceholder
+		}
+		cmd.Printf("%s\n", namespace.Name)
 	}
 }
 
 func frostfsidCreateSubject(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
-	subjName, _ := cmd.Flags().GetString(subjectNameFlag)
+	ns := getFrostfsIDNamespace(cmd)
+	subjName := getFrostfsIDSubjectName(cmd)
 	subjKey := getFrostfsIDSubjectKey(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
@@ -275,7 +280,7 @@ func frostfsidDeleteSubject(cmd *cobra.Command, _ []string) {
 }
 
 func frostfsidListSubjects(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
+	ns := getFrostfsIDNamespace(cmd)
 	includeNames, _ := cmd.Flags().GetBool(includeNamesFlag)
 
 	ffsid, err := newFrostfsIDClient(cmd)
@@ -300,8 +305,8 @@ func frostfsidListSubjects(cmd *cobra.Command, _ []string) {
 }
 
 func frostfsidCreateGroup(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
-	groupName, _ := cmd.Flags().GetString(groupNameFlag)
+	ns := getFrostfsIDNamespace(cmd)
+	groupName := getFrostfsIDGroupName(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
@@ -315,8 +320,8 @@ func frostfsidCreateGroup(cmd *cobra.Command, _ []string) {
 }
 
 func frostfsidDeleteGroup(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
-	groupID, _ := cmd.Flags().GetInt64(groupIDFlag)
+	ns := getFrostfsIDNamespace(cmd)
+	groupID := getFrostfsIDGroupID(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
@@ -328,7 +333,7 @@ func frostfsidDeleteGroup(cmd *cobra.Command, _ []string) {
 }
 
 func frostfsidListGroups(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
+	ns := getFrostfsIDNamespace(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract invoker: %w", err)
@@ -339,13 +344,13 @@ func frostfsidListGroups(cmd *cobra.Command, _ []string) {
 	sort.Slice(groups, func(i, j int) bool { return groups[i].Name < groups[j].Name })
 
 	for _, group := range groups {
-		cmd.Printf("%q (%d)\n", group.Name, group.ID)
+		cmd.Printf("%s (%d)\n", group.Name, group.ID)
 	}
 }
 
 func frostfsidAddSubjectToGroup(cmd *cobra.Command, _ []string) {
 	subjectAddress := getFrostfsIDSubjectAddress(cmd)
-	groupID, _ := cmd.Flags().GetInt64(groupIDFlag)
+	groupID := getFrostfsIDGroupID(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
@@ -358,7 +363,7 @@ func frostfsidAddSubjectToGroup(cmd *cobra.Command, _ []string) {
 
 func frostfsidRemoveSubjectFromGroup(cmd *cobra.Command, _ []string) {
 	subjectAddress := getFrostfsIDSubjectAddress(cmd)
-	groupID, _ := cmd.Flags().GetInt64(groupIDFlag)
+	groupID := getFrostfsIDGroupID(cmd)
 
 	ffsid, err := newFrostfsIDClient(cmd)
 	commonCmd.ExitOnErr(cmd, "init contract client: %w", err)
@@ -370,8 +375,8 @@ func frostfsidRemoveSubjectFromGroup(cmd *cobra.Command, _ []string) {
 }
 
 func frostfsidListGroupSubjects(cmd *cobra.Command, _ []string) {
-	ns, _ := cmd.Flags().GetString(namespaceFlag)
-	groupID, _ := cmd.Flags().GetInt64(groupIDFlag)
+	ns := getFrostfsIDNamespace(cmd)
+	groupID := getFrostfsIDGroupID(cmd)
 	includeNames, _ := cmd.Flags().GetBool(includeNamesFlag)
 
 	ffsid, err := newFrostfsIDClient(cmd)
diff --git a/cmd/frostfs-adm/internal/modules/morph/frostfsid_util.go b/cmd/frostfs-adm/internal/modules/morph/frostfsid_util.go
index dc7e581eb..f88e4edfb 100644
--- a/cmd/frostfs-adm/internal/modules/morph/frostfsid_util.go
+++ b/cmd/frostfs-adm/internal/modules/morph/frostfsid_util.go
@@ -1,7 +1,9 @@
 package morph
 
 import (
+	"errors"
 	"fmt"
+	"regexp"
 
 	commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
 	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@@ -11,6 +13,14 @@ import (
 	"github.com/spf13/viper"
 )
 
+var (
+	frostfsidSubjectNameRegexp = regexp.MustCompile(`^[\w+=,.@-]{1,64}$`)
+	frostfsidGroupNameRegexp   = regexp.MustCompile(`^[\w+=,.@-]{1,128}$`)
+
+	// frostfsidNamespaceNameRegexp similar to https://git.frostfs.info/TrueCloudLab/frostfs-contract/src/commit/f2a82aa635aa57d9b05092d8cf15b170b53cc324/nns/nns_contract.go#L690
+	frostfsidNamespaceNameRegexp = regexp.MustCompile(`(^$)|(^[a-z0-9]{1,2}$)|(^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$)`)
+)
+
 func getFrostfsIDAdmin(v *viper.Viper) (util.Uint160, bool, error) {
 	admin := v.GetString(frostfsIDAdminConfigKey)
 	if admin == "" {
@@ -47,3 +57,53 @@ func getFrostfsIDSubjectAddress(cmd *cobra.Command) util.Uint160 {
 	commonCmd.ExitOnErr(cmd, "invalid subject address: %w", err)
 	return subjAddr
 }
+
+func getFrostfsIDSubjectName(cmd *cobra.Command) string {
+	subjectName, _ := cmd.Flags().GetString(subjectNameFlag)
+
+	if subjectName == "" {
+		return ""
+	}
+
+	if !frostfsidSubjectNameRegexp.MatchString(subjectName) {
+		commonCmd.ExitOnErr(cmd, "invalid subject name: %w",
+			fmt.Errorf("name must match regexp: %s", frostfsidSubjectNameRegexp.String()))
+	}
+
+	return subjectName
+}
+
+func getFrostfsIDGroupName(cmd *cobra.Command) string {
+	groupName, _ := cmd.Flags().GetString(groupNameFlag)
+
+	if !frostfsidGroupNameRegexp.MatchString(groupName) {
+		commonCmd.ExitOnErr(cmd, "invalid group name: %w",
+			fmt.Errorf("name must match regexp: %s", frostfsidGroupNameRegexp.String()))
+	}
+
+	return groupName
+}
+
+func getFrostfsIDGroupID(cmd *cobra.Command) int64 {
+	groupID, _ := cmd.Flags().GetInt64(groupIDFlag)
+	if groupID <= 0 {
+		commonCmd.ExitOnErr(cmd, "invalid group id: %w",
+			errors.New("group id must be positive integer"))
+	}
+
+	return groupID
+}
+
+func getFrostfsIDNamespace(cmd *cobra.Command) string {
+	ns, _ := cmd.Flags().GetString(namespaceFlag)
+	if ns == rootNamespacePlaceholder {
+		ns = ""
+	}
+
+	if !frostfsidNamespaceNameRegexp.MatchString(ns) {
+		commonCmd.ExitOnErr(cmd, "invalid namespace: %w",
+			fmt.Errorf("name must match regexp: %s", frostfsidNamespaceNameRegexp.String()))
+	}
+
+	return ns
+}
diff --git a/cmd/frostfs-adm/internal/modules/morph/frostfsid_util_test.go b/cmd/frostfs-adm/internal/modules/morph/frostfsid_util_test.go
index 192dc9f12..f73ebad08 100644
--- a/cmd/frostfs-adm/internal/modules/morph/frostfsid_util_test.go
+++ b/cmd/frostfs-adm/internal/modules/morph/frostfsid_util_test.go
@@ -51,3 +51,122 @@ func TestFrostfsIDConfig(t *testing.T) {
 		require.False(t, found)
 	})
 }
+
+func TestNamespaceRegexp(t *testing.T) {
+	for _, tc := range []struct {
+		name      string
+		namespace string
+		matched   bool
+	}{
+		{
+			name:      "root empty ns",
+			namespace: "",
+			matched:   true,
+		},
+		{
+			name:      "simple valid ns",
+			namespace: "my-namespace-123",
+			matched:   true,
+		},
+		{
+			name:      "root placeholder",
+			namespace: "<root>",
+			matched:   false,
+		},
+		{
+			name:      "too long",
+			namespace: "abcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyz",
+			matched:   false,
+		},
+		{
+			name:      "start with hyphen",
+			namespace: "-ns",
+			matched:   false,
+		},
+		{
+			name:      "end with hyphen",
+			namespace: "ns-",
+			matched:   false,
+		},
+		{
+			name:      "with spaces",
+			namespace: "ns ns",
+			matched:   false,
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			require.Equal(t, tc.matched, frostfsidNamespaceNameRegexp.MatchString(tc.namespace))
+		})
+	}
+}
+
+func TestSubjectNameRegexp(t *testing.T) {
+	for _, tc := range []struct {
+		name    string
+		subject string
+		matched bool
+	}{
+		{
+			name:    "empty",
+			subject: "",
+			matched: false,
+		},
+		{
+			name:    "invalid",
+			subject: "invalid{name}",
+			matched: false,
+		},
+		{
+			name:    "too long",
+			subject: "abcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyz",
+			matched: false,
+		},
+		{
+			name:    "valid",
+			subject: "valid_name.012345@6789",
+			matched: true,
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			require.Equal(t, tc.matched, frostfsidSubjectNameRegexp.MatchString(tc.subject))
+		})
+	}
+}
+
+func TestSubjectGroupRegexp(t *testing.T) {
+	for _, tc := range []struct {
+		name    string
+		subject string
+		matched bool
+	}{
+		{
+			name:    "empty",
+			subject: "",
+			matched: false,
+		},
+		{
+			name:    "invalid",
+			subject: "invalid{name}",
+			matched: false,
+		},
+		{
+			name:    "too long",
+			subject: "abcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyz",
+			matched: false,
+		},
+		{
+			name:    "long",
+			subject: "abcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyzabcdefghijklmnopkrstuvwxyz",
+			matched: true,
+		},
+		{
+			name:    "valid",
+			subject: "valid_name.012345@6789",
+			matched: true,
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			require.Equal(t, tc.matched, frostfsidGroupNameRegexp.MatchString(tc.subject))
+		})
+	}
+}