TuBrief
Subscribed Channels
Videos
Community

v0で作ったプロトタイプを企業DBに直接接続してはいけない理由と safeな接続法

TuBrief Editorial
July 23, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

日本語한국어EnglishEspañol中文العربيةहिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia

Related Video

Ship 26 NYC - SERHANTがいかにして一発勝負のAIをローンチしたか18:10

Ship 26 NYC - SERHANTがいかにして一発勝負のAIをローンチしたか

Vercel

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

v0で作ったプロトタイプを企業DB에 直接接続してはいけない理由と safeな接続法

非エンジニアの社員がv0やCursorのようなバイブコーディング(Vibe Coding)ツールを使って、わずか3日で立派なWebアプリを作ってきます。社長は大喜びで「今すぐ本番DBに繋いで顧客に使ってもらおう」と言い出すわけです。このとき、開発陣やCTOは冷や汗をかきます。AIが生成したコードを開いてみると、クライアントコンポーネントの真ん中にDB接続文字列(DSN)がそのまま埋め込まれていたり、なんの検証もなくSQLクエリを投げている状態だからです。

これをそのまま運用サーバーに上げたら、事故が起きるのは時間の問題です。OWASP Top 10 for LLM Applications 2025レポートでも、AI生成コードの過剰な権限付与(LLM06)と入力値の未検証(LLM05)が最も危険なセキュリティ要因として挙げられています。実際にWebアプリケーションのセキュリティ侵害事故の73%が、入力検証の不足を狙ったものです。

非エンジニアの生産性を削ぐことなく、会社のDBを守るためには、プロトタイプとDBの間に堅牢な統制レイヤーを配置する必要があります。

クライアントからのDB直接アクセスを遮断するZod検証レイヤー

まず最初に行うべきは、非エンジニアが作成したアプリがDBを直接呼び出せないよう、経路を塞ぐことです。Next.js App Routerのサーバールートハンドラーをプロキシとして配置し、中間でZodライブラリを用いて入ってくるデータをリアルタイムで検証する必要があります。TypeScriptの型チェックは開発時にのみ動作するものであり、実際のユーザーが異常なデータを送信した際にサーバーが落ちるのを防ぐことはできません。

検証項目 ブラウザUI側の検証 サーバーサイドZodプロキシレイヤー
実行場所 顧客のブラウザ Vercel Serverless Runtime
セキュリティ性 開発者ツールで容易に回避可能 サーバーで強制遮断してDBを保護
データ検証 形式的なテキストチェック 実行時の値の範囲および型を精密検証
失敗時の処理 画面に警告文を表示 HTTP 400返却およびSentryへエラー記録

構築の手順はシンプルです。

  1. プロジェクト内に app/api/v1/customer-records/route.ts ファイルを作成します。
  2. Zodスキーマを定義します。 companyName は最低2文字以上、 contactEmail はメールアドレス形式、 employeeCount は正の整数のみを受け付けるよう仕様を組みます。
  3. request.json() で入ってきたリクエストを schema.parse() で検査します。通過したデータのみをPrisma ORM経由でDBに挿入し、失敗した場合はその場で400エラーを返して弾きます。

アプリ側の検証と同時に、DB自体にも防壁を張る必要があります。PostgreSQLベースのSupabaseを使用している場合は、Row Level Security (RLS) の設定が最適解です。ユーザーの役割(ロール)情報を、ユーザーが操作可能な raw_user_meta_data ではなく、管理者のみが操作する raw_app_meta_data に保持し、JWTを検証します。

`sql
-- 1. テーブルのRLSを有効化
ALTER TABLE public.enterprise_documents ENABLE ROW LEVEL SECURITY;

-- 2. JWTからユーザーロールを抽出する関数を作成
CREATE OR REPLACE FUNCTION get_user_role()
RETURNS text AS

SELECTNULLIF(currentsetting(′request.jwt.claims′,true)::json−>′appmetadata′−>>′userrole′,′′);SELECT NULLIF(current_setting('request.jwt.claims', true)::json->'app_metadata'->>'user_role', '');SELECTNULLIF(currents​etting(′request.jwt.claims′,true)::json−>′appm​etadata′−>>′userr​ole′,′′);

LANGUAGE sql STABLE;

-- 3. 部署が同じか、管理者の場合のみ参照を許可するポリシー
CREATE POLICY "Department Access Policy" ON public.enterprise_documents
FOR SELECT USING (
get_user_role() = 'admin' OR
department = (current_setting('request.jwt.claims', true)::json->'app_metadata'->>'department')
);
`

この作業を行っておけば、非エンジニアが誤ってサービスロールキー(Service Role Key)をコードに漏洩させてしまったとしても、他部署の機密文書が流出するような事態は絶対に防げます。

ソースコードスキャンでAPIキーの流出を防ぐ

AIツールはまず画面を表示させることに集中するよう設計されているため、APIキーやDB接続文字列をブラウザに露出する場所に平気で記述します。最もよく見られるミスは、 NEXT_PUBLIC_ プレフィックスをむやみに付けることです。Next.jsにおいて、このプレフィックスが付いた変数BrowserのJavaScriptファイル内にプレーンテキストとして組み込まれます。 NEXT_PUBLIC_OPENAI_API_KEY のような変数を作成した瞬間、F12開発者ツールを開く知識がある人なら誰でもAPIキーを取得して自由に使うことができるようになってしまいます。

2026年4月にVercelインフラで発生したセキュリティ侵害事故を見ても明らかです。連携していたサードパーティAIツールの権限が突破されたことで、隠されていなかった環境変数が露出し、多くのチームが徹夜でDBパスワードやAPIキーを個別に再発行する羽目になりました。

このようなミスを目視で一つひとつ検品するのは不可能です。GitHub ActionsにGitleaks静的解析ツールを組み込み、コードをマージする前に自動で検出・排除する必要があります。

`yaml
name: Security Scan

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
gitleaks-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

  - name: Install and Run Gitleaks
    run: |
      wget https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz
      tar -xzvf gitleaks_8.18.0_linux_x64.tar.gz
      sudo mv gitleaks /usr/local/bin/
      gitleaks detect --source=. --verbose --redact --exit-code=1

public-env-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check Unsafe Public Keys
run: |
UNSAFE=(grep -rn "NEXT_PUBLIC_.*\(SECRET\|KEY\|PASSWORD\|TOKEN\|DSN\)" . || true) if [ -n "UNSAFE" ]; then
echo "クライアントに露出した機密変数を発見:"
echo "$UNSAFE"
exit 1
fi
`

このパイプラインをセットアップしておけば、非エンジニアがAPIキーをソースコードや NEXT_PUBLIC_ 変数に入れてPushした瞬間に、デプロイが自動的にブロックされます。

Vercelダッシュボードに変数を登録する際も、Development、Preview、Productionのスコープを明確に分ける必要があります。特に Sensitive Environment Variable チェックボックスは必ずオンにしてください。ビルドログに出力されず、ダッシュボード上でも平文のコピーができないよう暗号化されます。

障害発生時に非エンジニアでも30秒で復旧する方法

OpenAIやAnthropicのサーバーが停止したりレスポンスが遅延したりすると、サーバーレスハンドラー全体が待機状態に陥り、連鎖障害が発生します。このような場合は、Node.jsの opossum ライ브ラリを使ってサーキットブレーカーを設定する必要があります。

`typescript
import CircuitBreaker from 'opossum';

async function callLLM(prompt: string) {
// LLM API呼び出しロジック
}

const options = {
timeout: 5000, // 5秒を超えたら失敗処理
errorThresholdPercentage: 50, // 失敗率が50%を超えたらブレーカーオープン
resetTimeout: 30000 // 30秒後に再試行
};

const breaker = new CircuitBreaker(callLLM, options);
breaker.fallback(() => ({ error: "AIの応答が遅延しています。しばらく時間をおいてから再試行してください。" }));
`

APIの応答が遅れた際に、0.1秒であらかじめ用意した案内文を返すことで、サービス全体がダウンするのを防ぐことができます。

障害状況を非エンジニアの作成者がすぐに把握できるよう、SentryとSlack Webhookも連携しておきます。

`typescript
// app/api/webhooks/sentry-to-slack/route.ts
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
try {
const event = await request.json();
const webhookUrl = process.env.SLACK_INCOMING_WEBHOOK_URL;

if (!webhookUrl) return NextResponse.json({ error: 'Webhookなし' }, { status: 500 });

const title = event.data?.issue?.title || '不明なシステムエラー';
const issueUrl = event.data?.issue?.permalink || '#';

await fetch(webhookUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    blocks: [
      {
        type: 'header',
        text: { type: 'plain_text', text: '🚨 プロダクションエラー発生' }
      },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: `*エラー内容:*

${title}` }
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: 'Sentryレポートを見る' },
url: issueUrl,
style: 'danger'
}
]
}
]
})
});

return NextResponse.json({ success: true });

} catch (err) {
return NextResponse.json({ error: 'Webhook失敗' }, { status: 500 });
}
}
`

エラーが拡大してメインページが表示されないレベルのP1障害が発生した場合でも、エンジニアの対応を待つ必要はありません。Vercelは過去のデプロイメントをそのまま保存しているため、数クリックで直前の正常な状態に戻すことができます。

  1. SlackチャンネルでP1障害の通知を受け取ります。
  2. Vercelダッシュボードの Deployments タブに移動します。
  3. リストの中から、直前まで正常に動作していたデプロイ(Ready状態)を探します。
  4. 右側の三点リーダーボタン(...)を押し、 Promote to Production をクリックします。

わずか30秒待つだけで、ドメインのルーティングが以前のバージョンに切り替わります。Zod検証、Gitleaksスキャン、Vercelのロールバック手順まで整えておけば、非エンジニアに思いむくままアプリを作らせつつも、夜安心して眠ることができます。