diff --git a/modules/structs/secret.go b/modules/structs/secret.go
index 6a41db4cd..c707eb227 100644
--- a/modules/structs/secret.go
+++ b/modules/structs/secret.go
@@ -5,7 +5,7 @@ package structs
 
 import "time"
 
-// User represents a secret
+// Secret represents a secret
 // swagger:model
 type Secret struct {
 	// the secret's name
@@ -13,3 +13,15 @@ type Secret struct {
 	// swagger:strfmt date-time
 	Created time.Time `json:"created_at"`
 }
+
+// CreateSecretOption options when creating secret
+// swagger:model
+type CreateSecretOption struct {
+	// Name of the secret to create
+	//
+	// required: true
+	// unique: true
+	Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"`
+	// Data of the secret to create
+	Data string `json:"data" binding:"Required"`
+}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index ccae83a94..9613bd610 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -1300,6 +1300,7 @@ func Routes() *web.Route {
 			})
 			m.Group("/actions/secrets", func() {
 				m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets)
+				m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateSecretOption{}), org.CreateOrgSecret)
 			})
 			m.Group("/public_members", func() {
 				m.Get("", org.ListPublicMembers)
diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go
index 9deda2209..765919194 100644
--- a/routers/api/v1/org/action.go
+++ b/routers/api/v1/org/action.go
@@ -6,10 +6,13 @@ package org
 import (
 	"net/http"
 
-	"code.gitea.io/gitea/models/secret"
+	secret_model "code.gitea.io/gitea/models/secret"
 	"code.gitea.io/gitea/modules/context"
 	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/web"
 	"code.gitea.io/gitea/routers/api/v1/utils"
+	"code.gitea.io/gitea/routers/web/shared/actions"
+	"code.gitea.io/gitea/services/convert"
 )
 
 // ListActionsSecrets list an organization's actions secrets
@@ -42,18 +45,18 @@ func ListActionsSecrets(ctx *context.APIContext) {
 
 // listActionsSecrets list an organization's actions secrets
 func listActionsSecrets(ctx *context.APIContext) {
-	opts := &secret.FindSecretsOptions{
+	opts := &secret_model.FindSecretsOptions{
 		OwnerID:     ctx.Org.Organization.ID,
 		ListOptions: utils.GetListOptions(ctx),
 	}
 
-	count, err := secret.CountSecrets(ctx, opts)
+	count, err := secret_model.CountSecrets(ctx, opts)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
 	}
 
-	secrets, err := secret.FindSecrets(ctx, *opts)
+	secrets, err := secret_model.FindSecrets(ctx, *opts)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
@@ -70,3 +73,43 @@ func listActionsSecrets(ctx *context.APIContext) {
 	ctx.SetTotalCountHeader(count)
 	ctx.JSON(http.StatusOK, apiSecrets)
 }
+
+// CreateOrgSecret create one secret of the organization
+func CreateOrgSecret(ctx *context.APIContext) {
+	// swagger:operation POST /orgs/{org}/actions/secrets organization createOrgSecret
+	// ---
+	// summary: Create a secret in an organization
+	// consumes:
+	// - application/json
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: org
+	//   in: path
+	//   description: name of organization
+	//   type: string
+	//   required: true
+	// - name: body
+	//   in: body
+	//   schema:
+	//     "$ref": "#/definitions/CreateSecretOption"
+	// responses:
+	//   "201":
+	//     "$ref": "#/responses/Secret"
+	//   "400":
+	//     "$ref": "#/responses/error"
+	//   "404":
+	//     "$ref": "#/responses/notFound"
+	//   "403":
+	//     "$ref": "#/responses/forbidden"
+	opt := web.GetForm(ctx).(*api.CreateSecretOption)
+	s, err := secret_model.InsertEncryptedSecret(
+		ctx, ctx.Org.Organization.ID, 0, opt.Name, actions.ReserveLineBreakForTextarea(opt.Data),
+	)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "InsertEncryptedSecret", err)
+		return
+	}
+
+	ctx.JSON(http.StatusCreated, convert.ToSecret(s))
+}
diff --git a/routers/api/v1/swagger/action.go b/routers/api/v1/swagger/action.go
index 493b167f7..377178071 100644
--- a/routers/api/v1/swagger/action.go
+++ b/routers/api/v1/swagger/action.go
@@ -11,3 +11,10 @@ type swaggerResponseSecretList struct {
 	// in:body
 	Body []api.Secret `json:"body"`
 }
+
+// Secret
+// swagger:response Secret
+type swaggerResponseSecret struct {
+	// in:body
+	Body api.Secret `json:"body"`
+}
diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go
index 073d9a19f..8e7e6ec3d 100644
--- a/routers/api/v1/swagger/options.go
+++ b/routers/api/v1/swagger/options.go
@@ -187,4 +187,7 @@ type swaggerParameterBodies struct {
 
 	// in:body
 	UpdateRepoAvatarOptions api.UpdateRepoAvatarOption
+
+	// in:body
+	CreateSecretOption api.CreateSecretOption
 }
diff --git a/services/convert/secret.go b/services/convert/secret.go
new file mode 100644
index 000000000..dd7b9f0a6
--- /dev/null
+++ b/services/convert/secret.go
@@ -0,0 +1,18 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package convert
+
+import (
+	secret_model "code.gitea.io/gitea/models/secret"
+	api "code.gitea.io/gitea/modules/structs"
+)
+
+// ToSecret converts Secret to API format
+func ToSecret(secret *secret_model.Secret) *api.Secret {
+	result := &api.Secret{
+		Name: secret.Name,
+	}
+
+	return result
+}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 734a73bc0..5e75f6f8b 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -1586,6 +1586,49 @@
             "$ref": "#/responses/SecretList"
           }
         }
+      },
+      "post": {
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "organization"
+        ],
+        "summary": "Create a secret in an organization",
+        "operationId": "createOrgSecret",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "name of organization",
+            "name": "org",
+            "in": "path",
+            "required": true
+          },
+          {
+            "name": "body",
+            "in": "body",
+            "schema": {
+              "$ref": "#/definitions/CreateSecretOption"
+            }
+          }
+        ],
+        "responses": {
+          "201": {
+            "$ref": "#/responses/Secret"
+          },
+          "400": {
+            "$ref": "#/responses/error"
+          },
+          "403": {
+            "$ref": "#/responses/forbidden"
+          },
+          "404": {
+            "$ref": "#/responses/notFound"
+          }
+        }
       }
     },
     "/orgs/{org}/activities/feeds": {
@@ -17443,6 +17486,27 @@
       },
       "x-go-package": "code.gitea.io/gitea/modules/structs"
     },
+    "CreateSecretOption": {
+      "description": "CreateSecretOption options when creating secret",
+      "type": "object",
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "data": {
+          "description": "Data of the secret to create",
+          "type": "string",
+          "x-go-name": "Data"
+        },
+        "name": {
+          "description": "Name of the secret to create",
+          "type": "string",
+          "uniqueItems": true,
+          "x-go-name": "Name"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
     "CreateStatusOption": {
       "description": "CreateStatusOption holds the information needed to create a new CommitStatus for a Commit",
       "type": "object",
@@ -21334,7 +21398,7 @@
       "x-go-package": "code.gitea.io/gitea/modules/structs"
     },
     "Secret": {
-      "description": "User represents a secret",
+      "description": "Secret represents a secret",
       "type": "object",
       "properties": {
         "created_at": {
@@ -22921,6 +22985,12 @@
         "$ref": "#/definitions/SearchResults"
       }
     },
+    "Secret": {
+      "description": "Secret",
+      "schema": {
+        "$ref": "#/definitions/Secret"
+      }
+    },
     "SecretList": {
       "description": "SecretList",
       "schema": {
@@ -23137,7 +23207,7 @@
     "parameterBodies": {
       "description": "parameterBodies",
       "schema": {
-        "$ref": "#/definitions/UpdateRepoAvatarOption"
+        "$ref": "#/definitions/CreateSecretOption"
       }
     },
     "redirect": {