[{"data":1,"prerenderedAt":1074},["ShallowReactive",2],{"navigation_docs":3,"-getting-started-installation":183,"-getting-started-installation-surround":1069},[4,25,60,81,153,168],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-lucide-zap",{"title":21,"path":22,"stem":23,"icon":24},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F3.installation","i-lucide-server",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Concepts","\u002Fconcepts","2.concepts",[30,35,40,45,50,55],{"title":31,"path":32,"stem":33,"icon":34},"How AML works","\u002Fconcepts\u002Fhow-aml-works","2.concepts\u002F1.how-aml-works","i-lucide-book-open",{"title":36,"path":37,"stem":38,"icon":39},"Events and decisions","\u002Fconcepts\u002Fevents-and-decisions","2.concepts\u002F2.events-and-decisions","i-lucide-activity",{"title":41,"path":42,"stem":43,"icon":44},"Rules","\u002Fconcepts\u002Frules","2.concepts\u002F3.rules","i-lucide-scale",{"title":46,"path":47,"stem":48,"icon":49},"Alerts, cases and reporting","\u002Fconcepts\u002Falerts-cases-reporting","2.concepts\u002F4.alerts-cases-reporting","i-lucide-folder-search",{"title":51,"path":52,"stem":53,"icon":54},"Entities and the graph","\u002Fconcepts\u002Fentities-and-graph","2.concepts\u002F5.entities-and-graph","i-lucide-network",{"title":56,"path":57,"stem":58,"icon":59},"Audit log","\u002Fconcepts\u002Faudit-log","2.concepts\u002F6.audit-log","i-lucide-scroll-text",{"title":61,"icon":6,"path":62,"stem":63,"children":64,"page":6},"Guides","\u002Fguides","3.guides",[65,70,75],{"title":66,"path":67,"stem":68,"icon":69},"Guides by role","\u002Fguides\u002Fby-role","3.guides\u002F1.by-role","i-lucide-users",{"title":71,"path":72,"stem":73,"icon":74},"Integration plan","\u002Fguides\u002Fintegration-plan","3.guides\u002F2.integration-plan","i-lucide-list-checks",{"title":76,"path":77,"stem":78,"icon":79,"badge":80},"Connecting a rail","\u002Fguides\u002Fconnecting-a-rail","3.guides\u002F3.connecting-a-rail","i-lucide-plug","Coming soon",{"title":82,"icon":6,"path":83,"stem":84,"children":85,"page":6},"API reference","\u002Fapi","4.api",[86,91,96,101,106,111,116,121,126,129,134,139,144,149],{"title":87,"path":88,"stem":89,"icon":90},"Authentication","\u002Fapi\u002Fauthentication","4.api\u002F01.authentication","i-lucide-key-round",{"title":92,"path":93,"stem":94,"icon":95},"Errors","\u002Fapi\u002Ferrors","4.api\u002F02.errors","i-lucide-circle-alert",{"title":97,"path":98,"stem":99,"icon":100},"Idempotency","\u002Fapi\u002Fidempotency","4.api\u002F03.idempotency","i-lucide-repeat",{"title":102,"path":103,"stem":104,"icon":105},"Health","\u002Fapi\u002Fhealth","4.api\u002F04.health","i-lucide-heart-pulse",{"title":107,"path":108,"stem":109,"icon":110},"Entities","\u002Fapi\u002Fentities","4.api\u002F05.entities","i-lucide-user-round",{"title":112,"path":113,"stem":114,"icon":115},"Events","\u002Fapi\u002Fevents","4.api\u002F06.events","i-lucide-send",{"title":117,"path":118,"stem":119,"icon":120},"Decisions","\u002Fapi\u002Fdecisions","4.api\u002F07.decisions","i-lucide-gavel",{"title":122,"path":123,"stem":124,"icon":125},"Alerts","\u002Fapi\u002Falerts","4.api\u002F08.alerts","i-lucide-bell",{"title":41,"path":127,"stem":128,"icon":44},"\u002Fapi\u002Frules","4.api\u002F09.rules",{"title":130,"path":131,"stem":132,"icon":133},"Screening","\u002Fapi\u002Fscreening","4.api\u002F10.screening","i-lucide-user-search",{"title":135,"path":136,"stem":137,"icon":138},"API keys","\u002Fapi\u002Fapi-keys","4.api\u002F11.api-keys","i-lucide-key",{"title":140,"path":141,"stem":142,"icon":143},"Overview","\u002Fapi\u002Foverview","4.api\u002F12.overview","i-lucide-layout-dashboard",{"title":145,"path":146,"stem":147,"icon":148,"badge":80},"Webhooks","\u002Fapi\u002Fwebhooks","4.api\u002F13.webhooks","i-lucide-webhook",{"title":80,"path":150,"stem":151,"icon":152,"badge":80},"\u002Fapi\u002Fcoming-soon","4.api\u002F14.coming-soon","i-lucide-clock",{"title":154,"icon":6,"path":155,"stem":156,"children":157,"page":6},"Security and licensing","\u002Fsecurity","5.security",[158,163],{"title":159,"path":160,"stem":161,"icon":162},"Data flows","\u002Fsecurity\u002Fdata-flows","5.security\u002F1.data-flows","i-lucide-shield-check",{"title":164,"path":165,"stem":166,"icon":167,"badge":80},"Licensing and metering","\u002Fsecurity\u002Flicensing","5.security\u002F2.licensing","i-lucide-file-badge",{"title":169,"icon":6,"path":170,"stem":171,"children":172,"page":6},"Reference","\u002Freference","6.reference",[173,178],{"title":174,"path":175,"stem":176,"icon":177},"Glossary","\u002Freference\u002Fglossary","6.reference\u002F1.glossary","i-lucide-book-a",{"title":179,"path":180,"stem":181,"icon":182},"FAQ","\u002Freference\u002Ffaq","6.reference\u002F2.faq","i-lucide-circle-help",{"id":184,"title":21,"body":185,"description":1062,"extension":1063,"links":1064,"meta":1065,"navigation":1066,"path":22,"seo":1067,"stem":23,"__hash__":1068},"docs\u002F1.getting-started\u002F3.installation.md",{"type":186,"value":187,"toc":1045},"minimark",[188,197,202,205,274,277,288,292,304,417,420,449,453,460,485,505,512,516,519,751,754,758,828,832,854,907,911,973,976,980,1014,1018,1021,1041],[189,190,191,192,196],"p",{},"You run Sentinel on your own servers (on-prem) or in your own cloud account, and the software is the same either way. Each running copy is called an ",[193,194,195],"strong",{},"install",".",[198,199,201],"h2",{"id":200},"whats-in-an-install","What's in an install",[189,203,204],{},"An install is one binary, one PostgreSQL database and, optionally, Redis.",[206,207,208,221],"table",{},[209,210,211],"thead",{},[212,213,214,218],"tr",{},[215,216,217],"th",{},"Component",[215,219,220],{},"What it does",[222,223,224,248,258,266],"tbody",{},[212,225,226,233],{},[227,228,229],"td",{},[230,231,232],"code",{},"sentinel-api",[227,234,235,236,239,240,243,244,247],{},"Serves the API under ",[230,237,238],{},"\u002Fv1",", ",[230,241,242],{},"\u002Fhealthz",", and the dashboard at ",[230,245,246],{},"\u002F",". Applies database migrations when it starts. Scores events with versioned CEL rules.",[212,249,250,255],{},[227,251,252],{},[230,253,254],{},"sentinel-admin",[227,256,257],{},"Command-line tool for operator tasks: creating keys, verifying the audit chain, seeding rules and loading screening lists",[212,259,260,263],{},[227,261,262],{},"PostgreSQL",[227,264,265],{},"The system of record: events, decisions, alerts, rules, screenings, keys and the audit log. The local setup uses PostgreSQL 17.",[212,267,268,271],{},[227,269,270],{},"Redis (optional)",[227,272,273],{},"Serves the velocity counters rules read. Without it the counts come from PostgreSQL, which is slower. Redis holds nothing that can't be rebuilt.",[189,275,276],{},"The binary makes no outbound connections except to your database and Redis. Nothing goes to Somu Labs.",[278,279,280,283,284,287],"note",{},[193,281,282],{},"Multi-tenancy."," Every row carries an ",[230,285,286],{},"org_id",", and every API key belongs to exactly one organisation. One install can serve several brands or legal entities with complete separation, including separate audit chains. Screening lists are the exception: they're shared by the whole install.",[198,289,291],{"id":290},"docker","Docker",[189,293,294,295,298,299,301,302,196],{},"The ",[230,296,297],{},"Dockerfile"," in the repository builds one image with the API, the dashboard and ",[230,300,254],{},". It runs as a non-root user, listens on port 8080, and has a health check on ",[230,303,242],{},[305,306,312],"pre",{"className":307,"code":308,"filename":309,"language":310,"meta":311,"style":311},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","docker build -t sentinel --build-arg VERSION=v0.1.0 .\n\ndocker run -d --name sentinel -p 8080:8080 \\\n  -e SENTINEL_DATABASE_URL=\"postgres:\u002F\u002Fsentinel:change-me@db.internal:5432\u002Fsentinel\" \\\n  -e SENTINEL_BOOTSTRAP_API_KEY=\"snt_live_...\" \\\n  sentinel\n","Terminal","bash","",[230,313,314,341,348,374,394,411],{"__ignoreMap":311},[315,316,319,322,326,329,332,335,338],"span",{"class":317,"line":318},"line",1,[315,320,290],{"class":321},"sBMFI",[315,323,325],{"class":324},"sfazB"," build",[315,327,328],{"class":324}," -t",[315,330,331],{"class":324}," sentinel",[315,333,334],{"class":324}," --build-arg",[315,336,337],{"class":324}," VERSION=v0.1.0",[315,339,340],{"class":324}," .\n",[315,342,344],{"class":317,"line":343},2,[315,345,347],{"emptyLinePlaceholder":346},true,"\n",[315,349,351,353,356,359,362,364,367,370],{"class":317,"line":350},3,[315,352,290],{"class":321},[315,354,355],{"class":324}," run",[315,357,358],{"class":324}," -d",[315,360,361],{"class":324}," --name",[315,363,331],{"class":324},[315,365,366],{"class":324}," -p",[315,368,369],{"class":324}," 8080:8080",[315,371,373],{"class":372},"sTEyZ"," \\\n",[315,375,377,380,383,387,390,392],{"class":317,"line":376},4,[315,378,379],{"class":324},"  -e",[315,381,382],{"class":324}," SENTINEL_DATABASE_URL=",[315,384,386],{"class":385},"sMK4o","\"",[315,388,389],{"class":324},"postgres:\u002F\u002Fsentinel:change-me@db.internal:5432\u002Fsentinel",[315,391,386],{"class":385},[315,393,373],{"class":372},[315,395,397,399,402,404,407,409],{"class":317,"line":396},5,[315,398,379],{"class":324},[315,400,401],{"class":324}," SENTINEL_BOOTSTRAP_API_KEY=",[315,403,386],{"class":385},[315,405,406],{"class":324},"snt_live_...",[315,408,386],{"class":385},[315,410,373],{"class":372},[315,412,414],{"class":317,"line":413},6,[315,415,416],{"class":324},"  sentinel\n",[189,418,419],{},"Migrations run on startup, so a new image upgrades the schema when it starts. Run the admin tool inside the container:",[305,421,423],{"className":307,"code":422,"filename":309,"language":310,"meta":311,"style":311},"docker exec sentinel \u002Fapp\u002Fsentinel-admin audit verify -org default\n",[230,424,425],{"__ignoreMap":311},[315,426,427,429,432,434,437,440,443,446],{"class":317,"line":318},[315,428,290],{"class":321},[315,430,431],{"class":324}," exec",[315,433,331],{"class":324},[315,435,436],{"class":324}," \u002Fapp\u002Fsentinel-admin",[315,438,439],{"class":324}," audit",[315,441,442],{"class":324}," verify",[315,444,445],{"class":324}," -org",[315,447,448],{"class":324}," default\n",[198,450,452],{"id":451},"from-source","From source",[189,454,455,456,459],{},"You need Go (the version in ",[230,457,458],{},"go.mod",") and Node 22 for the dashboard.",[305,461,463],{"className":307,"code":462,"filename":309,"language":310,"meta":311,"style":311},"make bundle          # builds the dashboard and compiles it into bin\u002Fsentinel-api\n.\u002Fbin\u002Fsentinel-api   # serves the dashboard at \u002F and the API under \u002Fv1\n",[230,464,465,477],{"__ignoreMap":311},[315,466,467,470,473],{"class":317,"line":318},[315,468,469],{"class":321},"make",[315,471,472],{"class":324}," bundle",[315,474,476],{"class":475},"sHwdD","          # builds the dashboard and compiles it into bin\u002Fsentinel-api\n",[315,478,479,482],{"class":317,"line":343},[315,480,481],{"class":321},".\u002Fbin\u002Fsentinel-api",[315,483,484],{"class":475},"   # serves the dashboard at \u002F and the API under \u002Fv1\n",[189,486,487,490,491,493,494,496,497,500,501,504],{},[230,488,489],{},"make build"," builds the API without the dashboard. ",[230,492,246],{}," then shows a page explaining the dashboard isn't included. ",[230,495,469],{}," reads a ",[230,498,499],{},".env"," file in the repository root if there is one. ",[230,502,503],{},".env.example"," has local defaults.",[189,506,507,508,511],{},"For a local database, ",[230,509,510],{},"make up"," starts PostgreSQL on port 5433 and Redis on 6379 with Docker Compose. It also starts Redpanda, which nothing uses yet.",[198,513,515],{"id":514},"configuration","Configuration",[189,517,518],{},"All settings are environment variables. Only the database URL is required.",[206,520,521,534],{},[209,522,523],{},[212,524,525,528,531],{},[215,526,527],{},"Variable",[215,529,530],{},"Default",[215,532,533],{},"Meaning",[222,535,536,549,564,577,592,611,628,643,657,675,690,705,720,738],{},[212,537,538,543,546],{},[227,539,540],{},[230,541,542],{},"SENTINEL_DATABASE_URL",[227,544,545],{},"none, required",[227,547,548],{},"PostgreSQL connection string",[212,550,551,556,561],{},[227,552,553],{},[230,554,555],{},"SENTINEL_HTTP_ADDR",[227,557,558],{},[230,559,560],{},":8080",[227,562,563],{},"Address the API listens on",[212,565,566,571,574],{},[227,567,568],{},[230,569,570],{},"SENTINEL_REDIS_ADDR",[227,572,573],{},"unset",[227,575,576],{},"Redis for velocity counters. Unset means counts come from PostgreSQL.",[212,578,579,584,589],{},[227,580,581],{},[230,582,583],{},"SENTINEL_REDIS_DB",[227,585,586],{},[230,587,588],{},"0",[227,590,591],{},"Redis database number, for installs that share a Redis",[212,593,594,599,604],{},[227,595,596],{},[230,597,598],{},"SENTINEL_AUTO_MIGRATE",[227,600,601],{},[230,602,603],{},"true",[227,605,606,607,610],{},"Apply pending migrations on startup. ",[230,608,609],{},"false"," skips them.",[212,612,613,618,620],{},[227,614,615],{},[230,616,617],{},"SENTINEL_BOOTSTRAP_API_KEY",[227,619,573],{},[227,621,622,623,196],{},"Becomes the organisation's first API key, only while it has none. See ",[624,625,627],"a",{"href":626},"\u002Fapi\u002Fauthentication#the-first-key-on-a-fresh-install","the first key",[212,629,630,635,640],{},[227,631,632],{},[230,633,634],{},"SENTINEL_BOOTSTRAP_ORG",[227,636,637],{},[230,638,639],{},"default",[227,641,642],{},"The organisation the bootstrap key belongs to",[212,644,645,650,654],{},[227,646,647],{},[230,648,649],{},"SENTINEL_SCREENING_SAMPLE",[227,651,652],{},[230,653,609],{},[227,655,656],{},"Load the synthetic screening list when no list is loaded. Keep it off in production.",[212,658,659,664,669],{},[227,660,661],{},[230,662,663],{},"SENTINEL_SLA_HIGH",[227,665,666],{},[230,667,668],{},"4h",[227,670,671,672,196],{},"How long a high priority alert has to be decided. Any Go duration, like ",[230,673,674],{},"90m",[212,676,677,682,687],{},[227,678,679],{},[230,680,681],{},"SENTINEL_SLA_MEDIUM",[227,683,684],{},[230,685,686],{},"24h",[227,688,689],{},"The same for medium priority alerts.",[212,691,692,697,702],{},[227,693,694],{},[230,695,696],{},"SENTINEL_NEAR_THRESHOLD_LOW",[227,698,699],{},[230,700,701],{},"4500",[227,703,704],{},"Lower end of the \"just under the reporting threshold\" band the structuring counter uses. Set both ends or neither.",[212,706,707,712,717],{},[227,708,709],{},[230,710,711],{},"SENTINEL_NEAR_THRESHOLD_HIGH",[227,713,714],{},[230,715,716],{},"5000",[227,718,719],{},"Upper end of the band, not included. Set it to your reporting threshold.",[212,721,722,727,732],{},[227,723,724],{},[230,725,726],{},"SENTINEL_RATE_LIMIT",[227,728,729],{},[230,730,731],{},"1000",[227,733,734,735,737],{},"Requests a second each API key may make, on average. ",[230,736,588],{}," turns the limit off. Each replica counts its own traffic.",[212,739,740,745,748],{},[227,741,742],{},[230,743,744],{},"SENTINEL_RATE_BURST",[227,746,747],{},"twice the limit",[227,749,750],{},"How many requests a key may make at once before the average applies.",[189,752,753],{},"The server fails to start, with a message naming the variable, if a required value is missing or a value can't be parsed.",[198,755,757],{"id":756},"first-run","First run",[759,760,762,767,773,777,790,794,801,805,815,819],"steps",{"level":761},"3",[763,764,766],"h3",{"id":765},"start-it","Start it",[189,768,769,770,772],{},"Point ",[230,771,542],{}," at an empty database and start the binary or container. It applies every migration and logs which ones it ran.",[763,774,776],{"id":775},"get-a-key","Get a key",[189,778,779,780,782,783,786,787,196],{},"Set ",[230,781,617],{}," before the first start, or run ",[230,784,785],{},"sentinel-admin key create -name admin"," once. See ",[624,788,87],{"href":789},"\u002Fapi\u002Fauthentication#creating-keys",[763,791,793],{"id":792},"make-your-own-keys","Make your own keys",[189,795,796,797,800],{},"Sign in to the dashboard with that key, open ",[193,798,799],{},"Developers → API keys",", and create a key for each person and service. Four-eyes approvals need at least two. Then revoke the bootstrap key and remove the variable.",[763,802,804],{"id":803},"seed-the-rules","Seed the rules",[189,806,807,808,811,812,196],{},"Run ",[230,809,810],{},"sentinel-admin rules seed -org default"," if you want the built-in rules installed as editable rules. See ",[624,813,41],{"href":814},"\u002Fconcepts\u002Frules#the-built-in-pack",[763,816,818],{"id":817},"load-a-screening-list","Load a screening list",[189,820,807,821,824,825,196],{},[230,822,823],{},"sentinel-admin screening load -file \u003Clist.json>"," with a list you've licensed. See ",[624,826,130],{"href":827},"\u002Fapi\u002Fscreening#loading-lists",[198,829,831],{"id":830},"admin-commands","Admin commands",[189,833,834,836,837,839,840,843,844,847,848,851,852,196],{},[230,835,254],{}," reads ",[230,838,542],{},". Run it with ",[230,841,842],{},"go run .\u002Fcmd\u002Fsentinel-admin ..."," from source, or ",[230,845,846],{},"\u002Fapp\u002Fsentinel-admin ..."," in the container. ",[230,849,850],{},"-org"," defaults to ",[230,853,639],{},[206,855,856,865],{},[209,857,858],{},[212,859,860,863],{},[215,861,862],{},"Command",[215,864,220],{},[222,866,867,877,887,897],{},[212,868,869,874],{},[227,870,871],{},[230,872,873],{},"key create -org \u003Corg> -name \u003Cname>",[227,875,876],{},"Makes an API key and prints it once",[212,878,879,884],{},[227,880,881],{},[230,882,883],{},"audit verify -org \u003Corg>",[227,885,886],{},"Checks the organisation's audit chain and reports the first broken entry",[212,888,889,894],{},[227,890,891],{},[230,892,893],{},"rules seed -org \u003Corg>",[227,895,896],{},"Installs the built-in rules as active, editable rules. Refuses if the organisation already has rule versions.",[212,898,899,904],{},[227,900,901],{},[230,902,903],{},"screening load -file \u003Clist.json>",[227,905,906],{},"Loads a sanctions or PEP list, or replaces the loaded list with the same code",[198,908,910],{"id":909},"network","Network",[206,912,913,926],{},[209,914,915],{},[212,916,917,920,923],{},[215,918,919],{},"Connection",[215,921,922],{},"Direction",[215,924,925],{},"Purpose",[222,927,928,942,952,963],{},[212,929,930,933,936],{},[227,931,932],{},"Your services → API",[227,934,935],{},"Inbound",[227,937,938,939,941],{},"Events, entities, decisions and the rest of ",[230,940,238],{},". Internal network only; no public exposure needed.",[212,943,944,947,949],{},[227,945,946],{},"Browsers → dashboard",[227,948,935],{},[227,950,951],{},"Your compliance team. Same port as the API.",[212,953,954,957,960],{},[227,955,956],{},"API → PostgreSQL",[227,958,959],{},"Outbound, internal",[227,961,962],{},"Required",[212,964,965,968,970],{},[227,966,967],{},"API → Redis",[227,969,959],{},[227,971,972],{},"Optional",[189,974,975],{},"The binary speaks plain HTTP. Put TLS in front of it with your load balancer or reverse proxy.",[198,977,979],{"id":978},"operations","Operations",[981,982,983,996,1002,1008],"ul",{},[984,985,986,989,990,993,994,196],"li",{},[193,987,988],{},"Health."," ",[230,991,992],{},"GET \u002Fhealthz"," returns status and version, for your load balancer and monitoring. See ",[624,995,102],{"href":103},[984,997,998,1001],{},[193,999,1000],{},"Logs."," Structured JSON on standard output.",[984,1003,1004,1007],{},[193,1005,1006],{},"Several instances."," You can run more than one behind a load balancer. Instances starting together take turns applying migrations. A rule activation takes effect at once on the instance that handled it and within 30 seconds on the others. New screening lists show up within 30 seconds too.",[984,1009,1010,1013],{},[193,1011,1012],{},"Backups."," Standard PostgreSQL backups cover everything that matters. Redis holds nothing that can't be rebuilt.",[198,1015,1017],{"id":1016},"not-built-yet","Not built yet",[189,1019,1020],{},"The product design includes more than the binary does today. None of these exist yet:",[981,1022,1023,1026,1029,1032,1035,1038],{},[984,1024,1025],{},"Async processing on an event stream, and the workers that would deliver webhooks and file reports.",[984,1027,1028],{},"Connectors that pull events from rails.",[984,1030,1031],{},"A licence agent, usage metering, and signed updates for releases, lists and rule packs.",[984,1033,1034],{},"Air-gapped update bundles.",[984,1036,1037],{},"Sign-in through your SSO. The dashboard signs in with an API key.",[984,1039,1040],{},"A Helm chart or a documented high-availability layout.",[1042,1043,1044],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":311,"searchDepth":343,"depth":343,"links":1046},[1047,1048,1049,1050,1051,1058,1059,1060,1061],{"id":200,"depth":343,"text":201},{"id":290,"depth":343,"text":291},{"id":451,"depth":343,"text":452},{"id":514,"depth":343,"text":515},{"id":756,"depth":343,"text":757,"children":1052},[1053,1054,1055,1056,1057],{"id":765,"depth":350,"text":766},{"id":775,"depth":350,"text":776},{"id":792,"depth":350,"text":793},{"id":803,"depth":350,"text":804},{"id":817,"depth":350,"text":818},{"id":830,"depth":343,"text":831},{"id":909,"depth":343,"text":910},{"id":978,"depth":343,"text":979},{"id":1016,"depth":343,"text":1017},"What a Sentinel install runs, how to deploy it with Docker or from source, and how to configure and operate it.","md",null,{},{"icon":24},{"title":21,"description":1062},"O2-ubtBooNHrLq-mMaTV-KA9wt4odw0IppWcOwOkLE8",[1070,1072],{"title":16,"path":17,"stem":18,"description":1071,"icon":19,"children":-1},"Run Sentinel locally, make a key, send events, and work the alert they raise.",{"title":31,"path":32,"stem":33,"description":1073,"icon":34,"children":-1},"The loop every anti-money laundering programme follows, and where Sentinel fits in it.",1792169656545]