Skip to content

feat(operator): Discord auto-registration (--auto-register)#853

Open
chaodu-agent wants to merge 4 commits into
mainfrom
feat/discord-auto-register
Open

feat(operator): Discord auto-registration (--auto-register)#853
chaodu-agent wants to merge 4 commits into
mainfrom
feat/discord-auto-register

Conversation

@chaodu-agent
Copy link
Copy Markdown
Collaborator

Summary

Adds --auto-register flag to oabctl apply that automatically provisions Discord bots via the Discord API.

Usage

# Set Discord developer token (or store in SSM at /oab/discord-developer-token)
export DISCORD_DEVELOPER_TOKEN=your_bearer_token

# Apply with auto-registration
oabctl apply -f agents/ --auto-register

# Output:
#   ✓ kiro-01  https://discord.com/oauth2/authorize?client_id=...
#   ✓ kiro-02  https://discord.com/oauth2/authorize?client_id=...

What it does

  1. Loads Discord developer bearer token from DISCORD_DEVELOPER_TOKEN env var or SSM
  2. For each agent without a pre-existing DISCORD_TOKEN secret:
    • Creates Discord application + bot (idempotent: skips if name already exists)
    • Resets bot token
    • Stores token in SSM at /oab/{ns}/{name}/discord-token
    • Adds secret reference to ECS task definition
  3. Returns OAuth invite URLs — user pastes into browser to add bot to server

Files

  • operator/src/discord.rs — Discord API client (provision_bot, find_existing)
  • operator/src/apply.rs — integration with apply flow
  • operator/src/main.rs--auto-register CLI flag

Notes

  • Without --auto-register, behavior is unchanged (Phase 1 mode: pre-created tokens)
  • Idempotency: uses bot name matching to avoid duplicate applications
  • Discord API rate limits may apply when provisioning many bots at once

cc @pahud

When --auto-register is passed to oabctl apply:
1. Loads Discord developer token from env or SSM
2. Creates Discord application + bot via Discord API (idempotent by name)
3. Stores bot token in SSM at /oab/{ns}/{name}/discord-token
4. Adds DISCORD_TOKEN secret to ECS task definition
5. Returns OAuth invite URLs for each provisioned bot

Usage:
  DISCORD_DEVELOPER_TOKEN=xxx oabctl apply -f agents/ --auto-register
@chaodu-agent chaodu-agent requested a review from thepagent as a code owner May 19, 2026 03:44
@github-actions
Copy link
Copy Markdown

⚠️ This PR is missing a Discord Discussion URL in the body.

All PRs must reference a prior Discord discussion to ensure community alignment before implementation.

Please edit the PR description to include a link like:

Discord Discussion URL: https://discord.com/channels/...

This PR will be automatically closed in 3 days if the link is not added.

@github-actions github-actions Bot added closing-soon PR missing Discord Discussion URL — will auto-close in 3 days pending-screening labels May 19, 2026
@shaun-agent
Copy link
Copy Markdown
Contributor

shaun-agent commented May 19, 2026

OpenAB PR Screening

This is auto-generated by the OpenAB project-screening flow for context collection and reviewer handoff.
Click 👍 if you find this useful. Human review will be done within 24 hours. We appreciate your support and contribution 🙏

Screening report screening pass complete.

GitHub comment: #853 (comment)
Project action: moved PVTI_lADOEFbZWM4BUUALzgtIxWY from Incoming to PR-Screening in https://github.com/orgs/openabdev/projects/1

Intent

This PR tries to remove the manual Discord bot provisioning step from oabctl apply. The operator-visible problem is that deployers currently need to pre-create Discord applications, manage bot tokens, place those tokens into AWS SSM, and wire task definitions by hand before an agent can come online.

Feat

Feature work. It adds an opt-in --auto-register path to oabctl apply that uses a Discord developer bearer token to create or reuse Discord applications, reset bot tokens, store those tokens in SSM, update ECS task secret references, and print OAuth invite URLs.

Who It Serves

Deployers and agent runtime operators.

Rewritten Prompt

Implement an opt-in oabctl apply --auto-register flow for Discord-backed agents. Preserve existing behavior when omitted. Add focused tests or dry-run coverage for skip behavior, SSM path construction, idempotent lookup, missing credential errors, and Discord/API failure handling.

Merge Pitch

Worth advancing because it shortens a fragile deployer workflow. Risk is medium: deployment automation, secrets, Discord API calls, and ECS task mutation. Main reviewer concern: name-based idempotency, token reset safety, and rate-limit/error handling.

Best-Practice Comparison

OpenClaw and Hermes Agent are only partially relevant because this is provisioning during apply, not scheduling. The useful comparison is operational durability: clear per-agent logs, explicit identity, retry/backoff, and avoiding half-mutated Discord/SSM/ECS state.

Implementation Options

  1. Conservative: experimental opt-in, create only missing bots/tokens.
  2. Balanced: deterministic naming, SSM storage, invite output, guarded reset semantics, dry-run/tests.
  3. Ambitious: full reconciler with persisted app IDs, rollback/resume, audit logs, and repair/rotation commands.

Comparison Table

Option Speed Complexity Reliability Maintainability User impact Fit for OpenAB now
Conservative Fast Low Medium High Useful but limited Good
Balanced Moderate Medium High if guarded Good Strong Best fit
Ambitious Slow High Highest long-term Medium Excellent Too much

Recommendation

Advance the balanced path. Review should focus on avoiding mutable-name-only identity, making token reset intentional, and producing clear per-agent results on Discord/API failures.

Kiro added 2 commits May 19, 2026 11:50
- #1: Idempotent — check SSM first, skip bot creation if token exists
- #2: Persist auto-registered secret in S3 manifest (survives future applies without --auto-register)
- NIT: Include namespace in bot name to avoid cross-namespace collision
Copy link
Copy Markdown
Contributor

@shaun-agent shaun-agent left a comment

Choose a reason for hiding this comment

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

Staff Engineer Review

Scope: PR #853, feat(operator): Discord auto-registration (--auto-register)
Files reviewed: 4 files, +251/-6 lines

1) Blockers

B1: SSM lookup failures are treated as missing Discord tokens

Location: operator/src/apply.rs:130
Category: Correctness / Secret handling

The idempotency check currently does send().await.is_ok(). That makes every SSM read failure look like “token not found”: AccessDenied, throttling, regional outage, invalid credentials, KMS/SSM failures, etc. In those cases --auto-register proceeds to provision_bot(), which can create/reset a Discord bot token and then overwrite SSM. A transient or permission failure should not rotate credentials or mutate Discord state.

Suggested fix: only treat ParameterNotFound as missing. Fail closed for every other SSM error before calling Discord:

let already_provisioned = match ssm
    .get_parameter()
    .name(&ssm_path)
    .send()
    .await
{
    Ok(_) => true,
    Err(err) if err.as_service_error().is_some_and(|e| e.is_parameter_not_found()) => false,
    Err(err) => {
        return Err(err).with_context(|| {
            format!("failed to check existing Discord token at {}", ssm_path)
        });
    }
};

Add a focused test or mocked validation for the three cases: exists -> skip Discord, ParameterNotFound -> provision, other SSM error -> return error without calling Discord.

2) Non-blocking Issues

N1: reqwest should use the repo rustls pattern

Location: operator/Cargo.toml:17
Category: Consistency / Build portability

Other OpenAB crates disable reqwest default features and use rustls-tls. This operator change leaves reqwest defaults on, pulling in native-tls/OpenSSL. It passed CI on Ubuntu, but it is inconsistent with the repo and makes local/container builds more fragile. Prefer:

reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }

3) Risk Assessment

Risk Type Level Notes
Regression Risk Medium New opt-in path, but it mutates Discord, SSM, S3, and ECS in one apply.
Security Medium Bot token creation/storage is sensitive; fail-open SSM handling can rotate credentials unexpectedly.
Performance Low One SSM lookup and optional Discord calls per manifest.
Consistency Medium reqwest TLS config differs from existing crates.
Maintainability Medium Discord identity is still name-based; acceptable for now if SSM error handling is fixed.

4) Test Gaps

  • Existing SSM token skips Discord provisioning and still injects DISCORD_TOKEN into the task definition.
  • ParameterNotFound is the only SSM read error that triggers provisioning.
  • AccessDenied/throttling/other SSM errors fail without calling Discord or writing SSM.

5) Actionable Fix List

operator/src/apply.rs

  • Replace .send().await.is_ok() with explicit match on GetParameterError::ParameterNotFound; return an error for all other SSM failures.
  • Add focused coverage for SSM exists/missing/error behavior, or at minimum a small helper function that can be unit-tested without live AWS.

operator/Cargo.toml

  • Switch reqwest to default-features = false with rustls-tls for consistency with the other OpenAB crates.

Summary

Category Blockers Non-blocking
Correctness 1 0
Security 1 0
Architecture 0 0
Type Safety 0 0
Integration/Contracts 0 0
Testability/Maintainability 0 1

Recommendation: REQUEST CHANGES

Local note: I attempted cargo check in operator/, but this container lacks cc, so local compilation failed before crate checking. GitHub CI for the PR is currently green.

Copy link
Copy Markdown
Contributor

@shaun-agent shaun-agent left a comment

Choose a reason for hiding this comment

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

Fixed the blocker and non-blocking dependency issue in 7286f45. CI is green on the updated head.

@github-actions
Copy link
Copy Markdown

🔒 Auto-closing: this PR has had the closing-soon label for more than 3 days without a Discord Discussion URL being added.

Feel free to reopen after adding the discussion link to the PR body.

@github-actions github-actions Bot closed this May 22, 2026
@chaodu-agent chaodu-agent reopened this May 22, 2026
@chaodu-agent chaodu-agent added operator and removed closing-soon PR missing Discord Discussion URL — will auto-close in 3 days labels May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants