יומן ביקורת חתום ושרשרת שמירה של הקלטות
מי נגע בהקלטה, מתי, ומה נמסר למי - רשום ברצף שאי אפשר לערוך בשקט. העמוד הזה מסביר בדיוק איך זה בנוי, מה זה מוכיח, ואיפה הגבול של ההבטחה.
- מה נחתם
- תוכן הרישום, ובנפרד הקישור שלו לרישום שקדם לו. שתי תמציות SHA-256 לכל שורה.
- מי יכול לשנות
- איש - לא עובד, לא מנהל ולא היישום עצמו. הרשאת העדכון והמחיקה נשללה, ומעליה טריגר שמפיל כל ניסיון.
- מה עדיין אין
- ייצוא עצמי של היומן וחבילת ראיות חתומה. היומן נקרא ומאומת בקונסולה; קובץ מוכן להורדה אינו קיים.
למה עסק מגיע לעמוד הזה
כמעט תמיד באותו רגע: מישהו טוען משהו על שיחה, וצריך להראות מה קרה בה - לא רק את ההקלטה, אלא מתי התבקשה, מי טיפל, מה נמסר ומתי. ברוב העסקים התשובה מפוזרת בין תיבת דוא״ל, גיליון ואדם אחד שזוכר. כשעולה השאלה "מי בכלל שמע את ההקלטה הזו", מתברר שאין לה תשובה.
תיעוד כזה הפך יקר יותר משהיה, כי אי-מסירה של הקלטה גוררת גם תוצאה ראייתית ולא רק קנס. ההסבר על הסנקציה הראייתית מפרט את זה. אבל הצורך התפעולי קדם לחוק: עסק שאינו יודע מי ניגש להקלטות שלו אינו יודע גם אם דלף ממנו משהו.
איך השרשרת בנויה
כל פעולה שנוגעת בהקלטה, בבקשה או בהרשאה נכתבת כרישום אחד ביומן של הארגון. הרישומים ממוספרים ברצף רץ, וכל אחד מהם נושא שתי תמציות:
- תמצית התוכן. השדות המהותיים של הרישום - הפעולה, סוג המבצע ומזההו, סוג הנושא ומזההו, הארגון והמטען - מסודרים לצורה קנונית אחת (מפתחות ממוינים, שדות ריקים מושמטים) ועליה מחושבת SHA-256. אותו רישום ייתן תמיד את אותה תמצית, ללא תלות בסדר השדות.
- תמצית הקישור. SHA-256 על צירוף של שלושה דברים: מספר הרצף, תמצית הקישור של הרישום הקודם, ותמצית התוכן של הרישום הנוכחי. הרישום הראשון בשרשרת מצביע על ערך פתיחה קבוע של 64 אפסים.
התוצאה היא שכל רישום מתחייב על כל מה שקדם לו. עריכה של רישום ישן משנה את תמצית התוכן שלו; מחיקה של רישום שוברת את הקישור של הרישום שאחריו; והוספת רישום באמצע דורשת לחשב מחדש את כל מה שבא אחריו. אין דרך לעשות אחד מאלה ולהשאיר שרשרת תקינה.
הרישום נכתב באותה עסקת בסיס נתונים כמו הפעולה עצמה. פעולה שנכשלה ובוטלה אינה משאירה רישום, ופעולה שהצליחה אינה יכולה לאבד אותו. כדי ששני כותבים בו-זמנית לא יתפסו את אותו מספר רצף ויפצלו את השרשרת, ההוספה מסונכרנת לכל ארגון בנפרד.
מה נאכף באמת, ואיפה הגבול
"בלתי ניתן לשינוי" היא מילה שקל לכתוב וקשה להצדיק. הטבלה הזו מפרידה בין מה שמנגנון בבסיס הנתונים אוכף לבין מה שנשאר מחוץ לתחומו. השורה הימנית היא ההבטחה; השמאלית היא מה שהיא לא מכסה.
| ההבטחה | מה אוכף אותה | מה היא לא מכסה |
|---|---|---|
| אי אפשר לשנות רישום קיים | מה אוכף אותהמדיניות ברמת השורה חוסמת UPDATE על טבלת היומן, הרשאת ה-UPDATE נשללת מהמשתמש שהיישום מתחבר בו, וטריגר בבסיס הנתונים מפיל כל ניסיון עדכון בשגיאה. | מה היא לא מכסההטריגר והמדיניות הם חלק מסכימת בסיס הנתונים. מי שמחזיק בבעלות על הסכימה יכול להסיר אותם. הוא לא יכול לעשות זאת בלי להשאיר עקבות בשרשרת עצמה. |
| אי אפשר למחוק רישום קיים | מה אוכף אותהאותם שלושה מנגנונים בדיוק חלים גם על DELETE. | מה היא לא מכסהמחיקה שכן תבוצע במעקף ברמת הסכימה תשבור את השרשרת מהרישום שאחריה והלאה, והאימות יצביע על הרצף הראשון שאינו תואם. |
| אי אפשר לערוך רישום בלי שיתגלה | מה אוכף אותהכל רישום נושא תמצית של תוכנו וגם תמצית שמחברת אותו לקודמו. האימות מחשב מחדש את שתיהן, ולכן עריכת תוכן שמשאירה את התמציות במקומן נתפסת אף היא. | מה היא לא מכסההאימות מגלה שהיומן נערך. הוא אינו משחזר את מה שנמחק, ואינו אומר מי עשה זאת. |
| ארגון אחד אינו רואה יומן של ארגון אחר | מה אוכף אותהבידוד ברמת השורה בבסיס הנתונים, כך שגם שאילתה שנשלחה בלי סינון מחזירה רק את הארגון שהוגדר לעסקה הנוכחית. | מה היא לא מכסההבידוד הוא בין ארגונים. הוא אינו מגביל מי בתוך הארגון רואה מה - זה תפקיד ההרשאות. |
| רישום שנכתב שייך לפעולה שבאמת קרתה | מה אוכף אותההרישום נכתב באותה עסקת בסיס נתונים כמו השינוי שהוא מתעד. פעולה שנכשלה ובוטלה אינה משאירה רישום, ופעולה שהצליחה אינה יכולה לאבד אותו. | מה היא לא מכסהזה מבטיח התאמה בין הרישום לבין מה שהמערכת עשתה. זה אינו מבטיח שמה שהמערכת קיבלה מהמרכזייה היה נכון. |
בקצרה: היומן בלתי ניתן לשינוי מבחינת היישום ומבחינת כל מי שמתחבר לבסיס הנתונים בהרשאות שהיישום משתמש בהן. מי שמחזיק בבעלות על הסכימה - אצלנו, או אצל ספק אחסון מנוהל - יכול להסיר את המנגנונים האלה. מה שהוא לא יכול לעשות הוא לשנות רישום ולהשאיר שרשרת שמאמתת את עצמה, וזה ההבדל בין יומן שאפשר לסמוך עליו לבין קובץ טקסט שכותרתו "יומן".
איך בודקים שהשרשרת שלמה
האימות מחשב את השרשרת מחדש מהתחלה ומדווח על הרצף הראשון שאינו תואם. הוא עושה שני דברים בכל רישום, ובסדר הזה: קודם מחשב מחדש את תמצית התוכן מהשדות עצמם ומשווה לזו הרשומה - כך נתפס תוקף שערך מטען והשאיר את התמציות במקומן - ורק אחר כך בודק שהקישור לרישום הקודם מחזיק. שרשרת ארוכה נבדקת בעמודים, כשההפניה בין עמוד לעמוד נשמרת, כדי שארגון עם שנים של שיחות לא ייקרא כולו לזיכרון.
בקונסולה זה מופיע כפס מצב מעל היומן: כמה רישומים נבדקו, והאם השרשרת תקינה. כשהיא נשברת זו התראה, לא כותרת - שרשרת שבורה היא אירוע אבטחה ולא תקלה תפעולית. אותה בדיקה רצה גם מדי לילה על כל ארגון, כחלק ממעבר התחזוקה. נדייק בגבול: כישלון בבדיקה הלילית נרשם ביומן התפעולי של המערכת ומטופל מצדנו, אבל המוצר אינו שולח על כך התראה יזומה למנהל - מי שרוצה לראות את המצב פותח את המסך.
תמצית הקובץ, ומה היא באמת אומרת
בזמן שההקלטה נקלטת מחושבת עליה תמצית SHA-256, על הבייטים המקוריים ולפני ההצפנה. התמצית נשמרת על שורת ההקלטה, וגם - וזה החלק שחשוב - נכתבת לתוך רישום היומן של רגע השמירה. שורת ההקלטה היא טבלה רגילה שהמערכת מעדכנת; רישום היומן אינו. כלומר אפילו אם ערך התמצית על השורה ישתנה אי-פעם, הערך שנרשם ברגע הקליטה נשאר בשרשרת.
במסך השיחה מוצגת התמצית המלאה, וניתן להשוות אליה כל עותק בפקודה אחת: shasum -a 256 <file> ב-macOS או בלינוקס, certutil -hashfile <file> SHA256 בחלונות. פלט זהה פירושו אותו קובץ בדיוק.
מה התמצית מוכיחה
- שהקובץ שבידיכם היום זהה בית-בית לקובץ שנקלט. שינוי של בית אחד משנה את התמצית כולה.
- שהעותק שהצרכן הוריד והעותק ששמור אצלכם הם אותו קובץ, כי שניהם נמדדים מול אותה תמצית.
- שהקובץ שנמחק בתום תקופת השמירה היה זה ולא אחר. התמצית נשמרת על השורה גם אחרי שהבייטים נמחקו.
מה היא אינה מוכיחה
- מה היה בקובץ לפני שנקלט. התמצית מחושבת ברגע הקליטה, ולכן היא מכסה את מה שקרה מאז ואילך בלבד.
- שההקלטה משקפת את השיחה. תמצית מזהה קובץ; היא אינה יודעת דבר על מה שנאמר בחדר.
- מתי השיחה התקיימה. את זה אומרת המטא-דאטה של השיחה, והיא נשענת על מה שהמרכזייה דיווחה.
אילו אירועים נרשמים
אוצר המילים סגור: אין שמות פעולה חופשיים, כי יומן שאי אפשר לסנן באמינות הוא יומן שאיש אינו קורא. להלן מה שנכתב בפועל היום, בחלוקה לפי מה שבדרך כלל מחפשים.
קליטה ואחסון
מה הגיע, ממי, ומה נשמר בפועל.
- שיחה נקלטה
- מזהה השיחה במרכזייה, כיוון, משך ומקור הקליטה שדיווח עליה.
- הקלטה נשמרה
- תמצית SHA-256 של הקובץ, גודלו, והאם זוהה כשקט או כבלתי קריא.
- הקלטה הועברה להסגר
- אותם פרטים, כשהקובץ התקבל אך אינו ראוי למסירה. הוא אינו נספר ככיסוי.
- מקור קליטה נכשל
- הרגע שבו חיבור הפסיק להתקבל, והסיבה.
- מפתח מקור קליטה נחשף או הוחלף
- מי ביקש לראות או להחליף מפתח חתימה, ומתי. חשיפה היא אירוע מתועד.
גישה לאודיו
האזנה היא אירוע פרטיות בפני עצמו, ולכן היא נרשמת גם כשלא ירד קובץ.
- עובד האזין להקלטה
- מזהה העובד, תפקידו, כתובת ה-IP, והאם השמיע או הוריד.
- ההקלטה הושמעה
- צרכן שהאזין דרך הקישור, עם מועד וכתובת.
- ההקלטה הורדה
- צרכן שהוריד את הקובץ, עם הבקשה שממנה נבעה הגישה.
בקשות צרכנים
כל שלב בבקשה, מהרגע שהתקבלה ועד לרגע שנסגרה.
- בקשה התקבלה
- האסמכתה, הערוץ שדרכו הגיעה, והמועד החוקי שנגזר ממנה.
- הפונה אומת
- שיטת האימות, כמה שיחות נמצאו וכמה מהן ניתנות למסירה.
- הבקשה נמסרה
- מי שחרר, כמה נמסר מתוך כמה שנמצא, והאם השחרור היה אוטומטי.
- הבקשה נדחתה
- הנימוק שנרשם. דחייה בלי נימוק אינה אפשרית.
- חלף המועד החוקי למענה
- נרשם מעצמו כשעברו עשרת ימי העסקים והבקשה פתוחה.
- הבקשה פגה ללא אימות
- הפונה לא השלים אימות. נפרד מאיחור, ובכוונה.
מסירה בפועל
שחרור אינו מסירה. שני הרישומים האלה הם ההבדל.
- הונפקה גישה להורדה
- תוקף הקישור ומכסת ההורדות שנקבעו לו.
- שליחת הודעה ללקוח נכשלה
- איזו הודעה, כמה ניסיונות, וכמה ערוצים הצליחו. אפס ערוצים פירושו שהצרכן לא הגיע.
- הודעה ללקוח נשלחה בניסיון חוזר
- המשלים של הרישום הקודם: מתי זה כן עבר.
שמירה ומחיקה
מחיקה כדין היא אירוע שצריך להוכיח בדיוק כמו שמירה.
- נקבע מועד מחיקה
- תקופת השמירה שנגזרה לשיחה, והמועד שממנו היא ניתנת למחיקה.
- הקלטה נמחקה כדין
- מועד המחיקה, סיבתה, ותמצית הקובץ שנמחק. השורה נשארת אחרי שהקובץ נעלם.
- מחיקה נכשלה
- הרישום שמונע מקובץ לשרוד את תקופתו בלי שאיש ידע.
- הוטלה או הוסרה הקפאה משפטית
- מי הקפיא, על אילו שיחות, ומאיזה נימוק.
אנשים והרשאות
מי יכול היה לגשת, ומתי זה השתנה.
- משתמש התחבר או ניסיון התחברות נכשל
- כולל כתובת ודפדפן.
- הרשאת משתמש שונתה
- מי שינה, ממה למה.
- משתמש הושבת או הופעל מחדש
- רגע כניסתו ורגע יציאתו של אדם מהמערכת.
- הגדרות הארגון עודכנו
- שינוי במדיניות שמירה או במסירה, עם השדות שהשתנו.
שתי הערות הגינות. ראשונה: בדיקת הודעת הפתיחה נרשמת גם היא, אבל רק כשהתמלול מופעל לארגון - בלי תמלול אין ממצא, וזה תקין. שנייה: האזנה של עובד לאודיו נרשמת; צפייה בתמליל אינה נרשמת כיום בנפרד. העדפנו לכתוב זאת כאן מאשר להשאיר את זה להפתעה בסקירת אבטחה.
ייצוא: מה יש היום, ומה אין
קיים היום
- מסך יומן בקונסולה, עם דפדוף על כל ההיסטוריה. סינון לפי סוג פעולה ולפי סוג מבצע נתמך דרך כתובת המסך, ולא כפקד על המסך עצמו.
- מצב השרשרת מוצג מעל היומן, עם מספר הרישומים שנבדקו והרצף הראשון שנשבר אם נשבר.
- ציר זמן מלא לכל בקשת צרכן, ובו הרישומים שנוגעים אליה בסדר כרונולוגי.
- התמצית המלאה של כל הקלטה במסך השיחה, כולל הקלטה שכבר נמחקה.
- הורדת האודיו עצמו מהקונסולה - וההורדה הזו נרשמת ביומן כמו כל גישה אחרת.
לא קיים היום
- ייצוא עצמי של היומן לקובץ CSV או JSON. את הרישומים קוראים במסך; אין כפתור שמוריד אותם.
- חבילת ראיות חתומה שנוצרת בלחיצה. המבנה קיים במודל הנתונים, אבל שום קוד אינו מפיק אותה, ולכן היא אינה יכולת של המוצר.
- חתימת זמן חיצונית מול גורם שלישי. השרשרת מוכיחה סדר פנימי, לא מועד שאושר מחוץ למערכת.
עד שיהיה ייצוא, תיק ראיות מורכב ידנית. המדריך להרכבת תיק ראיות מפרט בדיוק אילו רכיבים לאסוף ומה כל אחד מהם שווה.
דוגמה שאפשר לאמת בעצמכם
הקובץ שלהלן הוא שרשרת שלמה של אחת-עשרה רישומים: מהרגע שהארגון נוצר, דרך שיחה שנקלטה ונשמרה, בקשת צרכן שאומתה ונמסרה, הורדה בפועל, האזנה של עובד, ועד למחיקה בתום תקופת השמירה. כל הערכים בו מסונתזים - אין בו נתוני לקוח, אין מספרי טלפון, והכתובות שייכות לטווחים ששמורים לתיעוד.
התמציות בו אמיתיות. הקובץ מתעד את הנוסחאות שלפיהן חושבו, ומי שירצה יכול לחשב אותן מחדש ולקבל בדיוק את אותם ערכים. אנחנו בודקים את זה אוטומטית בכל בנייה, מול אותו קוד שמאמת שרשרת חיה, כדי שהקובץ שמתפרסם כאן לא יתיישן ביחס למוצר.
payloadHash = sha256(canonicalJson({
action, actorType, actorId,
subjectType, subjectId,
organizationId, payload
}))
hash = sha256(sequence + "|" + previousHash + "|" + payloadHash)
previousHash(first) = "0" x 64מה העמוד הזה לא מבטיח
- זו אינה תעודת עמידה בדרישות
- אין כאן ציון, אין תו ואין אישור. סעיף 16ד נמדד לפי מה שעוסק עשה בשיחה מסוימת, ומערכת אינה יכולה לחתום על כך מראש.
- השרשרת מגנה על הרישום, לא על המציאות
- היא מוכיחה שרצף הרישומים לא נערך בדיעבד. היא אינה מוכיחה שהאירוע שתועד קרה כפי שתואר, ואינה מוכיחה שאירוע שלא תועד לא קרה.
- שיחה שלא דווחה אינה מופיעה
- היומן מתעד את מה שהגיע. קו שהמרכזייה לא דיווחה עליו כלל אינו יוצר רישום חסר - הוא פשוט אינו קיים. בדיקת הכיסוי היא הכלי לכך, והיא נפרדת.
- אין כאן הבטחת קבילות
- קבילות ראיה נקבעת בבית המשפט לפי נסיבות התיק. שום מנגנון טכני, כאן או במקום אחר, אינו יכול להתחייב עליה.
מקורות ומתי נבדק העמוד
התיאור הטכני בעמוד הזה נכתב מול קוד המוצר. גרסה 1.0 · נבדק מול נוסח רשומות מיום 22.07.2026 · עודכן לאחרונה 02.08.2026. החומר כאן נכתב מתוך נוסח החוק שפורסם ברשומות, והוא הסבר תפעולי בלבד. הוא אינו ייעוץ משפטי, לא נבדק בידי עורך דין מטעמנו, ואינו מחליף בדיקה של הנוהל שלכם מול היועץ המשפטי שלכם ומול הרגולטור הענפי שלכם. נוסח החוק המלא באתר הכנסת (PDF).
הסעיף אינו קובע תקן טכני לתיעוד, אינו דורש שרשרת תמציות ואינו מכיר בפורמט מסוים. מה שמתואר כאן הוא בחירה הנדסית של VoiceBox, שנועדה לענות על שאלה מעשית - מה קרה לשיחה הזו - ולא לעמוד בדרישה שאיש לא ניסח. מה שהחוק לא קובע מפרט את ההבחנה הזו.
"מי נגע בהקלטה הזו" היא שאלה שצריכה תשובה בשתי דקות, לא בשני ימים.
VoiceBox רושמת כל גישה, כל בקשה וכל מסירה ברצף חתום, ומראה את מצב השרשרת בכל רגע.
יומן ביקורת הוא רכיב אחד בתיק ראיות. הרשימה המלאה של מה שצריך להיות בתיק נמצאת במדריך.
הרשימה ומבנה התיק לדוגמה זמינים במלואם בעמוד, בלי הרשמה.
להמשך קריאה
- אכיפה וסיכון ראייתיתיקון 74 הוסיף חמש הפרות לעיצום הכספי, אבל הסיכון הגדול הוא ראייתי: רואים את העוסק כמודה בגרסת הצרכן, וההקלטה שלו אינה קבילה אלא ברשות בית המשפט.
- מערכת הקלטת שיחות לעסקיםעמוד הקטגוריה של VoiceBox: מה מערכת לניהול הקלטות עושה מעל קובץ ההקלטה - קליטה מהמרכזייה, שמירה ומחיקה מבוקרת, איתור שיחות שלא נקלטו ומסירה ללקוח.