agent/php/Mod/Api/Boot.php
Snider 5385385314 feat(agent/api): RFC foundation — API keys, webhooks, rate limiting, docs split
Foundation slice for Mantis #844 php/Mod/Api RFC implementation:

* New php/Mod/Api/ package: Boot, Controllers, Documentation, Jobs,
  Middleware, Models, RateLimit, Routes, Services
* Models: ApiKey, WebhookEndpoint, WebhookDelivery
* WebhookService::dispatch() with DB::transaction + afterCommit
* DeliverWebhookJob with retry/backoff
* WebhookSignature with timing-safe verification + 5-minute tolerance +
  dual-secret rotation support
* Sliding-window rate limiter in RateLimit/RateLimitService.php
* AuthenticateApiKey middleware: hk_ prefix + Sanctum fallback
* DocsController / DocumentationController split
* 3 root migrations: api_keys, webhook_endpoints, webhook_deliveries
* Foundation tests under php/tests/Feature/Mod/Api/
* FOLLOWUP.md tracks remaining RFC scope

php -l clean across 21 PHP files. Pest unrunnable in sandbox (no vendor/).

Co-authored-by: Codex <noreply@openai.com>
Closes tasks.lthn.sh/view.php?id=844
2026-04-25 21:01:54 +01:00

46 lines
1.4 KiB
PHP

<?php
// SPDX-License-Identifier: EUPL-1.2
declare(strict_types=1);
namespace Core\Mod\Agentic\Mod\Api;
use Core\Events\ApiRoutesRegistering;
use Core\Mod\Agentic\Mod\Api\Documentation\Middleware\ProtectDocumentation;
use Core\Mod\Agentic\Mod\Api\RateLimit\RateLimitService;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Illuminate\Support\ServiceProvider;
class Boot extends ServiceProvider
{
/**
* Events this module listens to for lazy loading.
*
* @var array<class-string, string>
*/
public static array $listens = [
ApiRoutesRegistering::class => 'onApiRoutes',
];
public function register(): void
{
$this->app->singleton(RateLimitService::class, function ($app): RateLimitService {
return new RateLimitService($app->make(CacheRepository::class));
});
$this->app->singleton(Services\WebhookSignature::class);
$this->app->singleton(Services\WebhookService::class);
}
public function onApiRoutes(ApiRoutesRegistering $event): void
{
$event->middleware('api.auth', Middleware\AuthenticateApiKey::class);
$event->middleware('auth.api', Middleware\AuthenticateApiKey::class);
$event->middleware('api.docs.protect', ProtectDocumentation::class);
if (file_exists(__DIR__.'/Routes/api.php')) {
$event->routes(fn () => require __DIR__.'/Routes/api.php');
}
}
}