Skip to content

Add bot token storage, audit logging, and HTTP APIs for bot token management#2015

Merged
benjamin-747 merged 7 commits into
gitmono-dev:mainfrom
WiedersehenM:feature/bot-token
Mar 18, 2026
Merged

Add bot token storage, audit logging, and HTTP APIs for bot token management#2015
benjamin-747 merged 7 commits into
gitmono-dev:mainfrom
WiedersehenM:feature/bot-token

Conversation

@WiedersehenM

Copy link
Copy Markdown
Contributor

Related issue

#1999

Summary

  • Add secure, HMAC-based bot token storage in Jupiter, exposing only non-plaintext DTOs.
  • Introduce AuditStorage as a centralized audit logging entrypoint for bot-related flows.
  • Add Mono-layer HTTP APIs for bot token lifecycle management under /api/v1/bots/{bot_id}/tokens.

Details

  • Bot token storage (Jupiter)

    • Add BotTokenInfo DTO for listing bot tokens without exposing plaintext.
    • Extend BotsStorage with:
      • generate_bot_token that creates high-entropy random bot tokens, Base64-encodes them, prefixes with bot_, stores only an HMAC-SHA256 hash of the token body (without prefix) in bot_tokens.token_hash, and returns the plaintext token once.
      • list_bot_tokens to return per-bot token metadata ordered by created_at, without plaintext values.
      • revoke_bot_token and revoke_bot_tokens_by_bot to mark tokens as revoked in an idempotent way.
      • find_bot_by_token that:
        • Accepts tokens with or without the bot_ prefix.
        • Computes the HMAC-SHA256 hash of the token body and looks it up in bot_tokens.
        • Enforces revoked = false and expires_at either NULL or in the future.
        • Returns None when the token or corresponding bot record is missing.
    • Load the HMAC key from MEGA_BOT_TOKEN_HMAC_SECRET, returning a clear MegaError if it is missing or invalid.
  • Audit logging (Jupiter)

    • Introduce new module audit_storage.rs defining AuditStorage { base: BaseStorage }.
    • Implement log_audit(actor_id, actor_type: ActorTypeEnum, action: AuditActionEnum, target_type: TargetTypeEnum, target_id, metadata: Option<serde_json::Value>) which:
      • Generates a new id via IdInstance::next_id().
      • Fills all enum fields using callisto-generated types to stay aligned with the DB schema.
      • Converts optional JSON metadata into Json.
      • Sets created_at = Utc::now() and inserts a row into audit_logs.
    • Update storage::mod:
      • Register pub mod audit_storage;.
      • Add audit_storage: AuditStorage to Storage / AppService, initialize it in Storage::new() and AppService::mock().
      • Expose pub fn audit_storage(&self) -> AuditStorage for higher layers.
    • Intended usage:
      • Record bot token lifecycle events (generate / revoke / revoke_all).
      • Record bot-initiated business API calls with appropriate actor_type = Bot, target_type, target_id, and richer metadata (bot ID, permission scope, installation targets, API path, decision results, etc.).
  • Mono HTTP API for bot token management

    • Add bot_router that exposes admin-only bot token endpoints, all requiring authenticated LoginUser and an ensure_admin check:
      • POST /api/v1/bots/{bot_id}/tokens
        • Creates a new bot token using Jupiter BotsStorage::generate_bot_token.
        • Returns the plaintext token once (token_plain), plus metadata.
      • GET /api/v1/bots/{bot_id}/tokens
        • Lists existing tokens for a bot without exposing plaintext values.
      • DELETE /api/v1/bots/{bot_id}/tokens/{id}
        • Revokes a single token; the operation is idempotent.
      • POST /api/v1/bots/{bot_id}/tokens/revoke_all
        • Revokes all tokens for the given bot; also idempotent.
    • Define request/response DTOs for token creation and listing; tag endpoints and schemas with BOT_TAG = "Bot Management" for OpenAPI.
    • Register bot_router in the main api_router so the endpoints are served under /api/v1.
    • Expose bots_storage() from Jupiter Storage so Mono can call:
      • generate_bot_token
      • list_bot_tokens
      • revoke_bot_token
      • revoke_bot_tokens_by_bot

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d43d06e12

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread jupiter/src/storage/bots_storage.rs
Comment thread mono/src/api/router/bot_router.rs Outdated
Comment thread mono/src/api/router/bot_router.rs Fixed

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

Adds bot-token lifecycle support across the stack: a new Mono HTTP router for admin-only bot token management, plus new Jupiter storage capabilities for generating/listing/revoking/looking up bot tokens and writing audit-log entries.

Changes:

  • Add /api/v1/bots/{bot_id}/tokens endpoints in Mono (create/list/revoke/revoke_all) with OpenAPI tagging.
  • Extend Jupiter BotsStorage with HMAC-hashed bot token storage + lookup helpers and expose bots_storage() from Storage.
  • Introduce AuditStorage as a centralized audit-log insert entrypoint.

Reviewed changes

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

Show a summary per file
File Description
mono/src/server/http_server.rs Adds BOT_TAG OpenAPI tag constant.
mono/src/api/router/mod.rs Registers the new bot_router module.
mono/src/api/router/bot_router.rs Implements admin-only bot token management HTTP APIs + schemas.
mono/src/api/api_router.rs Merges bot_router into the main API router.
jupiter/src/storage/mod.rs Wires in AuditStorage, exposes audit_storage() and bots_storage().
jupiter/src/storage/bots_storage.rs Implements token generate/list/revoke/find using HMAC hashing.
jupiter/src/storage/audit_storage.rs Adds AuditStorage::log_audit insert helper.
jupiter/src/model/bot_token_dto.rs Adds BotTokenInfo DTO for listing token metadata without plaintext.

Comment thread jupiter/src/storage/bots_storage.rs Outdated
Comment thread jupiter/src/storage/bots_storage.rs Outdated
Comment thread mono/src/api/router/bot_router.rs Outdated
Comment on lines +137 to +141
/// Generate a new bot token, persist its HMAC-SHA256 hash and return the model with plaintext.
pub async fn generate_bot_token(
&self,
bot_id: i64,
token_name: &str,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

后续补充测试

Comment thread jupiter/src/storage/audit_storage.rs Outdated
Comment thread jupiter/src/storage/bots_storage.rs
Comment thread jupiter/src/storage/bots_storage.rs
Comment thread jupiter/src/storage/audit_storage.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff087c4e30

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +160 to +162
let models = bot_tokens::Entity::find()
.filter(bot_tokens::Column::BotId.eq(bot_id))
.order_by_desc(bot_tokens::Column::CreatedAt)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return 404 when listing tokens for unknown bots

list_bot_tokens only queries bot_tokens by bot_id and never verifies that the bot exists, so an invalid bot_id yields an empty list and the handler returns 200. That behavior conflicts with the endpoint contract in mono/src/api/router/bot_router.rs (which documents 404 for missing bots) and makes a typoed/stale bot ID indistinguishable from a valid bot with zero tokens.

Useful? React with 👍 / 👎.

Comment on lines +182 to +186
if let Some(model) = bot_tokens::Entity::find_by_id(token_id)
.filter(bot_tokens::Column::BotId.eq(bot_id))
.one(conn)
.await?
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return 404 when token revoke matches no record

revoke_bot_token silently succeeds when no row matches (bot_id, token_id) because the method falls through when the query returns None. This means DELETE /bots/{bot_id}/tokens/{id} can return success even though no token was revoked, which can leave compromised tokens active while callers believe cleanup succeeded and also contradicts the route’s documented 404 behavior for missing bot/token.

Useful? React with 👍 / 👎.

@WiedersehenM

Copy link
Copy Markdown
Contributor Author

本次提交进行的修复

1. jupiter/src/model/mod.rs

  • 修改:增加 pub mod bot_token_dto;,使 crate::model::bot_token_dto::BotTokenInfo 可被正常引用,解决 Copilot 指出的「BotsStorage 引用未导出模块」问题。

2. jupiter/src/storage/bots_storage.rs

  • get_bot_by_id:新增 get_bot_by_id(bot_id),按 ID 查询 bot,供 API 在操作前校验 bot 是否存在并返回 404。
  • revoke_bot_tokens_by_bot:改为用 bot_tokens::Entity::update_many() 一次批量更新(SET revoked = true WHERE bot_id = ? AND revoked = false),去掉「先 find 再逐条 update」的 N+1 循环。
  • HMAC secret 校验:在 load_bot_token_hmac_key() 中增加:
    • 非空校验(trim 后不能为空);
    • 最小长度 32 字符;
    • 不满足时返回明确的 MegaError::Other 错误信息。
  • find_bot_by_token 时间类型:将 now 改为 DateTimeWithTimeZonelet now: DateTimeWithTimeZone = Utc::now().into();,与 ExpiresAt 列类型一致,避免类型/比较问题。
  • import:为 update_many 使用增加 Exprprelude::{DateTimeWithTimeZone, Expr}

3. jupiter/src/storage/audit_storage.rs

  • created_at 类型:使用 DateTimeWithTimeZone 写入:
    • 增加 use sea_orm::prelude::DateTimeWithTimeZone
    • 使用 let created_at: DateTimeWithTimeZone = Utc::now().into();Set(created_at),与 audit_logs.created_at 列类型一致。

4. mono/src/api/router/bot_router.rs

  • Bot 存在性 → 404:新增 ensure_bot_exists(state, bot_id),在以下四个 handler 中、调用 storage 前先调用:
    • create_bot_token
    • list_bot_tokens
    • revoke_bot_token
    • revoke_all_bot_tokens
      若 bot 不存在则返回 ApiError::not_found("Bot not found"),与文档中的 404 约定一致。
  • expires_in 范围校验:在 create_bot_token 中:
    • 定义 MIN_EXPIRES_IN_SECS = 1MAX_EXPIRES_IN_SECS = 10 年(秒)
    • req.expires_inSome(seconds) 时,若不在 [MIN, MAX] 内则返回 ApiError::bad_request,并仅在合法时做 Utc::now() + Duration::seconds(seconds),避免极端 i64 导致 panic。
  • 依赖:增加 use anyhow::anyhow,用于 not_found / bad_request 的错误信息。

未修改项

  • CodeQL:Cleartext logging of sensitive information

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b2a47a538

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

let conn = self.get_connection();

let token = bot_tokens::Entity::find()
.filter(bot_tokens::Column::TokenHash.eq(token_hash))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Index token hash lookups for bot authentication

find_bot_by_token authenticates by querying bot_tokens on token_hash, but the schema currently only defines idx_bot_tokens_bot_id and uq_bot_tokens_name_hash(bot_id, token_name, token_hash) (see jupiter/src/migration/m20260306_121829_create_bots_related_table.rs), so this predicate has no efficient leading-column index and will devolve into scans as token rows grow; that can materially increase latency for every bot-authenticated request path using this function.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6924b8d9d6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +73 to +76
.routes(routes!(create_bot_token))
.routes(routes!(list_bot_tokens))
.routes(routes!(revoke_bot_token))
.routes(routes!(revoke_all_bot_tokens)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore bot installation routes in bot router

The router registration now includes only token-management handlers, so the previously exposed installation endpoints under /api/v1/bots/{id}/installations are no longer mounted. I checked mono/src/api/router for moved handlers (rg "installations") and found no replacement routes, while installation storage methods still exist in Jupiter, which means existing installation workflows will regress to 404 after this change.

Useful? React with 👍 / 👎.

@WiedersehenM

Copy link
Copy Markdown
Contributor Author

修复 Clippy 报错:在 AuditStorage::log_audit 中去掉对 metadata 的多余 map(Into::into) 调用,直接使用 Option<serde_json::Value>,消除了 clippy::useless-conversion 警告。

修复 mono 编译失败):在 bot_router 中的 revoke_bot_token 和 revoke_all_bot_tokens 两个接口上,调整 #[utoipa::path] 的 responses 描述,取消 body = CommonResult<()>,改为只保留 200 状态码的文本描述,从而避免 utoipa 对 () 类型解析时的 TypeTree must have a path panic,routes! 宏恢复正常展开。

Codex 的性能建议:新增迁移 m20260316_120000_add_bot_tokens_token_hash_index,为 bot_tokens.token_hash 创建单列索引 idx_bot_tokens_token_hash,并在 migration::mod 中注册该迁移,以优化 find_bot_by_token 中按 token_hash 的查询性能,避免未来在 Bot 请求量增大时退化为全表扫描。

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 736130f550

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +73 to +76
.routes(routes!(create_bot_token))
.routes(routes!(list_bot_tokens))
.routes(routes!(revoke_bot_token))
.routes(routes!(revoke_all_bot_tokens)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore bot installation routes in bot router

The router now mounts only token-management handlers, so the previously available installation APIs under /api/v1/bots/{id}/installations are no longer reachable and will return 404 after this change. I checked the updated router registration here and there is no replacement installation route in mono/src/api/router for this commit, while installation storage operations still exist in Jupiter, so existing install/list/update/uninstall client flows regress at runtime.

Useful? React with 👍 / 👎.

@WiedersehenM

Copy link
Copy Markdown
Contributor Author

本次提交进行的修改

1. Bot 身份提取:从 HTTP Header 到 Jupiter 校验

  • 新增 BotIdentity 提取器:在 oauth::mod.rs 中新增 BotIdentity { bot: bots::Model, token: bot_tokens::Model },并实现 FromRequestParts,使其可以像 LoginUser 一样作为 Handler 的 Extractor 使用。
  • 解析并校验 Authorization: Bearer bot_<token>
    • 从请求头读取 TypedHeader<Authorization<Bearer>>,失败直接返回 AuthRedirect(401)
    • 校验 Bearer token 必须以 "bot_" 前缀开头,否则返回 AuthRedirect,避免 Bot 路径误用 Human Token。
    • 去掉前缀后,通过 MonoApiServiceState::from_ref(state) 获取 state.storage.bots_storage(),调用 BotsStorage::find_bot_by_token,只接受 未撤销且未过期 的 token。
    • 校验通过时返回 BotIdentity { bot, token },失败则记录日志并返回 AuthRedirect
  • 依赖与集成方式
    • 引入 use callisto::{bot_tokens, bots}; 使用 Model 类型。
    • 复用现有的 MonoApiServiceStateFromRefAuthRedirect,不影响原有人类登录 LoginUser 流程。

2. Ceres 层统一的 Bot 权限检查入口

  • 新增 bot_ops 模块并对外暴露
    • api_service 下新增 bot_ops.rs,并在 mod.rspub mod bot_ops;,为 Mono / 上层 Handler 提供统一 Bot 权限检查接口。
  • 实现 MonoApiService::check_bot_permission
    • 签名:
      check_bot_permission(&self, bot_id: i64, resource_type: ResourceTypeEnum, resource_id: &str, required_permission: PermissionEnum) -> Result<bool, MegaError>
      其中 resource_typeresource_id 暂作为保留字段,用于后续按资源类型精细化安装范围判断。
    • 校验逻辑分为三层
      1. Bot 自身状态
        • 通过 self.storage.bots_storage().get_bot_by_id(bot_id) 获取 Bot;
        • 若不存在或 BotStatusEnum != Enabled,直接返回 Ok(false)
      2. 安装范围检查
        • 调用 get_installed_bot_by_id(bot_id) 查询安装记录;
        • 若没有任何 InstallationBotStatusEnum::Enabled 安装,同样返回 Ok(false),保证 Bot 至少安装在某个启用目标上。
      3. 权限等级比较
        • 从 Bot 记录中读取 permission_scope: PermissionScopeEnum
        • PermissionScopeEnumrequired_permission: PermissionEnum 做等级比较(Read < Write < Admin);
        • 只有当 scope_level >= permission_level(required_permission) 才返回 Ok(true),否则 Ok(false)

3. Cedar Guard 中区分 Human / Bot principal

  • 引入 Bot principal 支持
    • cedar_guard.rs 中导入 BotIdentity,在中间件中从 req.extensions() 同时尝试读取 LoginUser(Human)和 BotIdentity(Bot)。
  • 根据身份构造不同的 Cedar principal
    • 若存在 BotIdentity
      • 使用 principal_type = "Bot"principal_id = bot.bot.id.to_string(),在 Cedar 侧表现为 Bot::<bot_id>
    • 若不存在 BotIdentity 但存在 LoginUser
      • 使用 principal_type = "User"principal_id = username,保持 Human 流程不变(User::<username>)。
    • 若两者都不存在:
      • 继续沿用原有的回退逻辑,使用默认的 User::reader principal。

…using HMAC-SHA256 with an env-based secret, storing only token hashes and metadata while returning plaintext once on creation

- Implement listing, single revoke, bulk revoke, and plaintext-based lookup (with bot_ prefix) for bot tokens to support authentication flows

- Introduce AuditStorage wrapper around BaseStorage with a log_audit API using ActorTypeEnum / AuditActionEnum / TargetTypeEnum and JSON metadata

- Expose audit_storage from Storage/AppService so Mono and Ceres can record bot token lifecycle events and bot access audits

- Add bot_router with /api/v1/bots/{bot_id}/tokens CRUD-style endpoints and DTOs for creating, listing, and revoking bot tokens, including OpenAPI documentation and BOT_TAG swagger tag

- Wire bot_router into api_router and expose bots_storage() from Jupiter Storage so Mono can call bot token storage APIs

Signed-off-by: Hongze Gao <15101764808@163.com>
Signed-off-by: Hongze Gao <15101764808@163.com>
…le and storage

- Export bot_token_dto in jupiter model so BotTokenInfo is reachable
- BotsStorage: add get_bot_by_id() for bot existence checks
- BotsStorage: use update_many() in revoke_bot_tokens_by_bot to avoid N+1
- BotsStorage: validate HMAC secret (non-empty, min 32 chars) in load_bot_token_hmac_key
- BotsStorage: use DateTimeWithTimeZone for expiry comparison in find_bot_by_token
- AuditStorage: set created_at with DateTimeWithTimeZone (Utc::now().into())
- bot_router: ensure bot exists before create/list/revoke; return 404 when missing
- bot_router: validate expires_in range (1..=10y) to avoid overflow/panic
- tests: add audit_storage to AppService in test_storage()

Signed-off-by: Hongze Gao <15101764808@163.com>
…r token hash

- Resolve Clippy  warning in
  by removing the redundant  conversion.
- Fix mono OpenAPI annotations for bot token revoke endpoints by avoiding
   as a documented response body, preventing utoipa
- Add a dedicated  index via a new migration to
  optimize  lookups in  and address
  authentication path performance concerns.

Signed-off-by: Hongze Gao <15101764808@163.com>
…nference

- Import  and installation enums (,
  ) from  in  so installation
  queries and models resolve correctly.
- Implement bot installation management helpers in :
  , , ,
  and .
- Add explicit  /  type annotations
  around SeaORM  calls to satisfy the compiler and
  eliminate  type inference errors in CI.

Signed-off-by: Hongze Gao <15101764808@163.com>
…incipal support

- Introduce BotIdentity extractor in the mono OAuth module to validate 'Bearer bot_' tokens via Jupiter BotsStorage
- Add MonoApiService::check_bot_permission in Ceres to combine bot status, installation scope, and permission_scope for authorization
- Update Cedar guard to distinguish human and bot principals while keeping the current permit-all policy

Signed-off-by: Hongze Gao <15101764808@163.com>
- Re-add /api/v1/bots/{id}/installations endpoints (install/list/update/uninstall) that were
accidentally dropped when introducing bot token management routes.
- Keep token management routes mounted while preserving backward compatibility for existing
installation client workflows.

Signed-off-by: Hongze Gao <15101764808@163.com>
@genedna genedna requested a review from Copilot March 17, 2026 14:15
@genedna

genedna commented Mar 17, 2026

Copy link
Copy Markdown
Collaborator

@codex review

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

This PR adds end-to-end bot token lifecycle support across the stack: secure token generation/storage in Jupiter, admin-only HTTP management endpoints in Mono, and initial bot-aware identity/permission plumbing plus audit logging support.

Changes:

  • Add HMAC-based bot token storage + lookup/revocation APIs in jupiter::BotsStorage, plus a non-plaintext DTO for listing tokens.
  • Introduce AuditStorage as a centralized writer for audit_logs, and wire it into Storage/test helpers.
  • Add Mono /api/v1/bots/{bot_id}/tokens admin endpoints (create/list/revoke/revoke_all) and introduce BotIdentity extraction for bot-auth flows.

Reviewed changes

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

Show a summary per file
File Description
mono/src/server/http_server.rs Rename/standardize the OpenAPI tag constant for bot management endpoints.
mono/src/api/router/bot_router.rs Add admin-only bot token management endpoints and related request/response DTOs.
mono/src/api/oauth/mod.rs Add BotIdentity extractor to validate bot_ bearer tokens via Jupiter storage.
mono/src/api/guard/cedar_guard.rs Update authorization principal resolution to distinguish Bot vs User (but currently via request extensions).
jupiter/src/tests.rs Extend test storage wiring to include AuditStorage.
jupiter/src/storage/mod.rs Register and expose AuditStorage from Storage/AppService.
jupiter/src/storage/bots_storage.rs Implement bot token generate/list/revoke/find-by-token with HMAC hashing + expiry/revocation filtering.
jupiter/src/storage/audit_storage.rs Add AuditStorage::log_audit writer for audit_logs.
jupiter/src/model/mod.rs Export the new bot token DTO module.
jupiter/src/model/bot_token_dto.rs Add BotTokenInfo DTO for safe token listing without plaintext.
jupiter/src/migration/mod.rs Register the new bot token hash index migration.
jupiter/src/migration/m20260316_120000_add_bot_tokens_token_hash_index.rs Add an index on bot_tokens.token_hash to speed up token lookup.
ceres/src/api_service/mod.rs Register new bot operations module.
ceres/src/api_service/bot_ops.rs Add a basic check_bot_permission helper (bot enabled + has enabled installation + scope check).

Comment on lines +141 to 150
let login_user = req.extensions().get::<LoginUser>();
let bot_identity = req.extensions().get::<BotIdentity>();

let _username = match user {
Some(user) => user.username,
None => "reader".to_string(),
let (principal_type, principal_id) = if let Some(bot) = bot_identity {
("Bot".to_string(), bot.bot.id.to_string())
} else if let Some(user) = login_user {
("User".to_string(), user.username.clone())
} else {
("User".to_string(), "reader".to_string())
};
(status = 200, description = "Token revoked successfully"),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Forbidden - admin only"),
(status = 404, description = "Bot or token not found"),
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

We were unable to download your code in a timely manner.
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@benjamin-747 benjamin-747 added this pull request to the merge queue Mar 18, 2026
Merged via the queue into gitmono-dev:main with commit 0ac3d61 Mar 18, 2026
12 checks passed
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.

5 participants