本番環境ログと認証強化による信頼性構築
スマートロック管理のようなセキュリティ重要なシステムでは、運用可視性と認証堅牢性への細心の注意を通じて信頼が構築されます。UnlockOS SDKの最近の改善により、開発者体験を維持しながら本番環境システムを強化するための重要なパターンが実証されています。
環境対応ログ戦略
本番環境システムでは開発環境とは異なるログアプローチが必要です。環境固有のログレベルを実装することで、運用可視性を維持しながら情報漏洩を防げます:
interface LogConfig {
level: 'debug' | 'info' | 'warn' | 'error';
sensitiveFields: string[];
maxLogSize: number;
}
class SecureLogger {
private config: LogConfig;
constructor(environment: 'development' | 'staging' | 'production') {
this.config = {
level: environment === 'production' ? 'warn' : 'debug',
sensitiveFields: ['password', 'token', 'key', 'secret'],
maxLogSize: environment === 'production' ? 1000 : 5000
};
}
log(level: string, message: string, data?: any) {
if (this.shouldLog(level)) {
const sanitized = this.sanitizeData(data);
console[level](message, sanitized);
}
}
private sanitizeData(data: any): any {
if (!data) return data;
const sanitized = { ...data };
this.config.sensitiveFields.forEach(field => {
if (sanitized[field]) {
sanitized[field] = '[REDACTED]';
}
});
return sanitized;
}
}OAuth State管理と再認証防止
スマートロックシステムの認証フローは完璧である必要があります。重要な改善として、OAuthコールバック後の意図しない再認証を防ぐ機能を実装しました:
class AuthenticationManager {
private oauthState: Map<string, {
timestamp: number;
used: boolean;
redirectUrl: string;
}> = new Map();
async handleOAuthCallback(code: string, state: string): Promise<void> {
const stateData = this.oauthState.get(state);
// リプレイ攻撃と重複処理を防ぐ
if (!stateData || stateData.used ||
Date.now() - stateData.timestamp > 300000) { // 5分で期限切れ
throw new Error('Invalid or expired OAuth state');
}
// stateを即座に使用済みとしてマーク
stateData.used = true;
this.oauthState.set(state, stateData);
try {
await this.exchangeCodeForToken(code);
// メインアプリによる再認証トリガーを防ぐ
this.clearAuthenticationTriggers();
} catch (error) {
this.logAuthenticationFailure(error, { state, timestamp: Date.now() });
throw error;
}
}
private clearAuthenticationTriggers(): void {
// 保留中の認証リクエストをクリア
sessionStorage.removeItem('pending_auth');
localStorage.removeItem('auth_redirect');
}
}セキュリティ強化としての機能削除
機能を削除することは、機能を追加することと同じくらい重要です。「ゲストモード」の削除により、攻撃面を減らすことでセキュリティ態勢が改善されることが実証されています:
// 以前:ゲストモード付きの複雑なアクセス制御
interface AccessControl {
userType: 'admin' | 'host' | 'guest';
permissions: Permission[];
guestLimitations?: GuestLimitation[];
}
// 以後:簡略化されたより安全なアクセス制御
interface AccessControl {
userType: 'admin' | 'host';
permissions: Permission[];
authenticationRequired: true;
}
class SecurityAudit {
static validateAccess(user: AuthenticatedUser, resource: Resource): boolean {
// ゲストモードなし = 非認証アクセスパスなし
if (!user.isAuthenticated) {
this.logUnauthorizedAccess(user.id, resource.id);
return false;
}
return this.checkPermissions(user.permissions, resource.requiredPermissions);
}
}Row-Level Security(RLS)ポリシー強化
Row-Level Securityポリシーによるデータベースセキュリティは、アプリケーションレベルのチェックが失敗してもデータ分離を保証します:
-- 安全な役割権限アクセス
CREATE POLICY "role_permission_details_select" ON role_permission_details
FOR SELECT USING (
EXISTS (
SELECT 1 FROM user_organization_roles uor
WHERE uor.user_id = auth.uid()
AND uor.organization_id = role_permission_details.organization_id
AND uor.role IN ('admin', 'manager')
)
);
-- ポリシー違反の監査証跡
CREATE OR REPLACE FUNCTION log_rls_violation()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO security_audit_log (user_id, table_name, action, timestamp)
VALUES (auth.uid(), TG_TABLE_NAME, TG_OP, NOW());
RETURN NULL;
END;
$$ LANGUAGE plpgsql;本番環境対応エラーハンドリング
堅牢なエラーハンドリングは、運用可視性を維持しながら情報漏洩を防ぎます:
class ProductionErrorHandler {
static handlePaymentError(error: unknown, context: PaymentContext): PaymentResult {
const errorId = this.generateErrorId();
// 詳細なエラーを内部的にログ
logger.error('Payment processing failed', {
errorId,
error: error instanceof Error ? error.message : 'Unknown error',
stack: error instanceof Error ? error.stack : undefined,
context: this.sanitizeContext(context)
});
// サニタイズされたエラーをクライアントに返す
return {
success: false,
errorId,
message: this.getPublicErrorMessage(error),
retryable: this.isRetryable(error)
};
}
private static getPublicErrorMessage(error: unknown): string {
// 内部エラー詳細を決して公開しない
if (error instanceof ValidationError) {
return error.publicMessage;
}
return 'An error occurred. Please contact support with error ID.';
}
}容量管理とシステム制限
容量制限を実装することで、システム濫用を防ぎ公平なリソース配分を保証します:
interface CapacityConfig {
maxOccupancy: number;
warningThreshold: number; // 最大値の80%
blockNewCheckins: boolean;
}
class OccupancyManager {
async validateCheckIn(facilityId: string): Promise<CheckInValidation> {
const current = await this.getCurrentOccupancy(facilityId);
const config = await this.getCapacityConfig(facilityId);
const congestionRate = (current / config.maxOccupancy) * 100;
if (config.blockNewCheckins && current >= config.maxOccupancy) {
this.logCapacityViolation(facilityId, current, config.maxOccupancy);
return {
allowed: false,
reason: 'CAPACITY_EXCEEDED',
congestionRate
};
}
return {
allowed: true,
congestionRate,
warning: congestionRate > 80
};
}
}まとめ
セキュリティ重要なシステムでの信頼構築には以下が必要です:
- 多層ログ: 機密データサニタイゼーション付きの環境固有ログレベル
- 認証強化: 適切なstate管理とリプレイ攻撃防止
- 攻撃面削減: ゲストモードなどの不要機能の削除
- データベースセキュリティ: 多層防御としてのRow-Level Securityポリシー
- 本番環境エラーハンドリング: 情報漏洩のない内部可視性
- システム制限: 濫用防止のための容量管理
これらのパターンにより、セキュリティは単なる機能ではなく、システムアーキテクチャの基本的特性となることが保証されます。