Skip to content

fix: paperclip authenticated mode and required config fields - #1345

Merged
shunkakinoki merged 4 commits into
mainfrom
fix/paperclip-authenticated-mode
Apr 4, 2026
Merged

fix: paperclip authenticated mode and required config fields#1345
shunkakinoki merged 4 commits into
mainfrom
fix/paperclip-authenticated-mode

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Apr 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Use authenticated mode on kyber (local_trusted rejects 0.0.0.0 binding)
  • Add required $meta (version, updatedAt, source) and logging fields to template
  • Auth is still handled at Cloudflare tunnel / nginx ingress level

Problem

  • local_trusted mode rejects 0.0.0.0 host binding — but we need it for k8s to reach paperclip
  • Config validation requires $meta.updatedAt, $meta.source (enum), and logging section

Summary by cubic

Switches Paperclip on Kyber to authenticated mode, adds required config metadata/logging, and restricts access to the expected hostname. Fixes 0.0.0.0 binding rejection and config validation errors.

  • Bug Fixes
    • Set server.deploymentMode to authenticated on Kyber (keep local_trusted elsewhere); required for k8s 0.0.0.0 binding; external auth stays at Cloudflare tunnel/nginx ingress.
    • Add required $meta (version, updatedAt, source) and logging to config.template.json.
    • Add server.allowedHostnames and set paperclip.shunkakinoki.com on Kyber.
    • Wire __DEPLOYMENT_MODE__ and __ALLOWED_HOSTNAME__ via Nix and hydrate.sh. Remove EnvironmentFile from the Paperclip systemd service.
    • Format config.template.json for consistency.

Written for commit 0ef7968. Summary will update on new commits.

Copilot AI review requested due to automatic review settings April 4, 2026 10:08
@mesa-dot-dev

mesa-dot-dev Bot commented Apr 4, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@coderabbitai

coderabbitai Bot commented Apr 4, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@shunkakinoki has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 18 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 8 minutes and 18 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bba4be3c-c69c-4494-ad57-3fefb86758f8

📥 Commits

Reviewing files that changed from the base of the PR and between 8f6bdf9 and 0ef7968.

📒 Files selected for processing (3)
  • config/paperclip/config.template.json
  • config/paperclip/default.nix
  • config/paperclip/hydrate.sh
📝 Walkthrough

Walkthrough

Configuration templating enhancements are introduced across Paperclip's setup: metadata and logging configuration added to the JSON template, deployment mode parameter introduced in Nix with conditional logic, template substitution extended in hydrate.sh, and the EnvironmentFile directive removed from the systemd service definition.

Changes

Cohort / File(s) Summary
Config Template Metadata
config/paperclip/config.template.json
Added top-level $meta object with version, updatedAt, and source fields. Introduced logging section with file mode and extended server section with templated deploymentMode and private exposure setting.
Deployment Mode Templating
config/paperclip/default.nix, config/paperclip/hydrate.sh
Introduced deployment_mode template variable with conditional logic (authenticated if Kyber host, otherwise local_trusted). Added corresponding __DEPLOYMENT_MODE__ placeholder substitution in hydrate script.
Service Configuration
home-manager/modules/paperclip/default.nix
Removed EnvironmentFile directive from systemd.user.services.paperclip, eliminating environment variable loading from instance directory .env file.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • feat: add paperclip service #1342: Introduces the Paperclip Home Manager service with EnvironmentFile directive that is now being removed in this PR as part of the deployment mode configuration refactor.

Poem

🐰 Hopping through configs with care,
Metadata blooming everywhere,
Deployment modes shift like the wind,
New hydrations begin, old files pinned,
A template dance, precise and fair! 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: switching to authenticated mode for kyber and adding required config fields ($meta and logging).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description clearly relates to the changeset, explaining the motivation (0.0.0.0 binding rejection, config validation requirements) and detailing all key changes across the modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/paperclip-authenticated-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mesa-dot-dev

mesa-dot-dev Bot commented Apr 4, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Switches Paperclip on Kyber to authenticated mode, adds required config metadata/logging, and restricts access to the expected hostname. Fixes 0.0.0.0 binding rejection and config validation errors.

What changed?

  • config/paperclip/config.template.json: Updated to include a $meta object for metadata, a logging configuration, and extended the server configuration with deploymentMode, private exposure, and allowedHostnames.
  • config/paperclip/default.nix: Introduced deployment_mode and allowed_hostname configuration parameters, conditionally set based on the host.isKyber flag.
  • config/paperclip/hydrate.sh: Updated to include sed replacements for __DEPLOYMENT_MODE__ and __ALLOWED_HOSTNAME__ during configuration hydration.
  • home-manager/modules/paperclip/default.nix: Removed the EnvironmentFile directive from the paperclip service configuration.

Description generated by Mesa. Update settings

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Paperclip configuration template by adding metadata, logging settings, and server deployment options. It also updates the Nix expressions and hydration script to support a new deployment_mode variable and removes an unused environment file from the systemd service. Feedback suggests using dynamic placeholders for the configuration timestamp to avoid hardcoded dates and warns of a potential conflict between the application's file-based logging and systemd's log redirection.

{
"$meta": {
"version": 1,
"updatedAt": "2026-04-04T00:00:00.000Z",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The updatedAt field is hardcoded to a static date. It is better to use a placeholder and populate it dynamically during the hydration process to reflect the actual configuration generation time.

Suggested change
"updatedAt": "2026-04-04T00:00:00.000Z",
"updatedAt": "__UPDATED_AT__",

"connectionString": "__DATABASE_CONNECTION_STRING__"
},
"logging": {
"mode": "file"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Setting logging.mode to file may conflict with the systemd service configuration in home-manager/modules/paperclip/default.nix, which redirects StandardOutput and StandardError to a log file. If the application logs to its own file, it might bypass the systemd log capture or cause duplication. Consider using a mode that logs to stdout (e.g., console) to allow systemd to manage logs centrally via the journal or the configured redirection.

@sed@ \
-e "s|__DATABASE_MODE__|@database_mode@|g" \
-e "s|__DATABASE_CONNECTION_STRING__|@database_connection_string@|g" \
-e "s|__DEPLOYMENT_MODE__|@deployment_mode@|g" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add a substitution for the __UPDATED_AT__ placeholder to dynamically set the configuration's last updated timestamp using the current system time during deployment. This follows the established pattern for Nix-processed scripts in this repository.

Suggested change
-e "s|__DEPLOYMENT_MODE__|@deployment_mode@|g" \
-e "s|__DEPLOYMENT_MODE__|@deployment_mode@|g" \
-e "s|__UPDATED_AT__|$(date -u +'%Y-%m-%dT%H:%M:%S.000Z')|g" \
References
  1. Maintain consistency with established patterns for writing scripts that are extracted from Nix expressions, such as using @variable@ placeholders for build-time or deployment-time substitutions.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
config/paperclip/config.template.json (1)

2-5: Consider generating $meta.updatedAt dynamically instead of hardcoding.

Using a fixed timestamp at Line 4 will age quickly and make metadata less trustworthy. Prefer templating this value during hydration (or generation) so it reflects actual config creation/update time.

♻️ Suggested direction
-    "updatedAt": "2026-04-04T00:00:00.000Z",
+    "updatedAt": "__UPDATED_AT__",

And in config/paperclip/hydrate.sh, add a substitution using a generated UTC timestamp before writing the file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/paperclip/config.template.json` around lines 2 - 5, Replace the
hardcoded "$meta.updatedAt" value with a templated placeholder in
config/paperclip/config.template.json and update config/paperclip/hydrate.sh to
substitute that placeholder with a generated UTC timestamp at hydration time
(e.g., using date -u +%Y-%m-%dT%H:%M:%SZ) before writing the final config;
target the "$meta.updatedAt" field in the template and perform the replacement
in hydrate.sh so the produced config contains the actual creation/update time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@config/paperclip/config.template.json`:
- Around line 2-5: Replace the hardcoded "$meta.updatedAt" value with a
templated placeholder in config/paperclip/config.template.json and update
config/paperclip/hydrate.sh to substitute that placeholder with a generated UTC
timestamp at hydration time (e.g., using date -u +%Y-%m-%dT%H:%M:%SZ) before
writing the final config; target the "$meta.updatedAt" field in the template and
perform the replacement in hydrate.sh so the produced config contains the actual
creation/update time.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bfdf79cd-bf44-46e4-8e04-58d540abc278

📥 Commits

Reviewing files that changed from the base of the PR and between a8645c8 and 8f6bdf9.

📒 Files selected for processing (4)
  • config/paperclip/config.template.json
  • config/paperclip/default.nix
  • config/paperclip/hydrate.sh
  • home-manager/modules/paperclip/default.nix
💤 Files with no reviewable changes (1)
  • home-manager/modules/paperclip/default.nix

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts the Paperclip Home Manager integration/config generation to work on Kyber (k8s-reachable bind address) and to satisfy Paperclip’s config validation requirements.

Changes:

  • Switch Kyber to authenticated deployment mode (keep local_trusted elsewhere) and wire it into config hydration.
  • Extend config.template.json with required $meta fields and a logging section.
  • Remove the systemd EnvironmentFile reference for the Paperclip user service.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
home-manager/modules/paperclip/default.nix Drops EnvironmentFile from the Paperclip systemd user service.
config/paperclip/hydrate.sh Adds __DEPLOYMENT_MODE__ substitution during config generation.
config/paperclip/default.nix Introduces deployment_mode and sets Kyber to authenticated.
config/paperclip/config.template.json Adds required $meta + logging, and wires server.deploymentMode.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
"$meta": {
"version": 1,
"updatedAt": "2026-04-04T00:00:00.000Z",

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$meta.updatedAt is hard-coded to a fixed timestamp in the template, which will quickly become stale/misleading for regenerated configs. Consider making it a placeholder and populating it at hydration/activation time (or otherwise deriving it automatically) so the metadata reflects when the config was actually produced/updated.

Suggested change
"updatedAt": "2026-04-04T00:00:00.000Z",
"updatedAt": "__UPDATED_AT__",

Copilot uses AI. Check for mistakes.
Comment on lines 10 to 15
@sed@ \
-e "s|__DATABASE_MODE__|@database_mode@|g" \
-e "s|__DATABASE_CONNECTION_STRING__|@database_connection_string@|g" \
-e "s|__DEPLOYMENT_MODE__|@deployment_mode@|g" \
-e "s|__HOST__|@host@|g" \
"$TEMPLATE" >"$CONFIG"

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new __DEPLOYMENT_MODE__ substitution was added, but the existing ShellSpec coverage for this hydrate script doesn't assert that placeholder/substitution is present. Please extend spec/paperclip_hydrate_spec.sh to cover the new deployment mode substitution so regressions get caught.

Copilot uses AI. Check for mistakes.
@shunkakinoki
shunkakinoki merged commit 4fe689d into main Apr 4, 2026
10 checks passed
@shunkakinoki
shunkakinoki deleted the fix/paperclip-authenticated-mode branch April 4, 2026 10:25
shunkakinoki added a commit that referenced this pull request Apr 5, 2026
* feat: add paperclip service (#1342)

* feat: add paperclip service

- Systemd service on kyber: runs `paperclipai run` via bun, depends on docker-postgres
- Config via builtins.toJSON: external postgres on kyber, embedded on macOS
- Setup script creates paperclip database on docker-postgres
- Makefile target: `make systemctl-paperclip`

* fix: add shellcheck disable and shell test coverage for paperclip

* fix: correct shellcheck disable directive syntax

* refactor: use config.template.json pattern for paperclip

* refactor: rename setup.sh to hydrate.sh for paperclip

* test: add auto-switch hook tests and update coverage spec

* fix: remove EnvironmentFile from paperclip service (#1344)

* fix: paperclip authenticated mode and required config fields (#1345)

* fix: remove EnvironmentFile from paperclip service

* fix: use authenticated mode on kyber, add required meta/logging fields

* fix: add allowedHostnames for paperclip.shunkakinoki.com

* fix: format config template json

* fix: use trust auth for docker-postgres (#1346)

POSTGRES_HOST_AUTH_METHOD=trust removes password auth for all
connections. The password kept going out of sync after crash recovery,
causing paperclip and other services to fail with 'password
authentication failed'. Safe since postgres is only reachable from
the host.

* fix: use k8s postgres via DATABASE_URL, remove docker-postgres dep, add authenticated mode (#1347)

* fix: use bun runtime for paperclip (pino-http node crash), k8s postgres via DATABASE_URL (#1348)

* fix: use nix-profile bun path for paperclip service (#1350)

* fix: add caret prefix to paperclipai dependency (#1349)

* fix: use extra-substituters to avoid untrusted user warnings (#1351)

* fix: run paperclip from cloned repo via pnpm dev:once (#1352)

* fix: run paperclip from cloned repo via pnpm dev:once

The global bun install flattens pino@10 + pino-http@10.5 together,
but pino-http needs pino@9. The repo lockfile resolves this correctly
with nested dependencies. Running from the repo avoids the crash.

* fix: use bun run server/src/index.ts instead of pnpm dev:once

* fix: pin pino@9.14.0 override, run paperclipai from dotfiles node_modules

The bun flat hoisting was resolving pino@10 which is incompatible
with pino-http@10.5. Pinning pino to 9.14.0 via overrides matches
the paperclip repo's lockfile resolution and fixes the crash.

* fix: use global bun paperclipai with pino override (#1353)

* fix: use global ~/.bun/bin/paperclipai with pino override

Propagate overrides from dotfiles package.json to ~/.bun/install/global/
so the global binary resolves pino@9.14.0 correctly.

* test: add tests for npm-globals dependency overrides

* fix: resolve GitHub Actions failures and code review issues

- Fix non-portable \s regex to [[:space:]] in auto-switch.sh (shfmt compat)
- Add jq dependency check alongside cswap
- Use printf instead of echo for safer output
- Fix claude-swap version from >=1.1.5 (non-existent) to >=0.7.1
- Add auto-switch.sh to Nix deployment config (default.nix)
- Sort covered_scripts list alphabetically in coverage_spec.sh

https://claude.ai/code/session_012GyQBesQGF1asTfKebWyLM

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants