فهرست منبع

Say that the key file is how you develop against this

bin/tcms-vault-key --file read as a grudging fallback for a machine with no
systemd, and buried the case it is actually for: running tPSGI by hand, in a
tmux, which is the ordinary way to work on tCMS and to debug it.  Nothing in
that path hands a key over -- no unit importing a credential, and
service/tpsgi.sh, which is what would have put one in the environment, never ran
-- so /secrets does not work until you put one where Trog::Vault can find it,
and nothing said so.

It is still the wrong thing on a production host, and still says why: a key file
beside the database it protects goes into the same backup as the database it
protects.  That is a compromise for development and a hole in production, which
is two different things and now reads as two different things.

Also .gitignores config/secrets.key, which it was not.  Committing the key would
put it in the one place it exists not to be, and the Readme claimed it was
covered when it was not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ADwKSaBSvUTdA3RtGQeNau
George Baugh 1 ماه پیش
والد
کامیت
4883721cc9
4فایلهای تغییر یافته به همراه64 افزوده شده و 17 حذف شده
  1. 4 0
      .gitignore
  2. 19 1
      Readme.md
  3. 30 13
      bin/tcms-vault-key
  4. 11 3
      lib/Trog/Vault.pm

+ 4 - 0
.gitignore

@@ -19,6 +19,10 @@ www/styles/reveal-white.css
 www/.well_known
 config/auth.db
 config/has_users
+# The vault key, when bin/tcms-vault-key --file put one here rather than the
+# service handing one over.  Committing it would put the key in the same place
+# as everything it protects, which is the one thing it exists not to be.
+config/secrets.key
 config/main.cfg
 config/setup
 Makefile

+ 19 - 1
Readme.md

@@ -40,6 +40,19 @@ Then:
 You won't want to run like this in production, but this is probably how you want to develop your themes
 or hack on tCMS itself.
 
+Nothing hands a vault key to a tPSGI you started yourself: the systemd credential
+and the unit that imports it are not in the picture, and `service/tpsgi.sh`, which
+is what would have put it in the environment, never ran.  So if you want /secrets
+to work while developing, mint one into the checkout:
+
+    bin/tcms-vault-key --file
+
+That writes `config/secrets.key`, which is the last place Trog::Vault looks.  It
+is the right thing for development and testing and the wrong thing for a
+production host, for the reason under Stored Secrets: it sits next to the database
+it protects, so anything that backs up one backs up the other.  `.gitignore` keeps
+it out of the repository; keeping it out of your backups is on you.
+
 Production Deployment
 ====================
 
@@ -233,7 +246,12 @@ tPSGI's `bin/build_service` mints it and puts it in systemd's credential store,
 sealed to this machine's TPM if it has one, and its unit hands it over before it
 chroots -- so it never touches a disk here.  It is named for tPSGI rather than
 tCMS because tPSGI owns the unit and runs whatever is in the directory.
-`bin/tcms-vault-key --file` is the fallback for a machine with no systemd at all.
+`bin/tcms-vault-key --file` writes one to `config/secrets.key` instead.  That is
+what to use when you are running tPSGI by hand rather than under systemd, which
+is the ordinary way to develop against this and to debug it -- see Development
+above.  It is also the answer on a machine with no systemd at all, and there it
+is the weaker choice: a key beside the database it protects is a key in the same
+backup as the database it protects.
 
 tCMS deletes the key from its environment as it loads, because one of the things
 it forks is a provisioner it hands a decrypted password to.  With no key there is

+ 30 - 13
bin/tcms-vault-key

@@ -13,23 +13,37 @@ use Trog::Vault ();
 
 =head1 SYNOPSIS
 
-Write a vault key into config/secrets.key, for an installation that is not run
-by systemd.
+Write a vault key into config/secrets.key, for a tCMS that is not being handed
+one by the service that starts it.
 
 =head2 USAGE
 
     bin/tcms-vault-key --file
 
-=head2 YOU PROBABLY DO NOT WANT THIS
+=head2 WHEN YOU WANT THIS
 
-tPSGI's bin/build_service makes the key and puts it in systemd's credential
-store, sealed to this machine if it has a TPM to seal it to, and its unit hands
-it to tCMS before it chroots.  That is the way to do this, and it needs nothing
-from here.
+Developing, mostly.  Running tPSGI by hand -- HOME=. bin/tpsgi -p 5001, in a
+tmux, so you can watch it and restart it -- is the ordinary way to work on tCMS,
+and nothing in that path hands over a vault key: there is no unit importing a
+systemd credential, and service/tpsgi.sh, which is what would have put it in the
+environment, never ran.  So /secrets does not work until you put a key where
+Trog::Vault can find one, and this is how.
 
-This is the fallback for a machine with no systemd, and it is genuinely weaker:
-a key file beside the database it protects is a key file in the same backup as
-the database it protects.  Take the trade knowingly or not at all.
+The other time is a machine with no systemd at all, and there it is a compromise
+rather than a convenience.
+
+=head2 WHEN YOU DO NOT
+
+On a production host.  tPSGI's bin/build_service makes the key and puts it in
+systemd's credential store, sealed to this machine if it has a TPM to seal it to,
+and its unit hands it to tCMS before it chroots -- so the key is never on a disk
+that tCMS can see, and never in a backup of tCMS.
+
+A key file in the checkout gives up exactly that.  It sits next to the database
+it protects, so whatever copies one copies the other, and the encryption stops
+being worth anything the moment both are somewhere they should not be.
+.gitignore keeps it out of the repository; keeping it out of your backups is on
+you.
 
 =head2 WHAT THE KEY IS
 
@@ -57,8 +71,10 @@ GetOptions(
 
 if ( $help || !$file ) {
     print "Usage: bin/tcms-vault-key --file\n\n";
-    print "Writes $Trog::Vault::key_file for an installation with no systemd.\n";
-    print "Under systemd, tPSGI's bin/build_service does this properly; see perldoc bin/tcms-vault-key.\n";
+    print "Writes $Trog::Vault::key_file, for a tCMS nothing is handing a vault key to:\n";
+    print "running tPSGI by hand while developing, or a machine with no systemd.\n";
+    print "On a production host tPSGI's bin/build_service does this properly, and better;\n";
+    print "see perldoc bin/tcms-vault-key.\n";
     exit( $help ? 0 : 2 );
 }
 
@@ -75,4 +91,5 @@ close($fh);
 chmod( oct('600'), $Trog::Vault::key_file ) or die "Could not chmod $Trog::Vault::key_file: $!\n";
 
 print "Wrote $Trog::Vault::key_file.  Restart tCMS to pick it up.\n";
-print "Back it up somewhere that is not where you back up config/auth.db, or do not back it up at all.\n";
+print "Fine for development.  On a production host, let tPSGI's bin/build_service hand one\n";
+print "over instead, so the key is not sitting next to the database it protects.\n";

+ 11 - 3
lib/Trog/Vault.pm

@@ -67,9 +67,17 @@ that we are handing a decrypted password to on its stdin.  Read once, in the
 parent, before there are any workers; the workers inherit the key as a variable
 and an environment without it.
 
-The second is for a service that is not chrooted.  The third is for a machine
-that is not running systemd at all, and it is the weakest of the three: a file
-next to the database it protects is a file that goes into the same backup.
+The second is for a service that is not chrooted.
+
+The third is for a tCMS nothing is handing a key to, which is what you get from
+running tPSGI by hand -- the ordinary way to develop against this, since it is
+easier to watch and to restart.  There is no unit and no service/tpsgi.sh in that
+path, so nothing put a key in the environment, and bin/tcms-vault-key --file
+writes one here instead.
+
+It is the weakest of the three and the only one you should not be running in
+production: a file next to the database it protects is a file that goes into the
+same backup.
 
 No key means no vault.  Nothing is stored and nothing is offered, and the parts
 of tCMS which would have used one ask for the password directly, as they did