Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
DataOpsNight#11
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Tatsuya Hanyu
August 21, 2026
240
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DataOpsNight#11
Tatsuya Hanyu
August 21, 2026
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Navigating Weather and Climate Data
rabernat
0
540
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
How Software Deployment tools have changed in the past 20 years
geshan
2
34k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
4 Signs Your Business is Dying
shpigford
187
23k
GitHub's CSS Performance
jonrohan
1033
470k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Everyday Curiosity
cassininazir
0
330
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Transcript
DataOps Night #11 ⽻⼊達也、浅宮雄貴 © 2025 2026 Finatext Group ©
Finatext Group © Finatext Group
⾃⼰紹介 • • • • 名前:⽻⼊達也(データエンジニア) ◦ X :kaeton6ster 登壇テーマ:
◦ データ基盤にコンテキストレイヤー導⼊し始めた話 名前:浅宮雄貴(データエンジニア) ◦ X :NeoBigmegaphone 登壇テーマ: ◦ ユーザビリティと機密保護を両⽴するガバナンス Finatext Group ©© Finatext Group
データ基盤にコンテキストレイヤー 導⼊し始めた話 ©© Finatext Group Finatext Group
クレジット‧貸⾦向けの事業について ❚ 株式会社Finatext内のクレジットチームがクレジット基幹システム「Crest」を開発し、マルチテナント型で提供。 ❚ 株式会社スマートプラスクレジット(SPC)が「Crest」を活⽤して各種クレジットサービスを展開。 ❚ SPCにて⾃社で貸⾦事業を運営することでナレッジを蓄積し、業務への解像度を向上。 クレジット事業 • 基幹システムCrest
の開発 • 事業開発 貸金子会社 各種ファイナンスサービスの運営 • B2C:組込型ローン/ 個品割賦サービス • B2B:企業の資金繰りを支えるファイナンスサービ ス Finatext Group ©© Finatext Group
⾦融インフラストラクチャ事業 - Crest Crestは貸金サービスの実現を包括的に支え、一気通貫でサービス展開を可能にするプラットフォーム Finatext Group ©© Finatext Group
DWH構成の紹介 Crestの機能としてデータ基盤を提供している。⼀般的な3層構造でデータ基盤を構築 Crest DWH Crest DB Source / Lake Finatext
Group ©© Finatext Group Ware house Mart
DWH利活⽤の課題とアプローチ OLTPクエリをSnowflakeに変換し、⾃然⾔語問い合わせを実現するため、Skillと Semantic Layerを整備 Crest Lake Warehouse 課題① 💦 Mart
課題② OLTPクエリをSnowflakeでも活⽤ したいが、変換⽅法がわからず、エ ンジニアも多忙で進まない... 💦 アプローチ① ⾃然⾔語で問い合わせたいが、 AIに頼っても正しい結果を毎回は作 れない... アプローチ② OLTPクエリをSnowflakeクエリに 変換するskillを作る Semantic Layerを作る Finatext Group ©© Finatext Group
Skillの活⽤ Crest DB OLTPクエリをSnowflakeクエリに文法変換を行う skillを構築 skill 以下の SQLをsnowflake用に 変換してください <OLTP用のSQL>
ルールの例 現在有効な行を抽出する effective @> now() は 2 列に展開する OLTP(range型) WHERE effective @> now() 業務ユーザー skillを使⽤してクエリを変換 Snowflake ``` WHERE effective_start_at <= current_timestamp() AND (effective_end_at IS NULL OR current_timestamp() <= effective_end_at) ``` <Snowflake用のSQL> SNOWFLAKE COCO ※ あくまで自動変換のため、クエリの正確性チェックはエンジニアに依頼 Finatext Group ©© Finatext Group Source / Lake
Skillの活⽤ Lake層を前提としたクエリを Warehouse層を利用するクエリに変換 Source / Lake 変更前後での差分 • • •
• 60行超え 3つのテーブルを結合 複雑なCASE文 サブクエリあり 変換前 • • • • select A.DISPLAY_ID as "アカウントID", P.PLAN_CODE as "契約プラン番号", BASE_FEE_AMOUNT as "基本利用料", OPTION_FEE_AMOUNT as "オプション利用料", case -- 月末時に無料トライアル期間が終了している場合の日割り計算 when SUBSCRIPTION_STATUS = 'ACTIVE' and UTL.TRIAL_END_DATE > UTL.PROCESSED_AT and UTL.TRIAL_END_DATE at time zone 'Asia/Tokyo' <= '202X-12-31 23:59:59' then FLOOR(BASE_USAGE_FEE + BASE_FEE_AMOUNT * DATE_PART( 'day', TIMESTAMP '202X-12-31 23:59:59' at time zone 'Asia/Tokyo' - UTL.TRIAL_END_DATE at time zone 'Asia/Tokyo' + interval '1 day' ) * UTL.USAGE_RATE / 365) -- 月末時に無料トライアル期間内の場合 when SUBSCRIPTION_STATUS = 'ACTIVE' and UTL.TRIAL_END_DATE at time zone 'Asia/Tokyo' > '202X-12-31 23:59:59' then 0 -- 通常利用期間 when SUBSCRIPTION_STATUS = 'ACTIVE' then FLOOR(BASE_USAGE_FEE + BASE_FEE_AMOUNT * DATE_PART( 'day', TIMESTAMP '202X-12-31 23:59:59' at time zone 'Asia/Tokyo' - UTL.PROCESSED_AT at TIME zone 'Asia/Tokyo' ) * UTL.USAGE_RATE / 365) else FLOOR(BASE_USAGE_FEE) end as "未収基本料", case -- 停止中・解約済みアカウントの遅延損害金計算 when SUBSCRIPTION_STATUS in ('SUSPENDED','CANCELLED') then FLOOR(UTL.PENALTY_AMOUNT + UTL.BASE_FEE_AMOUNT * DATE_PART( 'day', TIMESTAMP '202X-12-31 23:59:59' at time zone 'Asia/Tokyo' - UTL.PROCESSED_AT at TIME zone 'Asia/Tokyo' ) * UTL.PENALTY_RATE / 365) else FLOOR(PENALTY_AMOUNT) end as "未収遅延請求金" from USER_TRANSACTION_LOGS UTL inner join ACCOUNTS A on A.ID = UTL.ACCOUNT_ID and UTL.VALID_PERIOD @> NOW() and UTL.SYSTEM_PERIOD @> NOW() and A.VALID_PERIOD @> NOW() and A.SYSTEM_PERIOD @> NOW() inner join SUBSCRIPTION_PLANS P on UTL.PLAN_ID = P.ID and P.VALID_PERIOD @> NOW() and P.SYSTEM_PERIOD @> NOW() where (UTL.ACCOUNT_ID, UTL.PROCESSED_AT) in ( -- 最新のトランザクションのみを抽出 select ACCOUNT_ID, MAX(PROCESSED_AT) from USER_TRANSACTION_LOGS where VALID_PERIOD @> NOW() and SYSTEM_PERIOD @> NOW() and PROCESSED_AT at time zone 'Asia/Tokyo' < '202X-12-31 23:59:59' group by ACCOUNT_ID ) order by A.ID; AI変換後 約10行に短縮 結合なし(単一テーブル) 計算済みカラムを参照するだけ サブクエリ不要、 whereのみ select s.account_id as "アカウントID", s.plan_code as "契約プラン番号", s.base_fee_amount as "基本利用料", s.option_fee_amount as "オプション利用料", floor(s.accrued_base_fee) as "未収基本料", floor(s.accrued_penalty_fee) as "未収遅延 請求金" from warehouse_billing.fct_daily_billing_snapsho t as s where s.date = date() ※クエリはサンプル Finatext Group ©© Finatext Group Ware house
Semantic Layer の構築 自然言語での問い合わせに適切な結果を返すには Semantic viewの整備が不可欠 • Semantic layerとは ◦
◦ • Snowflakeには Semantic layerの整備をサポートする autopilot機能がある ◦ • テーブルやカラムに、ビジネス上の意味や関係性を付与するレイヤー ⾃然⾔語から正確なSQLを⽣成するための「辞書」の役割を果たす auto pilot機能とは ▪ テーブルの構造やデータを解析し、初台となるセマンティックモデル(指標やディメンションの定義) を⾃動⽣成してくれる機能 ▪ ゼロから定義を記述する⼿間を⼤幅に削減し、素早い⽴ち上げが可能になる auto pilot機能を使⽤して、warehouse層に Semantic Layerを構築した Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 質問(⾃然⽂)と期待するSQL csvファイルを取り込み Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 Finatext Group ©© Finatext Group
Semantic View Autopilotで初期のセマンティックを⾃動作成 Finatext Group ©© Finatext Group
まとめ Crest Warehouse Lake ① Skillによって、アプリケーション DBへのクエリ をSnowflakeで使えるように変換。 Future Work
• • Semantic Layerの定期的な更新設計、グルーピングについて Snowflakeのアップデートに追従してSkillの更新 Finatext Group ©© Finatext Group Mart ② ①で作成したクエリを使用して、 Semantic Layerを整備
ユーザビリティと機密保護を両⽴するガバナンス ©© Finatext Group Finatext Group
課題:ユーザビリティと機密保護の両⽴ 多くの⼈にデータを 利⽤してもらいたい VS データごとに 「誰が‧いつ」⾒て 良いかは異なる 機密保護のためには⼀律で厳しめの制限をするしかなく、利活⽤が進みにくくなる 複数レイヤーに境界を設けることで、ユーザビリティと機密保護を両⽴する! Finatext
Group ©© Finatext Group
設計⽅針:三段構えの分離 STAGE 01 どこで / WHERE ⼿段 / METHOD ①
⼊れない AWS / Athena テーブル‧カラム除去 STAGE 02 どこで / WHERE ⼿段 / METHOD ② 隠す Snowflake内 マスキングポリシー STAGE 03 どこで / WHERE ⼿段 / METHOD ③ 承認する Snowflake 承認時に権限を⼀時付与する仕組みを実装 Finatext Group ©© Finatext Group
Stage 1:分析に不必要なデータをデータ基盤(Snowflake)に⼊れない Crest DWH Athena AthenaマスキングレイヤーのSQLでテーブル‧カラムを編集可能な設計 → データを絞り、意図せぬデータ露出のリスクを低減 Finatext Group
©© Finatext Group
Stage 2:分析に使う機密データを、許可されていない⼈から隠す 誰に⾒せるか = ロールベース ロール どの列を隠すか = タグベース クエリ
テーブル.カラム tagをset CURRENT_ROLE() で判定 紐づく マスキングポリシー タグ 対象ロールなら⽣値、それ以外は **** を返す ロールとタグを⽤いた権限管理 定義と適⽤を分離し、柔軟なマスキング設定を実現 Finatext Group ©© Finatext Group
Stage 2:分析に使う機密データを、許可されていない⼈から隠す # dim_customers.yml — mobile_phone_numberカラム どの列を隠すか = タグベース にタグを宣言
誰に⾒せるか = ロールベース クエリ models: ロール - name: dim_customers columns: - name: mobile_phone_number meta: CURRENT_ROLE() で判定 tag: name: SNOWFLAKE_CONFIG.TAG.PII value: PII 紐づく テーブル.カラム マスキングポリシー タグ tagをset # パイプライン実行時、 post-hook の**** macro が SET 対象ロールなら⽣値、それ以外は を返す TAG を実行 ロールとタグを⽤いた権限管理 alter table WH_SCHEMA.DIM_CUSTOMERS modify 定義と適⽤を分離し、柔軟なマスキング設定を実現 column mobile_phone_number set tag SNOWFLAKE_CONFIG.TAG.PII = 'PII'; Finatext Group ©© Finatext Group
Stage 2:分析に使う機密データを、許可されていない⼈から隠す # SNOWFLAKE_CONFIG.TAG.PIIタグの定義 誰に⾒せるか = ロールベース ロール どの列を隠すか =
タグベース クエリ テーブル.カラム resource "snowflake_tag" "pii" { … name = "PII" tagをset CURRENT_ROLE() で判定 masking_policies = [snowflake_masking_policy. pii_string.fully_qua 紐づく lified_name] マスキングポリシー } タグ 対象ロールなら⽣値、それ以外は **** を返す ロールとタグを⽤いた権限管理 定義と適⽤を分離し、柔軟なマスキング設定を実現 Finatext Group ©© Finatext Group
# マスキングポリシー : snowflake_masking_policy.pii_stringの定義 Stage 2:分析に使う機密データを、許可されていない⼈から隠 resource "snowflake_masking_policy" "pii_string" {
… 誰に⾒せるか = ロールベース どの列を隠すか = タグベース name = "PII_STRING" ロール CURRENT_ROLE() で判定 クエリ テーブル.カラム argument { name = "val" type = "STRING" } tagをset return_data_type = "STRING" body = <<-EOF 紐づく CASE マスキングポリシー タグ WHEN CURRENT_ROLE() IN (マスク解除ロール ) THEN val 対象ロールなら⽣値、それ以外は **** を返す ELSE '****' END ロールとタグを⽤いた権限管理 EOF 定義と適⽤を分離し、柔軟なマスキング設定を実現 } Finatext Group ©© Finatext Group
Stage 3: 強い権限は常時持たせず、短時間だけ承認する ⚠ 強いロールを常時持つ • 承認不要 • いつでも⾒られる →
• • 強いロール 本番データが⾒える 申請によって使⽤可能 申請者 ⭕ 必要な時だけ承認する • 通常のロール 本番データは⾒えない 常時使⽤可能 普段は本番データを⾒れないロールのみ使 える 権限付与フローを実施すると、本番データ を⾒られるロールが使えるようになる 期限切れ時に権限剥奪フローが起動し、本 番データ⾒られるロールの使⽤権限は⾃動 剥奪 Finatext Group ©© Finatext Group
Stage 3: 強い権限は常時持たせず、短時間だけ承認する ⚠ 強いロールを常時持つ • 承認不要 • いつでも⾒られる 権限付与フロー
① slack workflowで申請 ② 他者が承認 ③ 時間限定でロールを貸与 → ⭕ 必要な時だけ承認する • • • 普段は本番データを⾒れないロールのみ使 える 権限付与フローを実施すると、本番データ を⾒られるロールが使えるようになる 期限切れ時に権限剥奪フローが起動し、本 番データ⾒られるロールの使⽤権限は⾃動 剥奪 承認者 ① 申請者 通常のロール ② ③ 権限付与 ③ grant role 強いロール to user 申請者 Finatext Group ©© Finatext Group 強いロール
Stage 3: 強い権限は常時持たせず、短時間だけ承認する ⚠ 強いロールを常時持つ • 承認不要 • いつでも⾒られる 権限剥奪フロー
④ 期限切れで⾃動返却 → 申請者 ⭕ 必要な時だけ承認する • • • 普段は本番データを⾒れないロールのみ使 える 権限付与フローを実施すると、本番データ を⾒られるロールが使えるようになる 期限切れ時に権限剥奪フローが起動し、本 番データ⾒られるロールの使⽤権限は⾃動 剥奪 権限剥奪 ⾃動実⾏ 通常のロール ④ ④ revoke role 強いロール from user 申請者 Finatext Group ©© Finatext Group 強いロール
Stage 3: 強い権限は常時持たせず、短時間だけ承認する ⚠ 強いロールを常時持つ • 承認不要 • いつでも⾒られる 2つのpoint
時間的最⼩性 → 必要なとき、短時間だけ ⭕ 必要な時だけ承認する • • • 普段は本番データを⾒れないロールのみ使 える 権限付与フローを実施すると、本番データ を⾒られるロールが使えるようになる 期限切れ時に権限剥奪フローが起動し、本 番データ⾒られるロールの使⽤権限は⾃動 剥奪 Two Person Integrity ⼀⼈で完結させず、必ず他者 の承認を挟む Finatext Group ©© Finatext Group
まとめ ― 多層の境界で、ユーザビリティと機密保護を両⽴する ユーザビリティと機密保護は⼆択ではない。データごとの「誰が‧いつ」を、多層の境界で制御する STAGE 01 ① ⼊れない 不要なデータはそもそも基盤に載せない STAGE
02 ② 隠す 機密はロール×タグで動的にマスク STAGE 03 ③ 承認する 強い権限は常時でなく、承認を経て⼀時的に使⽤ データを守りながら、広く使ってもらう Finatext Group ©© Finatext Group
©© Finatext Group Finatext Group
Appendix: TARP (Temporal Assume Role Policy) の仕組み 権限付与フロー ① 申請
② 他者が承認 ③ 時間限定でロールを貸与 ① ③ 権限付与希望者がslack workflowで申請 権限剥奪フロー ④ 期限切れで⾃動返却 ② ④ 出典: https://speakerdeck.com/kevinrobot34/introduction-of-information-security-7f7b9 6b1-3ed9-4ef5-b8f6-96d428da6fc4?slide=31 Finatext Group ©© Finatext Group
Appendix: ロール設計 出典: https://speakerdeck.com/kevinrobot34/privilege-and-cost-management-in-snowflake?slide=4 Service Role 層 System User 1
Account Role Service_RW Database Access Role 層 Warehouse System User 2 Account Role Service_R Warehouse Database Role table-select Database Role ReadWrite Database Role table-create Functional Role 層 Human User A Account Role Functional_RW Warehouse Human User B tables Database Role Read Account Role Functional_R Database Role view-select views Database Role view-create Warehouse 権限の束の単位で継承させることで、メンテナンス性を維持しつつ最⼩権限を実現 Finatext Group ©© Finatext Group 33