Skip to content

WIP: Feature/project token rotation#28

Draft
daniel-falk wants to merge 2 commits intomainfrom
feature/project-token-rotation
Draft

WIP: Feature/project token rotation#28
daniel-falk wants to merge 2 commits intomainfrom
feature/project-token-rotation

Conversation

@daniel-falk
Copy link
Contributor

@daniel-falk daniel-falk commented Nov 15, 2025

Note

Introduces a token-rotation example with a Flask server, Telegraf configs, and a helper script to rotate tokens and send metrics securely.

  • Token-rotation example project (project-token-rotation/):
    • Server (test_scripts/example_server.py):
      • Flask server with POST /generate-token (accepts bootstrap or existing token, issues new UUID token) and POST /metrics (requires generated token).
      • Per-device token storage (serial header) and auth decorators for bootstrap vs. generated tokens.
    • Helper script (send_http_request.sh):
      • Sends/requests data with Bearer auth, serial header, JSON body; retries on 401 using --default-token.
      • Reads latest token from ${HELPER_FILES_DIR}/token.txt (JSONL), robust error handling and exit codes.
    • Telegraf configs:
      • inputs.conf: mock metrics (exec hello, sine wave) at 1s.
      • output.conf: sends metrics as JSON via helper script to http://${SERVER_URL}:8000/metrics, drops device_token.
      • update_token.conf: every 5s calls /generate-token, stores latest token to ${HELPER_FILES_DIR}/token.txt and logs to stdout.
    • Docs (README.md):
      • Architecture/flow, compatibility, and quick start instructions with required env vars.

Written by Cursor Bugbot for commit 0236735. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • Documentation

    • Added README documenting token rotation flow, authentication setup, and quick-start guide
  • New Features

    • Implemented token rotation system with periodic token updates every 5 seconds
    • Added metrics forwarding to external server with token-based authentication
    • Created test server and helper scripts for token-based HTTP communication
    • Added sample data generation for testing

@daniel-falk daniel-falk marked this pull request as draft November 15, 2025 12:23
@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

Walkthrough

This PR introduces a complete token rotation system for the FixedIT Data Agent. It includes documentation, Telegraf configurations for metrics input/output, a shell script for token-authenticated HTTP requests, a Flask test server for token generation and metrics endpoints, and configurations for periodic token updates with persistent token storage.

Changes

Cohort / File(s) Summary
Documentation
project-token-rotation/README.md
New README documenting token rotation flow, motivation, authentication flow, and quick-start guide for the FixedIT Data Agent.
Telegraf Input & Output Configurations
project-token-rotation/inputs.conf, project-token-rotation/output.conf
Mock input configuration generating sample sine_wave and exec metrics; exec output configuration forwarding metrics via HTTP requests with token-based authentication.
Token Rotation Configuration
project-token-rotation/update_token.conf
Periodic token request every 5 seconds via helper script, parsing JSON response for device serial and token, and atomically persisting latest token to token.txt.
Token-Authenticated HTTP Helper
project-token-rotation/send_http_request.sh
Shell script supporting two modes: --request-metrics to fetch data and --send-metrics to POST metrics; includes token management, retry logic on 401 responses, and comprehensive error handling.
Test Server Implementation
project-token-rotation/test_scripts/example_server.py
Flask server implementing token-rotating device endpoints; provides bootstrap and generated token authentication schemes, /metrics endpoint for receiving metrics, and /generate-token endpoint for UUID-based token generation and storage.

Sequence Diagram(s)

sequenceDiagram
    participant Device
    participant Server as Example Server
    participant Store as Token Store
    
    rect rgb(200, 220, 240)
    Note over Device,Server: Bootstrap & Initial Registration
    Device->>Server: POST /generate-token<br/>(BOOTSTRAP_TOKEN)
    Server->>Server: Extract device serial from header
    Server->>Server: Validate bootstrap token
    Server->>Store: Generate UUID token for device
    Server->>Server: Store token mapping
    Server-->>Device: JSON: [serial, token]
    Device->>Device: Persist token to token.txt
    end
    
    rect rgb(220, 240, 200)
    Note over Device,Server: Metrics Submission & Token Refresh
    Device->>Server: POST /metrics<br/>(Bearer: current_token)
    Server->>Server: Authenticate using generated token
    Server-->>Device: 200 Success
    Device->>Device: Every 5s: Request new token
    Device->>Server: POST /generate-token<br/>(Bearer: current_token)
    Server->>Store: Generate new UUID token
    Server-->>Device: JSON: [serial, new_token]
    Device->>Device: Atomically update token.txt
    end
    
    rect rgb(240, 220, 200)
    Note over Device,Server: Retry on Auth Failure
    Device->>Server: POST /metrics<br/>(Bearer: stale_token)
    Server-->>Device: 401 Unauthorized
    Device->>Device: Retry with bootstrap token
    Device->>Server: POST /metrics<br/>(Bearer: BOOTSTRAP_TOKEN)
    Server->>Server: Generate new token for device
    Server-->>Device: 200 Success
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • send_http_request.sh: Dense logic with error handling, JSONL token file parsing, retry logic on 401, multiple environment variable dependencies, and distinct exit codes for different failure modes.
  • example_server.py: Multiple authentication schemes (bootstrap vs. generated tokens), decorator patterns for route protection, global state management for device token storage, and error response handling.
  • Configuration files: Interconnected Telegraf configs with environment variable substitution, file atomicity concerns (temp file + mv pattern), and timing/scheduling implications.
  • Cross-component integration: Token flow spans shell script, Flask server, and Telegraf configs with multiple potential failure points.

Suggested reviewers

  • fixedit-olatz

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'WIP: Feature/project token rotation' is vague and uses generic/non-descriptive terms ('WIP', 'Feature') that don't clearly convey the specific main change. Replace with a more specific title that clearly describes the primary change, e.g., 'Add token rotation example project with Telegraf configs and Flask server' or 'Implement periodic token rotation with Telegraf integration example'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/project-token-rotation

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

@github-actions
Copy link

🎨 Code Formatting Required

Trailing Whitespace Issues

Some files have trailing whitespace (spaces/tabs at end of lines).

Files with trailing whitespace:

  • ./project-token-rotation/send_http_request.sh

To fix: Remove the trailing spaces/tabs at the end of lines in your favorite editor.

After fixing:

  1. Commit and push the changes
  2. The formatting check will automatically pass

@daniel-falk daniel-falk force-pushed the feature/project-token-rotation branch from 1088e09 to 0236735 Compare November 15, 2025 12:25
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 15, 2025

Quality Gate Passed Quality Gate passed

Issues
6 New issues
1 Accepted issue

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

@daniel-falk
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

✅ Actions performed

Full review triggered.

BOOTSTRAP_TOKEN = "bootstrap-key-12345"

# Dictionary to store generated tokens for each device (serial -> token)
device_tokens = {}
Copy link

Choose a reason for hiding this comment

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

Bug: Token Rotation Race Leads to Authentication Errors

The device_tokens dictionary stores only one token per device, but the device keeps the last 2 tokens in its file. When token rotation occurs, the server immediately invalidates the previous token, creating a race condition where metrics sent with the old token (still valid on the device side) get rejected. The server should maintain at least the last 2 tokens per device to match the device's token file behavior and prevent authentication failures during rotation.

Fix in Cursor Fix in Web

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (6)
project-token-rotation/output.conf (1)

4-9: Prefer passing script and arguments directly instead of sh -c

Using sh -c is slightly more brittle (quoting, shell parsing). You can let Telegraf exec the script directly:

-[[outputs.exec]]
-  # Send all metrics except from the metric in the 'update_token.conf' file.
-  namedrop = ["device_token"]
-  # Send the metrics as JSON to the script.
-  command = ["sh", "-c", "${HELPER_FILES_DIR}/send_http_request.sh --url http://${SERVER_URL}:8000/metrics --send-metrics"]
-  data_format = "json"
+[[outputs.exec]]
+  # Send all metrics except from the metric in the 'update_token.conf' file.
+  namedrop = ["device_token"]
+  # Send the metrics as JSON to the script.
+  command = ["${HELPER_FILES_DIR}/send_http_request.sh", "--url", "http://${SERVER_URL}:8000/metrics", "--send-metrics"]
+  data_format = "json"

This avoids an extra shell layer and handles spaces in paths/args more predictably.

project-token-rotation/README.md (1)

1-6: Align README with template and product-link / messaging guidelines

A few small tweaks will make this README match the shared guidelines:

  • First mention of the FixedIT Data Agent should link to the product page.
  • The "here" link text should be descriptive (markdownlint MD059).
  • The template expects clearer intro/background + troubleshooting/developer-notes and explicit “no C/C++ development required” messaging.

For example:

-# Example of token rotation for the FixedIT Data Agent
+# Example of token rotation for the [FixedIT Data Agent](https://fixedit.ai/products-data-agent/)
-This project was created during a screencast that can be found [here](https://www.youtube.com/watch?v=zeWdbDNvj_w).
+This project was created during a screencast, available on [YouTube](https://www.youtube.com/watch?v=zeWdbDNvj_w).

And before merging, consider:

  • Replacing Minimum AXIS OS version: TBD with a concrete version once you’ve verified the sh compatibility.
  • Adding brief troubleshooting and developer-oriented notes as per .project_readme_template.md (host testing limits, how to extend the example, “no C/C++ development required” note).

Also applies to: 24-36, 52-62

project-token-rotation/send_http_request.sh (2)

7-17: Tidy exit codes and clarify environment-variable expectations

A couple of small cleanups would make this script easier to maintain and use:

  • EXIT_EMPTY_TOKEN_FILE and EXIT_FAILED_TO_PARSE_TOKEN are never used; either wire them into get_token for more granular errors or drop them to avoid confusion.
  • At the top of the file, it helps to explicitly document the required environment variables (even though you validate them later), per the project shell guidelines.
  • Currently SERVER_URL is only used for the “not set” check; the actual URL always comes from --url. Either mention that in the comments or consider using SERVER_URL to build the default URL so there is a single source of truth.

Example header improvement:

-#!/bin/sh
-# Script to make HTTP requests with token-based authentication
-# Supports two modes:
+#!/bin/sh
+# Script to make HTTP requests with token-based authentication
+#
+# Environment variables:
+#   SERVER_URL         - base URL of the example server (used for validation)
+#   DEVICE_PROP_SERIAL - device serial sent as the 'serial' HTTP header
+#   HELPER_FILES_DIR   - directory where token.txt is stored
+#
+# Supports two modes:

Also applies to: 176-190


24-50: Improve POSIX portability and avoid logging full token values

Two related points around portability and secrecy:

  • The functions (get_token, send_http_request, make_request_with_retry, handle_response) all use local, which is not defined in pure POSIX sh. The README already notes this, but for maximum AXIS OS compatibility it’s better to avoid local and instead use function-specific global variable names.
  • get_token and later logs print the full bearer token in debug messages, which can leak credentials into logs even in a “demo” setup.

You can keep behavior but address both concerns like this for get_token (and apply the same pattern to other functions):

-get_token() {
-  local token_file="${HELPER_FILES_DIR}/token.txt"
-  local token=""
+get_token() {
+  get_token_token_file="${HELPER_FILES_DIR}/token.txt"
+  get_token_token=""
@@
-  echo "[DEBUG] Looking for token file at: $token_file" >&2
+  echo "[DEBUG] Looking for token file at: $get_token_token_file" >&2
@@
-  if [ -f "$token_file" ] && [ -s "$token_file" ]; then
+  if [ -f "$get_token_token_file" ] && [ -s "$get_token_token_file" ]; then
@@
-    token=$(tail -n 1 "$token_file" | jq -r '.fields.token' 2>/dev/null)
-    if [ -n "$token" ] && [ "$token" != "null" ]; then
-      echo "[DEBUG] Token found: $(echo "$token")..." >&2
-      echo "$token"
+    get_token_token=$(tail -n 1 "$get_token_token_file" | jq -r '.fields.token' 2>/dev/null)
+    if [ -n "$get_token_token" ] && [ "$get_token_token" != "null" ]; then
+      echo "[DEBUG] Token found in file" >&2
+      echo "$get_token_token"

Similarly, you can change the later debug lines to avoid echoing the token itself:

-echo "[DEBUG] Final token: $(echo "$TOKEN")..." >&2
+echo "[DEBUG] Final token selected (from file or default token)" >&2

This keeps debugging useful without putting sensitive values into logs while improving /bin/sh portability.

Also applies to: 52-79, 83-101, 106-126, 193-210

project-token-rotation/test_scripts/example_server.py (2)

91-115: Avoid unused serial variables in decorators

Both decorators unpack serial from the auth helpers but never use it, which triggers linters and adds noise:

 def require_generated_token(f):
@@
-    def decorated(*args, **kwargs):
-        is_valid, message, serial = authenticate_generated_token_only()
+    def decorated(*args, **kwargs):
+        is_valid, message, _serial = authenticate_generated_token_only()
@@
 def require_bootstrap_or_token(f):
@@
-    def decorated(*args, **kwargs):
-        is_valid, message, serial = authenticate_bootstrap_or_generated()
+    def decorated(*args, **kwargs):
+        is_valid, message, _serial = authenticate_bootstrap_or_generated()

This keeps the auth helper signatures intact while satisfying Ruff.


12-14: Clarify demo-only choices for bootstrap token and server exposure

Given this is a demo server, a couple of points are worth calling out explicitly:

  • BOOTSTRAP_TOKEN is hardcoded in the script and referenced in the README. That’s fine for an example, but for any non-demo use you’ll want to pass this via environment/config instead.
  • app.run(host="0.0.0.0", port=8000, debug=False) binds to all interfaces. Again, this is convenient for local testing, but in real deployments you’d normally rely on a fronting reverse proxy or restrict access with firewall rules.
  • The broad except Exception blocks in receive_metrics and generate_token are acceptable for a small example, but if this grows it may be worth catching narrower exceptions or logging full tracebacks.

No changes are strictly required for the example, but adding a short comment in the file or README that these are “demo defaults, not production settings” would help set expectations.

Also applies to: 143-165, 167-179

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 602347f and 0236735.

⛔ Files ignored due to path filters (1)
  • project-token-rotation/.images/diagram.png is excluded by !**/*.png
📒 Files selected for processing (6)
  • project-token-rotation/README.md (1 hunks)
  • project-token-rotation/inputs.conf (1 hunks)
  • project-token-rotation/output.conf (1 hunks)
  • project-token-rotation/send_http_request.sh (1 hunks)
  • project-token-rotation/test_scripts/example_server.py (1 hunks)
  • project-token-rotation/update_token.conf (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
project-*/**

⚙️ CodeRabbit configuration file

project-*/**: Each example project for the FixedIT Data Agent should be self-contained and designed as a standalone example / tutorial showing how to use the FixedIT Data Agent. The project should be well documented and include all the necessary files to run the example. A reader should be able to understand the background and the purpose of the project, and be able to understand the implementation details and how to use it. If the project includes a dashboard, it should be placed in a new folder in the repo-root/dashboard-deployments/ directory instead of being included in the project folder. In the README for the project, the first time the FixedIT Data Agent is mentioned, we should link to the product page: https://fixedit.ai/products-data-agent/ Emphasize that these solutions are accessible to system integrators and IT professionals without requiring complex C/C++ ACAP development. Highlight that custom edge intelligence can be implemented using familiar IT tools (configuration files, shell scripts, REST APIs) rather than traditional embedded programming approaches. Note that bash does not exist on the Axis devices, so .sh scripts should be written in portable shell syntax.
README Structure: All project README files should follow the standardized template at .project_readme_template.md. This template ensures consistent documentation that serves both audiences: (1) IT professionals who want plug-and-play solutions, and (2) developers who want to customize and extend the examples. The template enforces a logical structure: 1) Introduction and background (project purpose, how it works, why choose this approach) 2) Technical explanation and quick start guide (compatibility, setup, troubleshooting) 3) Developer-oriented notes (local testing, implementation details)
Key README Requirements: - Include compatibility sections for both AXIS OS and FixedIT Data Agent versions - Explain host testing and its limitations and why certain parts require actual Axis d...

Files:

  • project-token-rotation/README.md
  • project-token-rotation/output.conf
  • project-token-rotation/inputs.conf
  • project-token-rotation/send_http_request.sh
  • project-token-rotation/update_token.conf
  • project-token-rotation/test_scripts/example_server.py
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: Documentation files should clearly communicate the dual audience: (1) server-side dashboard users who want to keep agent with bundled configs, and (2) edge device developers who want to customize agent behavior. Ensure examples and instructions are appropriate for the intended skill level and use case. Since this is a public repository, we should not include any sensitive information, the instructions should be easily understandable for a wide audience, and we should avoid using any jargon or technical terms that are not commonly used.
Headings should not include special characters like emojis or backticks. The table of contents should be generated with the markdown-toc tool, meaning that we should use the <!-- toc --> and <!-- tocstop --> tags.

Files:

  • project-token-rotation/README.md
**/*

⚙️ CodeRabbit configuration file

This repository serves FixedIT Data Agent users across a spectrum from plug-and-play dashboard deployment to advanced edge device customization. Consider whether changes maintain accessibility for both DevOps professionals (server-side focus) and developers (edge customization focus). If new features are added or existing ones changed significantly, ensure documentation clearly explains the intended audience and usage level. We use prettier for formatting of common file formats like markdown, yaml, json, etc. Example projects should be placed in the repo-root in a directory named project-*/. Whenever referencing Axis device model names like "D4100-VE mk II" or "M3045", prefix it with "AXIS" in capital letters (e.g. "AXIS D4100-VE mk II"). When using Axis as a company name, use "Axis Communications", note that all-caps is only used when "AXIS" is used in their product names, not their company name. When using the name of an Axis product, google on the name to verify that it is correctly identified. Avoid using 'cameras' or 'Axis cameras' unless the solution in related to visual analytics, otherwise prefer using 'Axis devices' to show that the FixedIT Data Agent also works with strobes, speakers, door stations, etc. Images used for the README should be placed in a directory called .images/ in the affected project folder. These images might also be referred to from other sources like the top-level README.md file.

Files:

  • project-token-rotation/README.md
  • project-token-rotation/output.conf
  • project-token-rotation/inputs.conf
  • project-token-rotation/send_http_request.sh
  • project-token-rotation/update_token.conf
  • project-token-rotation/test_scripts/example_server.py
project-*/**/*.sh

⚙️ CodeRabbit configuration file

Shell scripts should be written in portable shell (/bin/sh) syntax since bash is not installed on the Axis devices. Since local is not supported in all cameras (like AXIS OS 9.80), it should be avoided unless the AXIS OS limitations are explicitly mentioned. If not using local, it can be good to use a function specific prefix for the variable names to avoid conflicts with other variables. Clearly document in the head of the file which environment variables they expect and if they are optional or required. It's normally good to use set -eu for stricter error handling, but -o pipefail is not supported in the Axis devices' shell.

Files:

  • project-token-rotation/send_http_request.sh
🧠 Learnings (2)
📓 Common learnings
Learnt from: daniel-falk
Repo: fixedit-ai/fixedit-data-agent-examples PR: 18
File: dashboard-deployments/system-monitoring-influxdb2-flux-grafana/provisioning/dashboards/overview_of_devices.json:1121-1130
Timestamp: 2025-09-03T14:18:52.406Z
Learning: When fixing unit mismatches in Grafana dashboards, daniel-falk prefers changing the panel unit configuration to match the data rather than transforming the query values, choosing simplicity over data conversion when both approaches are valid.
📚 Learning: 2025-10-15T11:36:24.102Z
Learnt from: daniel-falk
Repo: fixedit-ai/fixedit-data-agent-examples PR: 24
File: project-hello-world/README.md:156-179
Timestamp: 2025-10-15T11:36:24.102Z
Learning: The hello-world project (project-hello-world) for the FixedIT Data Agent has no differences between host and device behavior. It works identically on both because it only uses basic echo commands and standard Telegraf features.

Applied to files:

  • project-token-rotation/inputs.conf
🪛 ast-grep (0.39.9)
project-token-rotation/test_scripts/example_server.py

[warning] 178-178: Running flask app with host 0.0.0.0 could expose the server publicly.
Context: app.run(host="0.0.0.0", port=8000, debug=False)
Note: [CWE-668]: Exposure of Resource to Wrong Sphere [OWASP A01:2021]: Broken Access Control [REFERENCES]
https://owasp.org/Top10/A01_2021-Broken_Access_Control

(avoid_app_run_with_bad_host-python)

🪛 markdownlint-cli2 (0.18.1)
project-token-rotation/README.md

5-5: Link text should be descriptive

(MD059, descriptive-link-text)

🪛 Ruff (0.14.4)
project-token-rotation/test_scripts/example_server.py

1-1: Shebang is present but file is not executable

(EXE001)


13-13: Possible hardcoded password assigned to: "BOOTSTRAP_TOKEN"

(S105)


96-96: Unpacked variable serial is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


109-109: Unpacked variable serial is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


137-137: Consider moving this statement to an else block

(TRY300)


138-138: Do not catch blind exception: Exception

(BLE001)


161-161: Consider moving this statement to an else block

(TRY300)


162-162: Do not catch blind exception: Exception

(BLE001)


179-179: Possible binding to all interfaces

(S104)

🪛 Shellcheck (0.11.0)
project-token-rotation/send_http_request.sh

[warning] 10-10: EXIT_EMPTY_TOKEN_FILE appears unused. Verify use (or export if used externally).

(SC2034)


[warning] 11-11: EXIT_FAILED_TO_PARSE_TOKEN appears unused. Verify use (or export if used externally).

(SC2034)


[warning] 28-28: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 29-29: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 55-55: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 56-56: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 57-57: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 58-58: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 84-84: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 85-85: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 86-86: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 87-87: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 88-88: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 107-107: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 108-108: In POSIX sh, 'local' is undefined.

(SC3043)


[warning] 109-109: In POSIX sh, 'local' is undefined.

(SC3043)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (2)
project-token-rotation/inputs.conf (1)

1-24: Mock inputs config looks good for the example

The agent, tags, and mock inputs (exec + sine_wave) are coherent and match the described token-rotation test flow. No changes needed here.

project-token-rotation/update_token.conf (1)

4-39: Token rotation workflow and atomic token.txt update look solid

The exec input/output wiring, JSON parsing, and { tail ...; cat; } > tmp && mv pattern correctly implement:

  • Fetching a new token every 5s via /generate-token.
  • Emitting a device_token metric with serial and token fields.
  • Maintaining a small JSONL token.txt file with the previous + latest token via an atomic move.
  • Ensuring downstream readers see updates quickly (flush_interval = "1s", metric_batch_size = 1, use_batch_format = false).

No changes needed here.

Comment on lines +46 to +51
From the start, all devices share a bootstrapping key. The first time a new device connects to the server, it will be issued a new token. After this, the bootstrap token will no longer be accepted by the server for this particular device.

The device has a workflow that will request the latest active token from the server's `/generate-token` endpoint every 5 seconds. The workflow will then save this token to the `${HELPER_FILES_DIR}/token.txt` file.

All the workflows in the device that are pushing data to the server will make use of the `send_metrics.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Fix script name in authentication flow description

The script referenced in the auth-flow description doesn’t match the actual filename:

-All the workflows in the device that are pushing data to the server will make use of the `send_metrics.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.
+All the workflows in the device that are pushing data to the server will make use of the `send_http_request.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.

Without this change, readers might look for a non-existent send_metrics.sh.


I'll verify the script name claim by checking what files actually exist in the project and which scripts are referenced throughout the codebase.


---

🏁 Script executed:

```shell
#!/bin/bash
# Find all shell scripts in project-token-rotation directory
find project-token-rotation -name "*.sh" -type f | head -20

Length of output: 43


🏁 Script executed:

#!/bin/bash
# Search for references to both script names in the project
echo "=== Searching for send_metrics.sh references ==="
rg -n "send_metrics\.sh" project-token-rotation/ || echo "No matches found"

echo ""
echo "=== Searching for send_http_request.sh references ==="
rg -n "send_http_request\.sh" project-token-rotation/ || echo "No matches found"

Length of output: 1202


🏁 Script executed:

#!/bin/bash
# Check the content of the README to see the actual lines mentioned
sed -n '40,60p' project-token-rotation/README.md

Length of output: 2006


Fix script name in authentication flow description

The verification confirms the issue: the only script in the project is send_http_request.sh, but line 50 of README.md incorrectly references send_metrics.sh. The correct script name is used elsewhere in the documentation (lines 42, 58) and in the configuration files.

-All the workflows in the device that are pushing data to the server will make use of the `send_metrics.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.
+All the workflows in the device that are pushing data to the server will make use of the `send_http_request.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
From the start, all devices share a bootstrapping key. The first time a new device connects to the server, it will be issued a new token. After this, the bootstrap token will no longer be accepted by the server for this particular device.
The device has a workflow that will request the latest active token from the server's `/generate-token` endpoint every 5 seconds. The workflow will then save this token to the `${HELPER_FILES_DIR}/token.txt` file.
All the workflows in the device that are pushing data to the server will make use of the `send_metrics.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.
From the start, all devices share a bootstrapping key. The first time a new device connects to the server, it will be issued a new token. After this, the bootstrap token will no longer be accepted by the server for this particular device.
The device has a workflow that will request the latest active token from the server's `/generate-token` endpoint every 5 seconds. The workflow will then save this token to the `${HELPER_FILES_DIR}/token.txt` file.
All the workflows in the device that are pushing data to the server will make use of the `send_http_request.sh` script which will read the token from the `${HELPER_FILES_DIR}/token.txt` file and use it to authenticate the request.
🤖 Prompt for AI Agents
In project-token-rotation/README.md around lines 46 to 51, the README
incorrectly references send_metrics.sh in the device authentication flow while
the actual script is send_http_request.sh; update the sentence to use the
correct script name (send_http_request.sh) so it matches the rest of the docs
and configuration, and verify no other references in this block remain
incorrect.

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.

1 participant