[PR #3531] [MERGED] Implements generator cli for secrets #16977

Closed
opened 2025-11-02 12:23:25 -06:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/go-gitea/gitea/pull/3531
Author: @sdwolfz
Created: 2/18/2018
Status: Merged
Merged: 2/18/2018
Merged by: @lafriks

Base: masterHead: feature/generator-cli


📝 Commits (1)

  • 0a34245 Implements generator cli for secrets

📊 Changes

12 files changed (+215 additions, -67 deletions)

View changed files

cmd/generate.go (+83 -0)
📝 main.go (+1 -0)
📝 models/migrations/migrations.go (+3 -3)
📝 models/twofactor.go (+2 -2)
📝 models/user.go (+2 -1)
📝 modules/base/tool.go (+0 -29)
📝 modules/base/tool_test.go (+0 -6)
modules/generate/generate.go (+89 -0)
modules/generate/generate_test.go (+20 -0)
📝 modules/setting/setting.go (+5 -23)
📝 routers/install.go (+8 -2)
📝 routers/user/auth_openid.go (+2 -1)

📄 Description

Adds CLI subcommands for generating secrets.

This was inspired by a simmilar command available in Ruby on Rails: rails secret which generates a new value for SECRET_KEY_BASE, used to encrypt cookies.

To use this you execute the following commands:

./gitea generate secret INTERNAL_TOKEN
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1MTg5Njk4Njd9.X7-Qt89vFqLD1iS1UtAdGuVwvI7pz9n5EdqDuaHRNlI
./gitea generate secret LFS_JWT_SECRET
# SVxQQXbDGDqicXJoy9ygiHQKg6A79lTIuWoh_KfzPTI
./gitea generate secret SECRET_KEY
# FOQ5XMfOHo2GUc0FcnPJzf7MCvfUbqqkhkK1fJjXCx8UT1jYAxE2bIigI392j40x

I also modified the length of SECRET_KEY from 10 to 64 since it felt kind of short comapred to the rest.

The main use case for this would be an automated setup which has app.ini as a template and the values for INTERNAL_TOKEN, LFS_JWT_SECRET, and SECRET_KEY would be generated by the CLI commands, then added to the template. This would ensure no secrets would need to be hardcoded, and since they are generated by the same functions used in the /install endpoint, they will be consistent.

Here is an example of such automated setup I developed this for (just to give you an idea of how I intend this to be used):

An ansible role that generates the ini file:

- name: Generate postgres password
  shell: 'cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w ${1:-32} | head -n 1'
  register: new_postgres_password

- name: Generate internal token
  shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret INTERNAL_TOKEN | tail -n 1'
  register: new_internal_token

- name: Generate LFS JWT secret
  shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret LFS_JWT_SECRET | tail -n 1'
  register: new_lfs_jwt_secret

- name: Generate secret key
  shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret SECRET_KEY | tail -n 1'
  register: new_secret_key

- name: Create the app.ini file from the template
  template:
    src: '{{ project_repo }}/secrets/templates/app.ini.j2'
    dest: '{{ project_repo }}/secrets/app.ini'
  vars:
    postgres_password: '{{ new_postgres_password.stdout }}'
    internal_token: '{{ new_internal_token.stdout }}'
    lfs_jwt_secret: '{{ new_lfs_jwt_secret.stdout }}'
    secret_key: '{{ new_secret_key.stdout }}'

And the ini file template:

APP_NAME = Gitea: Git with a cup of tea
RUN_USER = git
RUN_MODE = prod

[security]
INTERNAL_TOKEN = {{ internal_token }}
INSTALL_LOCK   = true
SECRET_KEY     = {{ secret_key }}

[database]
DB_TYPE  = postgres
HOST     = postgres:5432
NAME     = gitea
USER     = postgres
PASSWD   = {{ postgres_password }}
SSL_MODE = disable
PATH     = /work/data/gitea.db

[repository]
ROOT          = /work/repos
FORCE_PRIVATE = true

[server]
SSH_DOMAIN       = gitea.local
DOMAIN           = gitea.local
HTTP_PORT        = 3000
ROOT_URL         = http://gitea.local:3000/
DISABLE_SSH      = false
SSH_PORT         = 22
START_SSH_SERVER = true
LFS_START_SERVER = true
LFS_CONTENT_PATH = /work/data/lfs
LFS_JWT_SECRET   = {{ lfs_jwt_secret }}
OFFLINE_MODE     = true

[mailer]
ENABLED = false

[markdown]
ENABLE_HARD_LINE_BREAK = true

[service]
REGISTER_EMAIL_CONFIRM            = false
ENABLE_NOTIFY_MAIL                = false
DISABLE_REGISTRATION              = true
ENABLE_CAPTCHA                    = false
REQUIRE_SIGNIN_VIEW               = true
DEFAULT_KEEP_EMAIL_PRIVATE        = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = false
DEFAULT_ENABLE_TIMETRACKING       = false
NO_REPLY_ADDRESS                  = noreply.gitea.local

[picture]
DISABLE_GRAVATAR        = true
ENABLE_FEDERATED_AVATAR = false

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[session]
PROVIDER = file

[log]
MODE      = console,file
LEVEL     = Info
ROOT_PATH = /work/log

About the implementation:

  • I extracted the generation logic into it's own package and reuse the same functions as part of the generate CLI subcommand and as part of the install setup.
  • Existing functionality is the same, except for the length of SECRET_KEY which I feel it's better to be longer.
  • This is the first (non trivial) golang code I've ever written so please let me know if I've made any mistakes.
  • I am not sure how to write tests for all this yet.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/go-gitea/gitea/pull/3531 **Author:** [@sdwolfz](https://github.com/sdwolfz) **Created:** 2/18/2018 **Status:** ✅ Merged **Merged:** 2/18/2018 **Merged by:** [@lafriks](https://github.com/lafriks) **Base:** `master` ← **Head:** `feature/generator-cli` --- ### 📝 Commits (1) - [`0a34245`](https://github.com/go-gitea/gitea/commit/0a3424516cb4aa84beb26d632531af9cf0d089a0) Implements generator cli for secrets ### 📊 Changes **12 files changed** (+215 additions, -67 deletions) <details> <summary>View changed files</summary> ➕ `cmd/generate.go` (+83 -0) 📝 `main.go` (+1 -0) 📝 `models/migrations/migrations.go` (+3 -3) 📝 `models/twofactor.go` (+2 -2) 📝 `models/user.go` (+2 -1) 📝 `modules/base/tool.go` (+0 -29) 📝 `modules/base/tool_test.go` (+0 -6) ➕ `modules/generate/generate.go` (+89 -0) ➕ `modules/generate/generate_test.go` (+20 -0) 📝 `modules/setting/setting.go` (+5 -23) 📝 `routers/install.go` (+8 -2) 📝 `routers/user/auth_openid.go` (+2 -1) </details> ### 📄 Description Adds CLI subcommands for generating secrets. This was inspired by a simmilar command available in Ruby on Rails: `rails secret` which generates a new value for `SECRET_KEY_BASE`, used to encrypt cookies. To use this you execute the following commands: ```bash ./gitea generate secret INTERNAL_TOKEN # eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1MTg5Njk4Njd9.X7-Qt89vFqLD1iS1UtAdGuVwvI7pz9n5EdqDuaHRNlI ./gitea generate secret LFS_JWT_SECRET # SVxQQXbDGDqicXJoy9ygiHQKg6A79lTIuWoh_KfzPTI ./gitea generate secret SECRET_KEY # FOQ5XMfOHo2GUc0FcnPJzf7MCvfUbqqkhkK1fJjXCx8UT1jYAxE2bIigI392j40x ``` I also modified the length of `SECRET_KEY` from `10` to `64` since it felt kind of short comapred to the rest. The main use case for this would be an automated setup which has `app.ini` as a template and the values for `INTERNAL_TOKEN`, `LFS_JWT_SECRET`, and `SECRET_KEY` would be generated by the CLI commands, then added to the template. This would ensure no secrets would need to be hardcoded, and since they are generated by the same functions used in the `/install` endpoint, they will be consistent. Here is an example of such automated setup I developed this for (just to give you an idea of how I intend this to be used): An ansible role that generates the ini file: ```yaml - name: Generate postgres password shell: 'cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w ${1:-32} | head -n 1' register: new_postgres_password - name: Generate internal token shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret INTERNAL_TOKEN | tail -n 1' register: new_internal_token - name: Generate LFS JWT secret shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret LFS_JWT_SECRET | tail -n 1' register: new_lfs_jwt_secret - name: Generate secret key shell: 'docker run --rm {{ project_name }}_web /work/gitea generate secret SECRET_KEY | tail -n 1' register: new_secret_key - name: Create the app.ini file from the template template: src: '{{ project_repo }}/secrets/templates/app.ini.j2' dest: '{{ project_repo }}/secrets/app.ini' vars: postgres_password: '{{ new_postgres_password.stdout }}' internal_token: '{{ new_internal_token.stdout }}' lfs_jwt_secret: '{{ new_lfs_jwt_secret.stdout }}' secret_key: '{{ new_secret_key.stdout }}' ``` And the ini file template: ```ini APP_NAME = Gitea: Git with a cup of tea RUN_USER = git RUN_MODE = prod [security] INTERNAL_TOKEN = {{ internal_token }} INSTALL_LOCK = true SECRET_KEY = {{ secret_key }} [database] DB_TYPE = postgres HOST = postgres:5432 NAME = gitea USER = postgres PASSWD = {{ postgres_password }} SSL_MODE = disable PATH = /work/data/gitea.db [repository] ROOT = /work/repos FORCE_PRIVATE = true [server] SSH_DOMAIN = gitea.local DOMAIN = gitea.local HTTP_PORT = 3000 ROOT_URL = http://gitea.local:3000/ DISABLE_SSH = false SSH_PORT = 22 START_SSH_SERVER = true LFS_START_SERVER = true LFS_CONTENT_PATH = /work/data/lfs LFS_JWT_SECRET = {{ lfs_jwt_secret }} OFFLINE_MODE = true [mailer] ENABLED = false [markdown] ENABLE_HARD_LINE_BREAK = true [service] REGISTER_EMAIL_CONFIRM = false ENABLE_NOTIFY_MAIL = false DISABLE_REGISTRATION = true ENABLE_CAPTCHA = false REQUIRE_SIGNIN_VIEW = true DEFAULT_KEEP_EMAIL_PRIVATE = true DEFAULT_ALLOW_CREATE_ORGANIZATION = false DEFAULT_ENABLE_TIMETRACKING = false NO_REPLY_ADDRESS = noreply.gitea.local [picture] DISABLE_GRAVATAR = true ENABLE_FEDERATED_AVATAR = false [openid] ENABLE_OPENID_SIGNIN = false ENABLE_OPENID_SIGNUP = false [session] PROVIDER = file [log] MODE = console,file LEVEL = Info ROOT_PATH = /work/log ``` About the implementation: - I extracted the generation logic into it's own package and reuse the same functions as part of the `generate` CLI subcommand and as part of the install setup. - Existing functionality is the same, except for the length of `SECRET_KEY` which I feel it's better to be longer. - This is the first (non trivial) golang code I've ever written so please let me know if I've made any mistakes. - I am not sure how to write tests for all this yet. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2025-11-02 12:23:25 -06:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#16977