print.html 1.1 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732
  1. <!DOCTYPE HTML>
  2. <html lang="en" class="sidebar-visible no-js light">
  3. <head>
  4. <!-- Book generated using mdBook -->
  5. <meta charset="UTF-8">
  6. <title>Synapse</title>
  7. <meta name="robots" content="noindex" />
  8. <!-- Custom HTML head -->
  9. <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  10. <meta name="description" content="">
  11. <meta name="viewport" content="width=device-width, initial-scale=1">
  12. <meta name="theme-color" content="#ffffff" />
  13. <link rel="icon" href="favicon.svg">
  14. <link rel="shortcut icon" href="favicon.png">
  15. <link rel="stylesheet" href="css/variables.css">
  16. <link rel="stylesheet" href="css/general.css">
  17. <link rel="stylesheet" href="css/chrome.css">
  18. <link rel="stylesheet" href="css/print.css" media="print">
  19. <!-- Fonts -->
  20. <link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
  21. <link rel="stylesheet" href="fonts/fonts.css">
  22. <!-- Highlight.js Stylesheets -->
  23. <link rel="stylesheet" href="highlight.css">
  24. <link rel="stylesheet" href="tomorrow-night.css">
  25. <link rel="stylesheet" href="ayu-highlight.css">
  26. <!-- Custom theme stylesheets -->
  27. <link rel="stylesheet" href="docs/website_files/table-of-contents.css">
  28. <link rel="stylesheet" href="docs/website_files/remove-nav-buttons.css">
  29. <link rel="stylesheet" href="docs/website_files/indent-section-headers.css">
  30. <link rel="stylesheet" href="docs/website_files/version-picker.css">
  31. </head>
  32. <body>
  33. <!-- Provide site root to javascript -->
  34. <script type="text/javascript">
  35. var path_to_root = "";
  36. var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
  37. </script>
  38. <!-- Work around some values being stored in localStorage wrapped in quotes -->
  39. <script type="text/javascript">
  40. try {
  41. var theme = localStorage.getItem('mdbook-theme');
  42. var sidebar = localStorage.getItem('mdbook-sidebar');
  43. if (theme.startsWith('"') && theme.endsWith('"')) {
  44. localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
  45. }
  46. if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
  47. localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
  48. }
  49. } catch (e) { }
  50. </script>
  51. <!-- Set the theme before any content is loaded, prevents flash -->
  52. <script type="text/javascript">
  53. var theme;
  54. try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
  55. if (theme === null || theme === undefined) { theme = default_theme; }
  56. var html = document.querySelector('html');
  57. html.classList.remove('no-js')
  58. html.classList.remove('light')
  59. html.classList.add(theme);
  60. html.classList.add('js');
  61. </script>
  62. <!-- Hide / unhide sidebar before it is displayed -->
  63. <script type="text/javascript">
  64. var html = document.querySelector('html');
  65. var sidebar = 'hidden';
  66. if (document.body.clientWidth >= 1080) {
  67. try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
  68. sidebar = sidebar || 'visible';
  69. }
  70. html.classList.remove('sidebar-visible');
  71. html.classList.add("sidebar-" + sidebar);
  72. </script>
  73. <nav id="sidebar" class="sidebar" aria-label="Table of contents">
  74. <div class="sidebar-scrollbox">
  75. <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="setup/turn/coturn.html">coturn TURN server</a></li><li class="chapter-item expanded "><a href="setup/turn/eturnal.html">eturnal TURN server</a></li></ol></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/config_documentation.html">Configuration Manual</a></li><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/refresh_tokens.html">Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_data_callbacks.html">Account data callbacks</a></li><li class="chapter-item expanded "><a href="modules/add_extra_fields_to_client_events_unsigned.html">Add extra fields to client events unsigned section callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/experimental_features.html">Experimental Features</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/monitoring/reporting_homeserver_usage_statistics.html">Reporting Homeserver Usage Statistics</a></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/monthly_active_users.html">Monthly Active Users</a></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/reviews.html">Reviewing Code</a></li><li class="chapter-item expanded "><a href="development/releases.html">Release Cycle</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/demo.html">Demo scripts</a></li></ol></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><a href="development/dependencies.html">Dependency management</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/synapse_architecture/cancellation.html">Cancellation</a></li><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="development/synapse_architecture/streams.html">Streams</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li><li class="chapter-item expanded "><a href="development/synapse_architecture/faster_joins.html">Faster remote joins</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
  76. </div>
  77. <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
  78. </nav>
  79. <div id="page-wrapper" class="page-wrapper">
  80. <div class="page">
  81. <div id="menu-bar-hover-placeholder"></div>
  82. <div id="menu-bar" class="menu-bar sticky bordered">
  83. <div class="left-buttons">
  84. <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
  85. <i class="fa fa-bars"></i>
  86. </button>
  87. <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
  88. <i class="fa fa-paint-brush"></i>
  89. </button>
  90. <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
  91. <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
  92. <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
  93. <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
  94. <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
  95. <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
  96. </ul>
  97. <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
  98. <i class="fa fa-search"></i>
  99. </button>
  100. <div class="version-picker">
  101. <div class="dropdown">
  102. <div class="select">
  103. <span></span>
  104. <i class="fa fa-chevron-down"></i>
  105. </div>
  106. <input type="hidden" name="version">
  107. <ul class="dropdown-menu">
  108. <!-- Versions will be added dynamically in version-picker.js -->
  109. </ul>
  110. </div>
  111. </div>
  112. </div>
  113. <h1 class="menu-title">Synapse</h1>
  114. <div class="right-buttons">
  115. <a href="print.html" title="Print this book" aria-label="Print this book">
  116. <i id="print-button" class="fa fa-print"></i>
  117. </a>
  118. <a href="https://github.com/matrix-org/synapse" title="Git repository" aria-label="Git repository">
  119. <i id="git-repository-button" class="fa fa-github"></i>
  120. </a>
  121. </div>
  122. </div>
  123. <div id="search-wrapper" class="hidden">
  124. <form id="searchbar-outer" class="searchbar-outer">
  125. <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
  126. </form>
  127. <div id="searchresults-outer" class="searchresults-outer hidden">
  128. <div id="searchresults-header" class="searchresults-header"></div>
  129. <ul id="searchresults">
  130. </ul>
  131. </div>
  132. </div>
  133. <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
  134. <script type="text/javascript">
  135. document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
  136. document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
  137. Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
  138. link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
  139. });
  140. </script>
  141. <div id="content" class="content">
  142. <main>
  143. <!-- Page table of contents -->
  144. <div class="sidetoc">
  145. <nav class="pagetoc"></nav>
  146. </div>
  147. <div style="break-before: page; page-break-before: always;"></div><h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
  148. <p>Welcome to the documentation repository for Synapse, a
  149. <a href="https://matrix.org">Matrix</a> homeserver implementation developed by the matrix.org core
  150. team.</p>
  151. <h2 id="installing-and-using-synapse"><a class="header" href="#installing-and-using-synapse">Installing and using Synapse</a></h2>
  152. <p>This documentation covers topics for <strong>installation</strong>, <strong>configuration</strong> and
  153. <strong>maintenance</strong> of your Synapse process:</p>
  154. <ul>
  155. <li>
  156. <p>Learn how to <a href="setup/installation.html">install</a> and
  157. <a href="usage/configuration/config_documentation.html">configure</a> your own instance, perhaps with <a href="usage/configuration/user_authentication/index.html">Single
  158. Sign-On</a>.</p>
  159. </li>
  160. <li>
  161. <p>See how to <a href="upgrade.html">upgrade</a> between Synapse versions.</p>
  162. </li>
  163. <li>
  164. <p>Administer your instance using the <a href="usage/administration/admin_api/index.html">Admin
  165. API</a>, installing <a href="modules/index.html">pluggable
  166. modules</a>, or by accessing the <a href="manhole.html">manhole</a>.</p>
  167. </li>
  168. <li>
  169. <p>Learn how to <a href="usage/administration/request_log.html">read log lines</a>, configure
  170. <a href="usage/configuration/logging_sample_config.html">logging</a> or set up <a href="structured_logging.html">structured
  171. logging</a>.</p>
  172. </li>
  173. <li>
  174. <p>Scale Synapse through additional <a href="workers.html">worker processes</a>.</p>
  175. </li>
  176. <li>
  177. <p>Set up <a href="metrics-howto.html">monitoring and metrics</a> to keep an eye on your
  178. Synapse instance's performance.</p>
  179. </li>
  180. </ul>
  181. <h2 id="developing-on-synapse"><a class="header" href="#developing-on-synapse">Developing on Synapse</a></h2>
  182. <p>Contributions are welcome! Synapse is primarily written in
  183. <a href="https://python.org">Python</a>. As a developer, you may be interested in the
  184. following documentation:</p>
  185. <ul>
  186. <li>
  187. <p>Read the <a href="development/contributing_guide.html">Contributing Guide</a>. It is meant
  188. to walk new contributors through the process of developing and submitting a
  189. change to the Synapse codebase (which is <a href="https://github.com/matrix-org/synapse">hosted on
  190. GitHub</a>).</p>
  191. </li>
  192. <li>
  193. <p>Set up your <a href="development/contributing_guide.html#2-what-do-i-need">development
  194. environment</a>, then learn
  195. how to <a href="development/contributing_guide.html#run-the-linters">lint</a> and
  196. <a href="development/contributing_guide.html#8-test-test-test">test</a> your code.</p>
  197. </li>
  198. <li>
  199. <p>Look at <a href="https://github.com/matrix-org/synapse/issues">the issue tracker</a> for
  200. bugs to fix or features to add. If you're new, it may be best to start with
  201. those labeled <a href="https://github.com/matrix-org/synapse/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22">good first
  202. issue</a>.</p>
  203. </li>
  204. <li>
  205. <p>Understand <a href="development/internal_documentation/index.html">how Synapse is
  206. built</a>, how to <a href="development/database_schema.html">migrate
  207. database schemas</a>, learn about
  208. <a href="federate.html">federation</a> and how to <a href="federate.html#running-a-demo-federation-of-synapses">set up a local
  209. federation</a> for development.</p>
  210. </li>
  211. <li>
  212. <p>We like to keep our <code>git</code> history clean. <a href="development/git.html">Learn</a> how to
  213. do so!</p>
  214. </li>
  215. <li>
  216. <p>And finally, contribute to this documentation! The source for which is
  217. <a href="https://github.com/matrix-org/synapse/tree/develop/docs">located here</a>.</p>
  218. </li>
  219. </ul>
  220. <h2 id="donating-to-synapse-development"><a class="header" href="#donating-to-synapse-development">Donating to Synapse development</a></h2>
  221. <p>Want to help keep Synapse going but don't know how to code? Synapse is a
  222. <a href="https://matrix.org">Matrix.org Foundation</a> project. Consider becoming a
  223. supporter on <a href="https://liberapay.com/matrixdotorg">Liberapay</a>,
  224. <a href="https://patreon.com/matrixdotorg">Patreon</a> or through
  225. <a href="https://paypal.me/matrixdotorg">PayPal</a> via a one-time donation.</p>
  226. <p>If you are an organisation or enterprise and would like to sponsor development,
  227. reach out to us over email at: support (at) matrix.org</p>
  228. <h2 id="reporting-a-security-vulnerability"><a class="header" href="#reporting-a-security-vulnerability">Reporting a security vulnerability</a></h2>
  229. <p>If you've found a security issue in Synapse or any other Matrix.org Foundation
  230. project, please report it to us in accordance with our <a href="https://www.matrix.org/security-disclosure-policy/">Security Disclosure
  231. Policy</a>. Thank you!</p>
  232. <div style="break-before: page; page-break-before: always;"></div><h1 id="installation-instructions"><a class="header" href="#installation-instructions">Installation Instructions</a></h1>
  233. <h2 id="choosing-your-server-name"><a class="header" href="#choosing-your-server-name">Choosing your server name</a></h2>
  234. <p>It is important to choose the name for your server before you install Synapse,
  235. because it cannot be changed later.</p>
  236. <p>The server name determines the &quot;domain&quot; part of user-ids for users on your
  237. server: these will all be of the format <code>@user:my.domain.name</code>. It also
  238. determines how other matrix servers will reach yours for federation.</p>
  239. <p>For a test configuration, set this to the hostname of your server. For a more
  240. production-ready setup, you will probably want to specify your domain
  241. (<code>example.com</code>) rather than a matrix-specific hostname here (in the same way
  242. that your email address is probably <code>user@example.com</code> rather than
  243. <code>user@email.example.com</code>) - but doing so may require more advanced setup: see
  244. <a href="setup/../federate.html">Setting up Federation</a>.</p>
  245. <h2 id="installing-synapse"><a class="header" href="#installing-synapse">Installing Synapse</a></h2>
  246. <h3 id="prebuilt-packages"><a class="header" href="#prebuilt-packages">Prebuilt packages</a></h3>
  247. <p>Prebuilt packages are available for a number of platforms. These are recommended
  248. for most users.</p>
  249. <h4 id="docker-images-and-ansible-playbooks"><a class="header" href="#docker-images-and-ansible-playbooks">Docker images and Ansible playbooks</a></h4>
  250. <p>There is an official synapse image available at
  251. <a href="https://hub.docker.com/r/matrixdotorg/synapse">https://hub.docker.com/r/matrixdotorg/synapse</a> or at <a href="https://ghcr.io/matrix-org/synapse"><code>ghcr.io/matrix-org/synapse</code></a>
  252. which can be used with the docker-compose file available at
  253. <a href="https://github.com/matrix-org/synapse/tree/develop/contrib/docker">contrib/docker</a>.
  254. Further information on this including configuration options is available in the README
  255. on hub.docker.com.</p>
  256. <p>Alternatively, Andreas Peters (previously Silvio Fricke) has contributed a
  257. Dockerfile to automate a synapse server in a single Docker image, at
  258. <a href="https://hub.docker.com/r/avhost/docker-matrix/tags/">https://hub.docker.com/r/avhost/docker-matrix/tags/</a></p>
  259. <p>Slavi Pantaleev has created an Ansible playbook,
  260. which installs the official Docker image of Matrix Synapse
  261. along with many other Matrix-related services (Postgres database, Element, coturn,
  262. ma1sd, SSL support, etc.).
  263. For more details, see
  264. <a href="https://github.com/spantaleev/matrix-docker-ansible-deploy">https://github.com/spantaleev/matrix-docker-ansible-deploy</a></p>
  265. <h4 id="debianubuntu"><a class="header" href="#debianubuntu">Debian/Ubuntu</a></h4>
  266. <h5 id="matrixorg-packages"><a class="header" href="#matrixorg-packages">Matrix.org packages</a></h5>
  267. <p>Matrix.org provides Debian/Ubuntu packages of Synapse, for the amd64
  268. architecture via <a href="https://packages.matrix.org/debian/">https://packages.matrix.org/debian/</a>.</p>
  269. <p>To install the latest release:</p>
  270. <pre><code class="language-sh">sudo apt install -y lsb-release wget apt-transport-https
  271. sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
  272. echo &quot;deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main&quot; |
  273. sudo tee /etc/apt/sources.list.d/matrix-org.list
  274. sudo apt update
  275. sudo apt install matrix-synapse-py3
  276. </code></pre>
  277. <p>Packages are also published for release candidates. To enable the prerelease
  278. channel, add <code>prerelease</code> to the <code>sources.list</code> line. For example:</p>
  279. <pre><code class="language-sh">sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
  280. echo &quot;deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main prerelease&quot; |
  281. sudo tee /etc/apt/sources.list.d/matrix-org.list
  282. sudo apt update
  283. sudo apt install matrix-synapse-py3
  284. </code></pre>
  285. <p>The fingerprint of the repository signing key (as shown by <code>gpg /usr/share/keyrings/matrix-org-archive-keyring.gpg</code>) is
  286. <code>AAF9AE843A7584B5A3E4CD2BCF45A512DE2DA058</code>.</p>
  287. <p>When installing with Debian packages, you might prefer to place files in
  288. <code>/etc/matrix-synapse/conf.d/</code> to override your configuration without editing
  289. the main configuration file at <code>/etc/matrix-synapse/homeserver.yaml</code>.
  290. By doing that, you won't be asked if you want to replace your configuration
  291. file when you upgrade the Debian package to a later version.</p>
  292. <h5 id="downstream-debian-packages"><a class="header" href="#downstream-debian-packages">Downstream Debian packages</a></h5>
  293. <p>Andrej Shadura maintains a
  294. <a href="https://packages.debian.org/sid/matrix-synapse"><code>matrix-synapse</code></a> package in
  295. the Debian repositories.
  296. For <code>bookworm</code> and <code>sid</code>, it can be installed simply with:</p>
  297. <pre><code class="language-sh">sudo apt install matrix-synapse
  298. </code></pre>
  299. <p>Synapse is also available in <code>bullseye-backports</code>. Please
  300. see the <a href="https://backports.debian.org/Instructions/">Debian documentation</a>
  301. for information on how to use backports.</p>
  302. <p><code>matrix-synapse</code> is no longer maintained for <code>buster</code> and older.</p>
  303. <h5 id="downstream-ubuntu-packages"><a class="header" href="#downstream-ubuntu-packages">Downstream Ubuntu packages</a></h5>
  304. <p>We do not recommend using the packages in the default Ubuntu repository
  305. at this time, as they are <a href="https://bugs.launchpad.net/ubuntu/+source/matrix-synapse/+bug/1848709">old and suffer from known security vulnerabilities</a>.
  306. The latest version of Synapse can be installed from <a href="setup/installation.html#matrixorg-packages">our repository</a>.</p>
  307. <h4 id="fedora"><a class="header" href="#fedora">Fedora</a></h4>
  308. <p>Synapse is in the Fedora repositories as
  309. <a href="https://src.fedoraproject.org/rpms/matrix-synapse"><code>matrix-synapse</code></a>:</p>
  310. <pre><code class="language-sh">sudo dnf install matrix-synapse
  311. </code></pre>
  312. <p>Additionally, Oleg Girko provides Fedora RPMs at
  313. <a href="https://obs.infoserver.lv/project/monitor/matrix-synapse">https://obs.infoserver.lv/project/monitor/matrix-synapse</a></p>
  314. <h4 id="opensuse"><a class="header" href="#opensuse">OpenSUSE</a></h4>
  315. <p>Synapse is in the OpenSUSE repositories as
  316. <a href="https://software.opensuse.org/package/matrix-synapse"><code>matrix-synapse</code></a>:</p>
  317. <pre><code class="language-sh">sudo zypper install matrix-synapse
  318. </code></pre>
  319. <h4 id="suse-linux-enterprise-server"><a class="header" href="#suse-linux-enterprise-server">SUSE Linux Enterprise Server</a></h4>
  320. <p>Unofficial package are built for SLES 15 in the openSUSE:Backports:SLE-15 repository at
  321. <a href="https://download.opensuse.org/repositories/openSUSE:/Backports:/SLE-15/standard/">https://download.opensuse.org/repositories/openSUSE:/Backports:/SLE-15/standard/</a></p>
  322. <h4 id="archlinux"><a class="header" href="#archlinux">ArchLinux</a></h4>
  323. <p>The quickest way to get up and running with ArchLinux is probably with the package provided by ArchLinux
  324. <a href="https://archlinux.org/packages/extra/x86_64/matrix-synapse/">https://archlinux.org/packages/extra/x86_64/matrix-synapse/</a>, which should pull in most of
  325. the necessary dependencies.</p>
  326. <p>pip may be outdated (6.0.7-1 and needs to be upgraded to 6.0.8-1 ):</p>
  327. <pre><code class="language-sh">sudo pip install --upgrade pip
  328. </code></pre>
  329. <p>If you encounter an error with lib bcrypt causing an Wrong ELF Class:
  330. ELFCLASS32 (x64 Systems), you may need to reinstall py-bcrypt to correctly
  331. compile it under the right architecture. (This should not be needed if
  332. installing under virtualenv):</p>
  333. <pre><code class="language-sh">sudo pip uninstall py-bcrypt
  334. sudo pip install py-bcrypt
  335. </code></pre>
  336. <h4 id="alpine-linux"><a class="header" href="#alpine-linux">Alpine Linux</a></h4>
  337. <p>6543 maintains <a href="https://pkgs.alpinelinux.org/packages?name=synapse&amp;branch=edge">Synapse packages for Alpine Linux</a> in the community repository. Install with:</p>
  338. <pre><code class="language-sh">sudo apk add synapse
  339. </code></pre>
  340. <h4 id="void-linux"><a class="header" href="#void-linux">Void Linux</a></h4>
  341. <p>Synapse can be found in the void repositories as
  342. <a href="https://github.com/void-linux/void-packages/tree/master/srcpkgs/synapse">'synapse'</a>:</p>
  343. <pre><code class="language-sh">xbps-install -Su
  344. xbps-install -S synapse
  345. </code></pre>
  346. <h4 id="freebsd"><a class="header" href="#freebsd">FreeBSD</a></h4>
  347. <p>Synapse can be installed via FreeBSD Ports or Packages contributed by Brendan Molloy from:</p>
  348. <ul>
  349. <li>Ports: <code>cd /usr/ports/net-im/py-matrix-synapse &amp;&amp; make install clean</code></li>
  350. <li>Packages: <code>pkg install py38-matrix-synapse</code></li>
  351. </ul>
  352. <h4 id="openbsd"><a class="header" href="#openbsd">OpenBSD</a></h4>
  353. <p>As of OpenBSD 6.7 Synapse is available as a pre-compiled binary. The filesystem
  354. underlying the homeserver directory (defaults to <code>/var/synapse</code>) has to be
  355. mounted with <code>wxallowed</code> (cf. <code>mount(8)</code>), so creating a separate filesystem
  356. and mounting it to <code>/var/synapse</code> should be taken into consideration.</p>
  357. <p>Installing Synapse:</p>
  358. <pre><code class="language-sh">doas pkg_add synapse
  359. </code></pre>
  360. <h4 id="nixos"><a class="header" href="#nixos">NixOS</a></h4>
  361. <p>Robin Lambertz has packaged Synapse for NixOS at:
  362. <a href="https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/matrix/synapse.nix">https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/matrix/synapse.nix</a></p>
  363. <h3 id="installing-as-a-python-module-from-pypi"><a class="header" href="#installing-as-a-python-module-from-pypi">Installing as a Python module from PyPI</a></h3>
  364. <p>It's also possible to install Synapse as a Python module from PyPI.</p>
  365. <p>When following this route please make sure that the <a href="setup/installation.html#platform-specific-prerequisites">Platform-specific prerequisites</a> are already installed.</p>
  366. <p>System requirements:</p>
  367. <ul>
  368. <li>POSIX-compliant system (tested on Linux &amp; OS X)</li>
  369. <li>Python 3.8 or later, up to Python 3.11.</li>
  370. <li>At least 1GB of free RAM if you want to join large public rooms like #matrix:matrix.org</li>
  371. </ul>
  372. <p>If building on an uncommon architecture for which pre-built wheels are
  373. unavailable, you will need to have a recent Rust compiler installed. The easiest
  374. way of installing the latest version is to use <a href="https://rustup.rs/">rustup</a>.</p>
  375. <p>To install the Synapse homeserver run:</p>
  376. <pre><code class="language-sh">mkdir -p ~/synapse
  377. virtualenv -p python3 ~/synapse/env
  378. source ~/synapse/env/bin/activate
  379. pip install --upgrade pip
  380. pip install --upgrade setuptools
  381. pip install matrix-synapse
  382. </code></pre>
  383. <p>This will download Synapse from <a href="https://pypi.org/project/matrix-synapse">PyPI</a>
  384. and install it, along with the python libraries it uses, into a virtual environment
  385. under <code>~/synapse/env</code>. Feel free to pick a different directory if you
  386. prefer.</p>
  387. <p>This Synapse installation can then be later upgraded by using pip again with the
  388. update flag:</p>
  389. <pre><code class="language-sh">source ~/synapse/env/bin/activate
  390. pip install -U matrix-synapse
  391. </code></pre>
  392. <p>Before you can start Synapse, you will need to generate a configuration
  393. file. To do this, run (in your virtualenv, as before):</p>
  394. <pre><code class="language-sh">cd ~/synapse
  395. python -m synapse.app.homeserver \
  396. --server-name my.domain.name \
  397. --config-path homeserver.yaml \
  398. --generate-config \
  399. --report-stats=[yes|no]
  400. </code></pre>
  401. <p>... substituting an appropriate value for <code>--server-name</code> and choosing whether
  402. or not to report usage statistics (hostname, Synapse version, uptime, total
  403. users, etc.) to the developers via the <code>--report-stats</code> argument.</p>
  404. <p>This command will generate you a config file that you can then customise, but it will
  405. also generate a set of keys for you. These keys will allow your homeserver to
  406. identify itself to other homeserver, so don't lose or delete them. It would be
  407. wise to back them up somewhere safe. (If, for whatever reason, you do need to
  408. change your homeserver's keys, you may find that other homeserver have the
  409. old key cached. If you update the signing key, you should change the name of the
  410. key in the <code>&lt;server name&gt;.signing.key</code> file (the second word) to something
  411. different. See the <a href="https://matrix.org/docs/spec/server_server/latest.html#retrieving-server-keys">spec</a> for more information on key management).</p>
  412. <p>To actually run your new homeserver, pick a working directory for Synapse to
  413. run (e.g. <code>~/synapse</code>), and:</p>
  414. <pre><code class="language-sh">cd ~/synapse
  415. source env/bin/activate
  416. synctl start
  417. </code></pre>
  418. <h4 id="platform-specific-prerequisites"><a class="header" href="#platform-specific-prerequisites">Platform-specific prerequisites</a></h4>
  419. <p>Synapse is written in Python but some of the libraries it uses are written in
  420. C. So before we can install Synapse itself we need a working C compiler and the
  421. header files for Python C extensions.</p>
  422. <h5 id="debianubunturaspbian"><a class="header" href="#debianubunturaspbian">Debian/Ubuntu/Raspbian</a></h5>
  423. <p>Installing prerequisites on Ubuntu or Debian:</p>
  424. <pre><code class="language-sh">sudo apt install build-essential python3-dev libffi-dev \
  425. python3-pip python3-setuptools sqlite3 \
  426. libssl-dev virtualenv libjpeg-dev libxslt1-dev libicu-dev
  427. </code></pre>
  428. <h5 id="archlinux-1"><a class="header" href="#archlinux-1">ArchLinux</a></h5>
  429. <p>Installing prerequisites on ArchLinux:</p>
  430. <pre><code class="language-sh">sudo pacman -S base-devel python python-pip \
  431. python-setuptools python-virtualenv sqlite3 icu
  432. </code></pre>
  433. <h5 id="centosfedora"><a class="header" href="#centosfedora">CentOS/Fedora</a></h5>
  434. <p>Installing prerequisites on CentOS or Fedora Linux:</p>
  435. <pre><code class="language-sh">sudo dnf install libtiff-devel libjpeg-devel libzip-devel freetype-devel \
  436. libwebp-devel libxml2-devel libxslt-devel libpq-devel \
  437. python3-virtualenv libffi-devel openssl-devel python3-devel \
  438. libicu-devel
  439. sudo dnf groupinstall &quot;Development Tools&quot;
  440. </code></pre>
  441. <h5 id="macos"><a class="header" href="#macos">macOS</a></h5>
  442. <p>Installing prerequisites on macOS:</p>
  443. <p>You may need to install the latest Xcode developer tools:</p>
  444. <pre><code class="language-sh">xcode-select --install
  445. </code></pre>
  446. <p>Some extra dependencies may be needed. You can use Homebrew (https://brew.sh) for them.</p>
  447. <p>You may need to install icu, and make the icu binaries and libraries accessible.
  448. Please follow <a href="https://pypi.org/project/PyICU/">the official instructions of PyICU</a> to do so.</p>
  449. <p>On ARM-based Macs you may also need to install libjpeg and libpq:</p>
  450. <pre><code class="language-sh"> brew install jpeg libpq
  451. </code></pre>
  452. <p>On macOS Catalina (10.15) you may need to explicitly install OpenSSL
  453. via brew and inform <code>pip</code> about it so that <code>psycopg2</code> builds:</p>
  454. <pre><code class="language-sh">brew install openssl@1.1
  455. export LDFLAGS=&quot;-L/usr/local/opt/openssl/lib&quot;
  456. export CPPFLAGS=&quot;-I/usr/local/opt/openssl/include&quot;
  457. </code></pre>
  458. <h5 id="opensuse-1"><a class="header" href="#opensuse-1">OpenSUSE</a></h5>
  459. <p>Installing prerequisites on openSUSE:</p>
  460. <pre><code class="language-sh">sudo zypper in -t pattern devel_basis
  461. sudo zypper in python-pip python-setuptools sqlite3 python-virtualenv \
  462. python-devel libffi-devel libopenssl-devel libjpeg62-devel \
  463. libicu-devel
  464. </code></pre>
  465. <h5 id="openbsd-1"><a class="header" href="#openbsd-1">OpenBSD</a></h5>
  466. <p>A port of Synapse is available under <code>net/synapse</code>. The filesystem
  467. underlying the homeserver directory (defaults to <code>/var/synapse</code>) has to be
  468. mounted with <code>wxallowed</code> (cf. <code>mount(8)</code>), so creating a separate filesystem
  469. and mounting it to <code>/var/synapse</code> should be taken into consideration.</p>
  470. <p>To be able to build Synapse's dependency on python the <code>WRKOBJDIR</code>
  471. (cf. <code>bsd.port.mk(5)</code>) for building python, too, needs to be on a filesystem
  472. mounted with <code>wxallowed</code> (cf. <code>mount(8)</code>).</p>
  473. <p>Creating a <code>WRKOBJDIR</code> for building python under <code>/usr/local</code> (which on a
  474. default OpenBSD installation is mounted with <code>wxallowed</code>):</p>
  475. <pre><code class="language-sh">doas mkdir /usr/local/pobj_wxallowed
  476. </code></pre>
  477. <p>Assuming <code>PORTS_PRIVSEP=Yes</code> (cf. <code>bsd.port.mk(5)</code>) and <code>SUDO=doas</code> are
  478. configured in <code>/etc/mk.conf</code>:</p>
  479. <pre><code class="language-sh">doas chown _pbuild:_pbuild /usr/local/pobj_wxallowed
  480. </code></pre>
  481. <p>Setting the <code>WRKOBJDIR</code> for building python:</p>
  482. <pre><code class="language-sh">echo WRKOBJDIR_lang/python/3.7=/usr/local/pobj_wxallowed \\nWRKOBJDIR_lang/python/2.7=/usr/local/pobj_wxallowed &gt;&gt; /etc/mk.conf
  483. </code></pre>
  484. <p>Building Synapse:</p>
  485. <pre><code class="language-sh">cd /usr/ports/net/synapse
  486. make install
  487. </code></pre>
  488. <h5 id="windows"><a class="header" href="#windows">Windows</a></h5>
  489. <p>Running Synapse natively on Windows is not officially supported.</p>
  490. <p>If you wish to run or develop Synapse on Windows, the Windows Subsystem for
  491. Linux provides a Linux environment which is capable of using the Debian, Fedora,
  492. or source installation methods. More information about WSL can be found at
  493. <a href="https://docs.microsoft.com/en-us/windows/wsl/install">https://docs.microsoft.com/en-us/windows/wsl/install</a> for Windows 10/11 and
  494. <a href="https://docs.microsoft.com/en-us/windows/wsl/install-on-server">https://docs.microsoft.com/en-us/windows/wsl/install-on-server</a> for
  495. Windows Server.</p>
  496. <h2 id="setting-up-synapse"><a class="header" href="#setting-up-synapse">Setting up Synapse</a></h2>
  497. <p>Once you have installed synapse as above, you will need to configure it.</p>
  498. <h3 id="using-postgresql"><a class="header" href="#using-postgresql">Using PostgreSQL</a></h3>
  499. <p>By default Synapse uses an <a href="https://sqlite.org/">SQLite</a> database and in doing so trades
  500. performance for convenience. Almost all installations should opt to use <a href="https://www.postgresql.org">PostgreSQL</a>
  501. instead. Advantages include:</p>
  502. <ul>
  503. <li>significant performance improvements due to the superior threading and
  504. caching model, smarter query optimiser</li>
  505. <li>allowing the DB to be run on separate hardware</li>
  506. </ul>
  507. <p>For information on how to install and use PostgreSQL in Synapse, please see
  508. <a href="setup/../postgres.html">Using Postgres</a></p>
  509. <p>SQLite is only acceptable for testing purposes. SQLite should not be used in
  510. a production server. Synapse will perform poorly when using
  511. SQLite, especially when participating in large rooms.</p>
  512. <h3 id="tls-certificates"><a class="header" href="#tls-certificates">TLS certificates</a></h3>
  513. <p>The default configuration exposes a single HTTP port on the local
  514. interface: <code>http://localhost:8008</code>. It is suitable for local testing,
  515. but for any practical use, you will need Synapse's APIs to be served
  516. over HTTPS.</p>
  517. <p>The recommended way to do so is to set up a reverse proxy on port
  518. <code>8448</code>. You can find documentation on doing so in
  519. <a href="setup/../reverse_proxy.html">the reverse proxy documentation</a>.</p>
  520. <p>Alternatively, you can configure Synapse to expose an HTTPS port. To do
  521. so, you will need to edit <code>homeserver.yaml</code>, as follows:</p>
  522. <ul>
  523. <li>First, under the <code>listeners</code> option, add the configuration for the
  524. TLS-enabled listener like so:</li>
  525. </ul>
  526. <pre><code class="language-yaml">listeners:
  527. - port: 8448
  528. type: http
  529. tls: true
  530. resources:
  531. - names: [client, federation]
  532. </code></pre>
  533. <ul>
  534. <li>
  535. <p>You will also need to add the options <code>tls_certificate_path</code> and
  536. <code>tls_private_key_path</code>. to your configuration file. You will need to manage provisioning of
  537. these certificates yourself.</p>
  538. </li>
  539. <li>
  540. <p>You can find more information about these options as well as how to configure synapse in the
  541. <a href="setup/../usage/configuration/config_documentation.html">configuration manual</a>.</p>
  542. <p>If you are using your own certificate, be sure to use a <code>.pem</code> file that
  543. includes the full certificate chain including any intermediate certificates
  544. (for instance, if using certbot, use <code>fullchain.pem</code> as your certificate, not
  545. <code>cert.pem</code>).</p>
  546. </li>
  547. </ul>
  548. <p>For a more detailed guide to configuring your server for federation, see
  549. <a href="setup/../federate.html">Federation</a>.</p>
  550. <h3 id="client-well-known-uri"><a class="header" href="#client-well-known-uri">Client Well-Known URI</a></h3>
  551. <p>Setting up the client Well-Known URI is optional but if you set it up, it will
  552. allow users to enter their full username (e.g. <code>@user:&lt;server_name&gt;</code>) into clients
  553. which support well-known lookup to automatically configure the homeserver and
  554. identity server URLs. This is useful so that users don't have to memorize or think
  555. about the actual homeserver URL you are using.</p>
  556. <p>The URL <code>https://&lt;server_name&gt;/.well-known/matrix/client</code> should return JSON in
  557. the following format.</p>
  558. <pre><code class="language-json">{
  559. &quot;m.homeserver&quot;: {
  560. &quot;base_url&quot;: &quot;https://&lt;matrix.example.com&gt;&quot;
  561. }
  562. }
  563. </code></pre>
  564. <p>It can optionally contain identity server information as well.</p>
  565. <pre><code class="language-json">{
  566. &quot;m.homeserver&quot;: {
  567. &quot;base_url&quot;: &quot;https://&lt;matrix.example.com&gt;&quot;
  568. },
  569. &quot;m.identity_server&quot;: {
  570. &quot;base_url&quot;: &quot;https://&lt;identity.example.com&gt;&quot;
  571. }
  572. }
  573. </code></pre>
  574. <p>To work in browser based clients, the file must be served with the appropriate
  575. Cross-Origin Resource Sharing (CORS) headers. A recommended value would be
  576. <code>Access-Control-Allow-Origin: *</code> which would allow all browser based clients to
  577. view it.</p>
  578. <p>In nginx this would be something like:</p>
  579. <pre><code class="language-nginx">location /.well-known/matrix/client {
  580. return 200 '{&quot;m.homeserver&quot;: {&quot;base_url&quot;: &quot;https://&lt;matrix.example.com&gt;&quot;}}';
  581. default_type application/json;
  582. add_header Access-Control-Allow-Origin *;
  583. }
  584. </code></pre>
  585. <p>You should also ensure the <code>public_baseurl</code> option in <code>homeserver.yaml</code> is set
  586. correctly. <code>public_baseurl</code> should be set to the URL that clients will use to
  587. connect to your server. This is the same URL you put for the <code>m.homeserver</code>
  588. <code>base_url</code> above.</p>
  589. <pre><code class="language-yaml">public_baseurl: &quot;https://&lt;matrix.example.com&gt;&quot;
  590. </code></pre>
  591. <h3 id="email"><a class="header" href="#email">Email</a></h3>
  592. <p>It is desirable for Synapse to have the capability to send email. This allows
  593. Synapse to send password reset emails, send verifications when an email address
  594. is added to a user's account, and send email notifications to users when they
  595. receive new messages.</p>
  596. <p>To configure an SMTP server for Synapse, modify the configuration section
  597. headed <code>email</code>, and be sure to have at least the <code>smtp_host</code>, <code>smtp_port</code>
  598. and <code>notif_from</code> fields filled out. You may also need to set <code>smtp_user</code>,
  599. <code>smtp_pass</code>, and <code>require_transport_security</code>.</p>
  600. <p>If email is not configured, password reset, registration and notifications via
  601. email will be disabled.</p>
  602. <h3 id="registering-a-user"><a class="header" href="#registering-a-user">Registering a user</a></h3>
  603. <p>One way to create a new user is to do so from a client like
  604. <a href="https://element.io/">Element</a>. This requires registration to be enabled via
  605. the
  606. <a href="setup/../usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a>
  607. setting.</p>
  608. <p>Alternatively, you can create new users from the command line. This can be done as follows:</p>
  609. <ol>
  610. <li>If synapse was installed via pip, activate the virtualenv as follows (if Synapse was
  611. installed via a prebuilt package, <code>register_new_matrix_user</code> should already be
  612. on the search path):
  613. <pre><code class="language-sh">cd ~/synapse
  614. source env/bin/activate
  615. synctl start # if not already running
  616. </code></pre>
  617. </li>
  618. <li>Run the following command:
  619. <pre><code class="language-sh">register_new_matrix_user -c homeserver.yaml
  620. </code></pre>
  621. </li>
  622. </ol>
  623. <p>This will prompt you to add details for the new user, and will then connect to
  624. the running Synapse to create the new user. For example:</p>
  625. <pre><code>New user localpart: erikj
  626. Password:
  627. Confirm password:
  628. Make admin [no]:
  629. Success!
  630. </code></pre>
  631. <p>This process uses a setting
  632. <a href="setup/../usage/configuration/config_documentation.html#registration_shared_secret"><code>registration_shared_secret</code></a>,
  633. which is shared between Synapse itself and the <code>register_new_matrix_user</code>
  634. script. It doesn't matter what it is (a random value is generated by
  635. <code>--generate-config</code>), but it should be kept secret, as anyone with knowledge of
  636. it can register users, including admin accounts, on your server even if
  637. <code>enable_registration</code> is <code>false</code>.</p>
  638. <h3 id="setting-up-a-turn-server"><a class="header" href="#setting-up-a-turn-server">Setting up a TURN server</a></h3>
  639. <p>For reliable VoIP calls to be routed via this homeserver, you MUST configure
  640. a TURN server. See <a href="setup/../turn-howto.html">TURN setup</a> for details.</p>
  641. <h3 id="url-previews"><a class="header" href="#url-previews">URL previews</a></h3>
  642. <p>Synapse includes support for previewing URLs, which is disabled by default. To
  643. turn it on you must enable the <code>url_preview_enabled: True</code> config parameter
  644. and explicitly specify the IP ranges that Synapse is not allowed to spider for
  645. previewing in the <code>url_preview_ip_range_blacklist</code> configuration parameter.
  646. This is critical from a security perspective to stop arbitrary Matrix users
  647. spidering 'internal' URLs on your network. At the very least we recommend that
  648. your loopback and RFC1918 IP addresses are blacklisted.</p>
  649. <p>This also requires the optional <code>lxml</code> python dependency to be installed. This
  650. in turn requires the <code>libxml2</code> library to be available - on Debian/Ubuntu this
  651. means <code>apt-get install libxml2-dev</code>, or equivalent for your OS.</p>
  652. <h3 id="troubleshooting-installation"><a class="header" href="#troubleshooting-installation">Troubleshooting Installation</a></h3>
  653. <p><code>pip</code> seems to leak <em>lots</em> of memory during installation. For instance, a Linux
  654. host with 512MB of RAM may run out of memory whilst installing Twisted. If this
  655. happens, you will have to individually install the dependencies which are
  656. failing, e.g.:</p>
  657. <pre><code class="language-sh">pip install twisted
  658. </code></pre>
  659. <p>If you have any other problems, feel free to ask in
  660. <a href="https://matrix.to/#/#synapse:matrix.org">#synapse:matrix.org</a>.</p>
  661. <div style="break-before: page; page-break-before: always;"></div><h1 id="using-postgres"><a class="header" href="#using-postgres">Using Postgres</a></h1>
  662. <p>The minimum supported version of PostgreSQL is determined by the <a href="deprecation_policy.html">Dependency
  663. Deprecation Policy</a>.</p>
  664. <h2 id="install-postgres-client-libraries"><a class="header" href="#install-postgres-client-libraries">Install postgres client libraries</a></h2>
  665. <p>Synapse will require the python postgres client library in order to
  666. connect to a postgres database.</p>
  667. <ul>
  668. <li>
  669. <p>If you are using the <a href="setup/installation.html#matrixorg-packages">matrix.org debian/ubuntu
  670. packages</a>, the necessary python
  671. library will already be installed, but you will need to ensure the
  672. low-level postgres library is installed, which you can do with
  673. <code>apt install libpq5</code>.</p>
  674. </li>
  675. <li>
  676. <p>For other pre-built packages, please consult the documentation from
  677. the relevant package.</p>
  678. </li>
  679. <li>
  680. <p>If you installed synapse <a href="setup/installation.html#installing-as-a-python-module-from-pypi">in a
  681. virtualenv</a>, you can install
  682. the library with:</p>
  683. <pre><code>~/synapse/env/bin/pip install &quot;matrix-synapse[postgres]&quot;
  684. </code></pre>
  685. <p>(substituting the path to your virtualenv for <code>~/synapse/env</code>, if
  686. you used a different path). You will require the postgres
  687. development files. These are in the <code>libpq-dev</code> package on
  688. Debian-derived distributions.</p>
  689. </li>
  690. </ul>
  691. <h2 id="set-up-database"><a class="header" href="#set-up-database">Set up database</a></h2>
  692. <p>Assuming your PostgreSQL database user is called <code>postgres</code>, first authenticate as the database user with:</p>
  693. <pre><code class="language-sh">su - postgres
  694. # Or, if your system uses sudo to get administrative rights
  695. sudo -u postgres bash
  696. </code></pre>
  697. <p>Then, create a postgres user and a database with:</p>
  698. <pre><code class="language-sh"># this will prompt for a password for the new user
  699. createuser --pwprompt synapse_user
  700. createdb --encoding=UTF8 --locale=C --template=template0 --owner=synapse_user synapse
  701. </code></pre>
  702. <p>The above will create a user called <code>synapse_user</code>, and a database called
  703. <code>synapse</code>.</p>
  704. <p>Note that the PostgreSQL database <em>must</em> have the correct encoding set
  705. (as shown above), otherwise it will not be able to store UTF8 strings.</p>
  706. <p>You may need to enable password authentication so <code>synapse_user</code> can
  707. connect to the database. See
  708. <a href="https://www.postgresql.org/docs/current/auth-pg-hba-conf.html">https://www.postgresql.org/docs/current/auth-pg-hba-conf.html</a>.</p>
  709. <h2 id="synapse-config"><a class="header" href="#synapse-config">Synapse config</a></h2>
  710. <p>When you are ready to start using PostgreSQL, edit the <code>database</code>
  711. section in your config file to match the following lines:</p>
  712. <pre><code class="language-yaml">database:
  713. name: psycopg2
  714. args:
  715. user: &lt;user&gt;
  716. password: &lt;pass&gt;
  717. dbname: &lt;db&gt;
  718. host: &lt;host&gt;
  719. cp_min: 5
  720. cp_max: 10
  721. </code></pre>
  722. <p>All key, values in <code>args</code> are passed to the <code>psycopg2.connect(..)</code>
  723. function, except keys beginning with <code>cp_</code>, which are consumed by the
  724. twisted adbapi connection pool. See the <a href="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS">libpq
  725. documentation</a>
  726. for a list of options which can be passed.</p>
  727. <p>You should consider tuning the <code>args.keepalives_*</code> options if there is any danger of
  728. the connection between your homeserver and database dropping, otherwise Synapse
  729. may block for an extended period while it waits for a response from the
  730. database server. Example values might be:</p>
  731. <pre><code class="language-yaml">database:
  732. args:
  733. # ... as above
  734. # seconds of inactivity after which TCP should send a keepalive message to the server
  735. keepalives_idle: 10
  736. # the number of seconds after which a TCP keepalive message that is not
  737. # acknowledged by the server should be retransmitted
  738. keepalives_interval: 10
  739. # the number of TCP keepalives that can be lost before the client's connection
  740. # to the server is considered dead
  741. keepalives_count: 3
  742. </code></pre>
  743. <h2 id="tuning-postgres"><a class="header" href="#tuning-postgres">Tuning Postgres</a></h2>
  744. <p>The default settings should be fine for most deployments. For larger
  745. scale deployments tuning some of the settings is recommended, details of
  746. which can be found at
  747. <a href="https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server">https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server</a>.</p>
  748. <p>In particular, we've found tuning the following values helpful for
  749. performance:</p>
  750. <ul>
  751. <li><code>shared_buffers</code></li>
  752. <li><code>effective_cache_size</code></li>
  753. <li><code>work_mem</code></li>
  754. <li><code>maintenance_work_mem</code></li>
  755. <li><code>autovacuum_work_mem</code></li>
  756. </ul>
  757. <p>Note that the appropriate values for those fields depend on the amount
  758. of free memory the database host has available.</p>
  759. <p>Additionally, admins of large deployments might want to consider using huge pages
  760. to help manage memory, especially when using large values of <code>shared_buffers</code>. You
  761. can read more about that <a href="https://www.postgresql.org/docs/10/kernel-resources.html#LINUX-HUGE-PAGES">here</a>.</p>
  762. <h2 id="porting-from-sqlite"><a class="header" href="#porting-from-sqlite">Porting from SQLite</a></h2>
  763. <h3 id="overview"><a class="header" href="#overview">Overview</a></h3>
  764. <p>The script <code>synapse_port_db</code> allows porting an existing synapse server
  765. backed by SQLite to using PostgreSQL. This is done in as a two phase
  766. process:</p>
  767. <ol>
  768. <li>Copy the existing SQLite database to a separate location and run
  769. the port script against that offline database.</li>
  770. <li>Shut down the server. Rerun the port script to port any data that
  771. has come in since taking the first snapshot. Restart server against
  772. the PostgreSQL database.</li>
  773. </ol>
  774. <p>The port script is designed to be run repeatedly against newer snapshots
  775. of the SQLite database file. This makes it safe to repeat step 1 if
  776. there was a delay between taking the previous snapshot and being ready
  777. to do step 2.</p>
  778. <p>It is safe to at any time kill the port script and restart it.</p>
  779. <p>However, under no circumstances should the SQLite database be <code>VACUUM</code>ed between
  780. multiple runs of the script. Doing so can lead to an inconsistent copy of your database
  781. into Postgres.
  782. To avoid accidental error, the script will check that SQLite's <code>auto_vacuum</code> mechanism
  783. is disabled, but the script is not able to protect against a manual <code>VACUUM</code> operation
  784. performed either by the administrator or by any automated task that the administrator
  785. may have configured.</p>
  786. <p>Note that the database may take up significantly more (25% - 100% more)
  787. space on disk after porting to Postgres.</p>
  788. <h3 id="using-the-port-script"><a class="header" href="#using-the-port-script">Using the port script</a></h3>
  789. <p>Firstly, shut down the currently running synapse server and copy its
  790. database file (typically <code>homeserver.db</code>) to another location. Once the
  791. copy is complete, restart synapse. For instance:</p>
  792. <pre><code class="language-sh">synctl stop
  793. cp homeserver.db homeserver.db.snapshot
  794. synctl start
  795. </code></pre>
  796. <p>Copy the old config file into a new config file:</p>
  797. <pre><code class="language-sh">cp homeserver.yaml homeserver-postgres.yaml
  798. </code></pre>
  799. <p>Edit the database section as described in the section <em>Synapse config</em>
  800. above and with the SQLite snapshot located at <code>homeserver.db.snapshot</code>
  801. simply run:</p>
  802. <pre><code class="language-sh">synapse_port_db --sqlite-database homeserver.db.snapshot \
  803. --postgres-config homeserver-postgres.yaml
  804. </code></pre>
  805. <p>The flag <code>--curses</code> displays a coloured curses progress UI.</p>
  806. <p>If the script took a long time to complete, or time has otherwise passed
  807. since the original snapshot was taken, repeat the previous steps with a
  808. newer snapshot.</p>
  809. <p>To complete the conversion shut down the synapse server and run the port
  810. script one last time, e.g. if the SQLite database is at <code>homeserver.db</code>
  811. run:</p>
  812. <pre><code class="language-sh">synapse_port_db --sqlite-database homeserver.db \
  813. --postgres-config homeserver-postgres.yaml
  814. </code></pre>
  815. <p>Once that has completed, change the synapse config to point at the
  816. PostgreSQL database configuration file <code>homeserver-postgres.yaml</code>:</p>
  817. <pre><code class="language-sh">synctl stop
  818. mv homeserver.yaml homeserver-old-sqlite.yaml
  819. mv homeserver-postgres.yaml homeserver.yaml
  820. synctl start
  821. </code></pre>
  822. <p>Synapse should now be running against PostgreSQL.</p>
  823. <h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
  824. <h3 id="alternative-auth-methods"><a class="header" href="#alternative-auth-methods">Alternative auth methods</a></h3>
  825. <p>If you get an error along the lines of <code>FATAL: Ident authentication failed for user &quot;synapse_user&quot;</code>, you may need to use an authentication method other than
  826. <code>ident</code>:</p>
  827. <ul>
  828. <li>
  829. <p>If the <code>synapse_user</code> user has a password, add the password to the <code>database:</code>
  830. section of <code>homeserver.yaml</code>. Then add the following to <code>pg_hba.conf</code>:</p>
  831. <pre><code>host synapse synapse_user ::1/128 md5 # or `scram-sha-256` instead of `md5` if you use that
  832. </code></pre>
  833. </li>
  834. <li>
  835. <p>If the <code>synapse_user</code> user does not have a password, then a password doesn't
  836. have to be added to <code>homeserver.yaml</code>. But the following does need to be added
  837. to <code>pg_hba.conf</code>:</p>
  838. <pre><code>host synapse synapse_user ::1/128 trust
  839. </code></pre>
  840. </li>
  841. </ul>
  842. <p>Note that line order matters in <code>pg_hba.conf</code>, so make sure that if you do add a
  843. new line, it is inserted before:</p>
  844. <pre><code>host all all ::1/128 ident
  845. </code></pre>
  846. <h3 id="fixing-incorrect-collate-or-ctype"><a class="header" href="#fixing-incorrect-collate-or-ctype">Fixing incorrect <code>COLLATE</code> or <code>CTYPE</code></a></h3>
  847. <p>Synapse will refuse to set up a new database if it has the wrong values of
  848. <code>COLLATE</code> and <code>CTYPE</code> set. Synapse will also refuse to start an existing database with incorrect values
  849. of <code>COLLATE</code> and <code>CTYPE</code> unless the config flag <code>allow_unsafe_locale</code>, found in the
  850. <code>database</code> section of the config, is set to true. Using different locales can cause issues if the locale library is updated from
  851. underneath the database, or if a different version of the locale is used on any
  852. replicas.</p>
  853. <p>If you have a database with an unsafe locale, the safest way to fix the issue is to dump the database and recreate it with
  854. the correct locale parameter (as shown above). It is also possible to change the
  855. parameters on a live database and run a <code>REINDEX</code> on the entire database,
  856. however extreme care must be taken to avoid database corruption.</p>
  857. <p>Note that the above may fail with an error about duplicate rows if corruption
  858. has already occurred, and such duplicate rows will need to be manually removed.</p>
  859. <h3 id="fixing-inconsistent-sequences-error"><a class="header" href="#fixing-inconsistent-sequences-error">Fixing inconsistent sequences error</a></h3>
  860. <p>Synapse uses Postgres sequences to generate IDs for various tables. A sequence
  861. and associated table can get out of sync if, for example, Synapse has been
  862. downgraded and then upgraded again.</p>
  863. <p>To fix the issue shut down Synapse (including any and all workers) and run the
  864. SQL command included in the error message. Once done Synapse should start
  865. successfully.</p>
  866. <div style="break-before: page; page-break-before: always;"></div><h1 id="using-a-reverse-proxy-with-synapse"><a class="header" href="#using-a-reverse-proxy-with-synapse">Using a reverse proxy with Synapse</a></h1>
  867. <p>It is recommended to put a reverse proxy such as
  868. <a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html">nginx</a>,
  869. <a href="https://httpd.apache.org/docs/current/mod/mod_proxy_http.html">Apache</a>,
  870. <a href="https://caddyserver.com/docs/quick-starts/reverse-proxy">Caddy</a>,
  871. <a href="https://www.haproxy.org/">HAProxy</a> or
  872. <a href="https://man.openbsd.org/relayd.8">relayd</a> in front of Synapse. One advantage
  873. of doing so is that it means that you can expose the default https port
  874. (443) to Matrix clients without needing to run Synapse with root
  875. privileges.</p>
  876. <p>You should configure your reverse proxy to forward requests to <code>/_matrix</code> or
  877. <code>/_synapse/client</code> to Synapse, and have it set the <code>X-Forwarded-For</code> and
  878. <code>X-Forwarded-Proto</code> request headers.</p>
  879. <p>You should remember that Matrix clients and other Matrix servers do not
  880. necessarily need to connect to your server via the same server name or
  881. port. Indeed, clients will use port 443 by default, whereas servers default to
  882. port 8448. Where these are different, we refer to the 'client port' and the
  883. 'federation port'. See <a href="https://matrix.org/docs/spec/server_server/latest#resolving-server-names">the Matrix
  884. specification</a>
  885. for more details of the algorithm used for federation connections, and
  886. <a href="delegate.html">Delegation</a> for instructions on setting up delegation.</p>
  887. <p><strong>NOTE</strong>: Your reverse proxy must not <code>canonicalise</code> or <code>normalise</code>
  888. the requested URI in any way (for example, by decoding <code>%xx</code> escapes).
  889. Beware that Apache <em>will</em> canonicalise URIs unless you specify
  890. <code>nocanon</code>.</p>
  891. <p>Let's assume that we expect clients to connect to our server at
  892. <code>https://matrix.example.com</code>, and other servers to connect at
  893. <code>https://example.com:8448</code>. The following sections detail the configuration of
  894. the reverse proxy and the homeserver.</p>
  895. <h2 id="homeserver-configuration"><a class="header" href="#homeserver-configuration">Homeserver Configuration</a></h2>
  896. <p>The HTTP configuration will need to be updated for Synapse to correctly record
  897. client IP addresses and generate redirect URLs while behind a reverse proxy. </p>
  898. <p>In <code>homeserver.yaml</code> set <code>x_forwarded: true</code> in the port 8008 section and
  899. consider setting <code>bind_addresses: ['127.0.0.1']</code> so that the server only
  900. listens to traffic on localhost. (Do not change <code>bind_addresses</code> to <code>127.0.0.1</code>
  901. when using a containerized Synapse, as that will prevent it from responding
  902. to proxied traffic.)</p>
  903. <p>Optionally, you can also set
  904. <a href="./usage/configuration/config_documentation.html#listeners"><code>request_id_header</code></a>
  905. so that the server extracts and re-uses the same request ID format that the
  906. reverse proxy is using.</p>
  907. <h2 id="reverse-proxy-configuration-examples"><a class="header" href="#reverse-proxy-configuration-examples">Reverse-proxy configuration examples</a></h2>
  908. <p><strong>NOTE</strong>: You only need one of these.</p>
  909. <h3 id="nginx"><a class="header" href="#nginx">nginx</a></h3>
  910. <pre><code class="language-nginx">server {
  911. listen 443 ssl http2;
  912. listen [::]:443 ssl http2;
  913. # For the federation port
  914. listen 8448 ssl http2 default_server;
  915. listen [::]:8448 ssl http2 default_server;
  916. server_name matrix.example.com;
  917. location ~ ^(/_matrix|/_synapse/client) {
  918. # note: do not add a path (even a single /) after the port in `proxy_pass`,
  919. # otherwise nginx will canonicalise the URI and cause signature verification
  920. # errors.
  921. proxy_pass http://localhost:8008;
  922. proxy_set_header X-Forwarded-For $remote_addr;
  923. proxy_set_header X-Forwarded-Proto $scheme;
  924. proxy_set_header Host $host;
  925. # Nginx by default only allows file uploads up to 1M in size
  926. # Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
  927. client_max_body_size 50M;
  928. # Synapse responses may be chunked, which is an HTTP/1.1 feature.
  929. proxy_http_version 1.1;
  930. }
  931. }
  932. </code></pre>
  933. <h3 id="caddy-v2"><a class="header" href="#caddy-v2">Caddy v2</a></h3>
  934. <pre><code>matrix.example.com {
  935. reverse_proxy /_matrix/* localhost:8008
  936. reverse_proxy /_synapse/client/* localhost:8008
  937. }
  938. example.com:8448 {
  939. reverse_proxy /_matrix/* localhost:8008
  940. }
  941. </code></pre>
  942. <p><a href="delegate.html">Delegation</a> example:</p>
  943. <pre><code>example.com {
  944. header /.well-known/matrix/* Content-Type application/json
  945. header /.well-known/matrix/* Access-Control-Allow-Origin *
  946. respond /.well-known/matrix/server `{&quot;m.server&quot;: &quot;matrix.example.com:443&quot;}`
  947. respond /.well-known/matrix/client `{&quot;m.homeserver&quot;:{&quot;base_url&quot;:&quot;https://matrix.example.com&quot;},&quot;m.identity_server&quot;:{&quot;base_url&quot;:&quot;https://identity.example.com&quot;}}`
  948. }
  949. matrix.example.com {
  950. reverse_proxy /_matrix/* localhost:8008
  951. reverse_proxy /_synapse/client/* localhost:8008
  952. }
  953. </code></pre>
  954. <h3 id="apache"><a class="header" href="#apache">Apache</a></h3>
  955. <pre><code class="language-apache">&lt;VirtualHost *:443&gt;
  956. SSLEngine on
  957. ServerName matrix.example.com
  958. RequestHeader set &quot;X-Forwarded-Proto&quot; expr=%{REQUEST_SCHEME}
  959. AllowEncodedSlashes NoDecode
  960. ProxyPreserveHost on
  961. ProxyPass /_matrix http://127.0.0.1:8008/_matrix nocanon
  962. ProxyPassReverse /_matrix http://127.0.0.1:8008/_matrix
  963. ProxyPass /_synapse/client http://127.0.0.1:8008/_synapse/client nocanon
  964. ProxyPassReverse /_synapse/client http://127.0.0.1:8008/_synapse/client
  965. &lt;/VirtualHost&gt;
  966. &lt;VirtualHost *:8448&gt;
  967. SSLEngine on
  968. ServerName example.com
  969. RequestHeader set &quot;X-Forwarded-Proto&quot; expr=%{REQUEST_SCHEME}
  970. AllowEncodedSlashes NoDecode
  971. ProxyPass /_matrix http://127.0.0.1:8008/_matrix nocanon
  972. ProxyPassReverse /_matrix http://127.0.0.1:8008/_matrix
  973. &lt;/VirtualHost&gt;
  974. </code></pre>
  975. <p><strong>NOTE</strong>: ensure the <code>nocanon</code> options are included.</p>
  976. <p><strong>NOTE 2</strong>: It appears that Synapse is currently incompatible with the ModSecurity module for Apache (<code>mod_security2</code>). If you need it enabled for other services on your web server, you can disable it for Synapse's two VirtualHosts by including the following lines before each of the two <code>&lt;/VirtualHost&gt;</code> above:</p>
  977. <pre><code class="language-apache">&lt;IfModule security2_module&gt;
  978. SecRuleEngine off
  979. &lt;/IfModule&gt;
  980. </code></pre>
  981. <p><strong>NOTE 3</strong>: Missing <code>ProxyPreserveHost on</code> can lead to a redirect loop.</p>
  982. <h3 id="haproxy"><a class="header" href="#haproxy">HAProxy</a></h3>
  983. <pre><code>frontend https
  984. bind *:443,[::]:443 ssl crt /etc/ssl/haproxy/ strict-sni alpn h2,http/1.1
  985. http-request set-header X-Forwarded-Proto https if { ssl_fc }
  986. http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
  987. http-request set-header X-Forwarded-For %[src]
  988. # Matrix client traffic
  989. acl matrix-host hdr(host) -i matrix.example.com matrix.example.com:443
  990. acl matrix-path path_beg /_matrix
  991. acl matrix-path path_beg /_synapse/client
  992. use_backend matrix if matrix-host matrix-path
  993. frontend matrix-federation
  994. bind *:8448,[::]:8448 ssl crt /etc/ssl/haproxy/synapse.pem alpn h2,http/1.1
  995. http-request set-header X-Forwarded-Proto https if { ssl_fc }
  996. http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
  997. http-request set-header X-Forwarded-For %[src]
  998. default_backend matrix
  999. backend matrix
  1000. server matrix 127.0.0.1:8008
  1001. </code></pre>
  1002. <p>Example configuration, if using a UNIX socket. The configuration lines regarding the frontends do not need to be modified.</p>
  1003. <pre><code>backend matrix
  1004. server matrix unix@/run/synapse/main_public.sock
  1005. </code></pre>
  1006. <p><a href="delegate.html">Delegation</a> example:</p>
  1007. <pre><code>frontend https
  1008. acl matrix-well-known-client-path path /.well-known/matrix/client
  1009. acl matrix-well-known-server-path path /.well-known/matrix/server
  1010. use_backend matrix-well-known-client if matrix-well-known-client-path
  1011. use_backend matrix-well-known-server if matrix-well-known-server-path
  1012. backend matrix-well-known-client
  1013. http-after-response set-header Access-Control-Allow-Origin &quot;*&quot;
  1014. http-after-response set-header Access-Control-Allow-Methods &quot;GET, POST, PUT, DELETE, OPTIONS&quot;
  1015. http-after-response set-header Access-Control-Allow-Headers &quot;Origin, X-Requested-With, Content-Type, Accept, Authorization&quot;
  1016. http-request return status 200 content-type application/json string '{&quot;m.homeserver&quot;:{&quot;base_url&quot;:&quot;https://matrix.example.com&quot;},&quot;m.identity_server&quot;:{&quot;base_url&quot;:&quot;https://identity.example.com&quot;}}'
  1017. backend matrix-well-known-server
  1018. http-after-response set-header Access-Control-Allow-Origin &quot;*&quot;
  1019. http-after-response set-header Access-Control-Allow-Methods &quot;GET, POST, PUT, DELETE, OPTIONS&quot;
  1020. http-after-response set-header Access-Control-Allow-Headers &quot;Origin, X-Requested-With, Content-Type, Accept, Authorization&quot;
  1021. http-request return status 200 content-type application/json string '{&quot;m.server&quot;:&quot;matrix.example.com:443&quot;}'
  1022. </code></pre>
  1023. <h3 id="relayd"><a class="header" href="#relayd">Relayd</a></h3>
  1024. <pre><code>table &lt;webserver&gt; { 127.0.0.1 }
  1025. table &lt;matrixserver&gt; { 127.0.0.1 }
  1026. http protocol &quot;https&quot; {
  1027. tls { no tlsv1.0, ciphers &quot;HIGH&quot; }
  1028. tls keypair &quot;example.com&quot;
  1029. match header set &quot;X-Forwarded-For&quot; value &quot;$REMOTE_ADDR&quot;
  1030. match header set &quot;X-Forwarded-Proto&quot; value &quot;https&quot;
  1031. # set CORS header for .well-known/matrix/server, .well-known/matrix/client
  1032. # httpd does not support setting headers, so do it here
  1033. match request path &quot;/.well-known/matrix/*&quot; tag &quot;matrix-cors&quot;
  1034. match response tagged &quot;matrix-cors&quot; header set &quot;Access-Control-Allow-Origin&quot; value &quot;*&quot;
  1035. pass quick path &quot;/_matrix/*&quot; forward to &lt;matrixserver&gt;
  1036. pass quick path &quot;/_synapse/client/*&quot; forward to &lt;matrixserver&gt;
  1037. # pass on non-matrix traffic to webserver
  1038. pass forward to &lt;webserver&gt;
  1039. }
  1040. relay &quot;https_traffic&quot; {
  1041. listen on egress port 443 tls
  1042. protocol &quot;https&quot;
  1043. forward to &lt;matrixserver&gt; port 8008 check tcp
  1044. forward to &lt;webserver&gt; port 8080 check tcp
  1045. }
  1046. http protocol &quot;matrix&quot; {
  1047. tls { no tlsv1.0, ciphers &quot;HIGH&quot; }
  1048. tls keypair &quot;example.com&quot;
  1049. block
  1050. pass quick path &quot;/_matrix/*&quot; forward to &lt;matrixserver&gt;
  1051. pass quick path &quot;/_synapse/client/*&quot; forward to &lt;matrixserver&gt;
  1052. }
  1053. relay &quot;matrix_federation&quot; {
  1054. listen on egress port 8448 tls
  1055. protocol &quot;matrix&quot;
  1056. forward to &lt;matrixserver&gt; port 8008 check tcp
  1057. }
  1058. </code></pre>
  1059. <h2 id="health-check-endpoint"><a class="header" href="#health-check-endpoint">Health check endpoint</a></h2>
  1060. <p>Synapse exposes a health check endpoint for use by reverse proxies.
  1061. Each configured HTTP listener has a <code>/health</code> endpoint which always returns
  1062. 200 OK (and doesn't get logged).</p>
  1063. <h2 id="synapse-administration-endpoints"><a class="header" href="#synapse-administration-endpoints">Synapse administration endpoints</a></h2>
  1064. <p>Endpoints for administering your Synapse instance are placed under
  1065. <code>/_synapse/admin</code>. These require authentication through an access token of an
  1066. admin user. However as access to these endpoints grants the caller a lot of power,
  1067. we do not recommend exposing them to the public internet without good reason.</p>
  1068. <div style="break-before: page; page-break-before: always;"></div><h1 id="using-a-forward-proxy-with-synapse"><a class="header" href="#using-a-forward-proxy-with-synapse">Using a forward proxy with Synapse</a></h1>
  1069. <p>You can use Synapse with a forward or outbound proxy. An example of when
  1070. this is necessary is in corporate environments behind a DMZ (demilitarized zone).
  1071. Synapse supports routing outbound HTTP(S) requests via a proxy. Only HTTP(S)
  1072. proxy is supported, not SOCKS proxy or anything else.</p>
  1073. <h2 id="configure"><a class="header" href="#configure">Configure</a></h2>
  1074. <p>The <code>http_proxy</code>, <code>https_proxy</code>, <code>no_proxy</code> environment variables are used to
  1075. specify proxy settings. The environment variable is not case sensitive.</p>
  1076. <ul>
  1077. <li><code>http_proxy</code>: Proxy server to use for HTTP requests.</li>
  1078. <li><code>https_proxy</code>: Proxy server to use for HTTPS requests.</li>
  1079. <li><code>no_proxy</code>: Comma-separated list of hosts, IP addresses, or IP ranges in CIDR
  1080. format which should not use the proxy. Synapse will directly connect to these hosts.</li>
  1081. </ul>
  1082. <p>The <code>http_proxy</code> and <code>https_proxy</code> environment variables have the form: <code>[scheme://][&lt;username&gt;:&lt;password&gt;@]&lt;host&gt;[:&lt;port&gt;]</code></p>
  1083. <ul>
  1084. <li>
  1085. <p>Supported schemes are <code>http://</code> and <code>https://</code>. The default scheme is <code>http://</code>
  1086. for compatibility reasons; it is recommended to set a scheme. If scheme is set
  1087. to <code>https://</code> the connection uses TLS between Synapse and the proxy.</p>
  1088. <p><strong>NOTE</strong>: Synapse validates the certificates. If the certificate is not
  1089. valid, then the connection is dropped.</p>
  1090. </li>
  1091. <li>
  1092. <p>Default port if not given is <code>1080</code>.</p>
  1093. </li>
  1094. <li>
  1095. <p>Username and password are optional and will be used to authenticate against
  1096. the proxy.</p>
  1097. </li>
  1098. </ul>
  1099. <p><strong>Examples</strong></p>
  1100. <ul>
  1101. <li>HTTP_PROXY=http://USERNAME:PASSWORD@10.0.1.1:8080/</li>
  1102. <li>HTTPS_PROXY=http://USERNAME:PASSWORD@proxy.example.com:8080/</li>
  1103. <li>NO_PROXY=master.hostname.example.com,10.1.0.0/16,172.30.0.0/16</li>
  1104. </ul>
  1105. <p><strong>NOTE</strong>:
  1106. Synapse does not apply the IP blacklist to connections through the proxy (since
  1107. the DNS resolution is done by the proxy). It is expected that the proxy or firewall
  1108. will apply blacklisting of IP addresses.</p>
  1109. <h2 id="connection-types"><a class="header" href="#connection-types">Connection types</a></h2>
  1110. <p>The proxy will be <strong>used</strong> for:</p>
  1111. <ul>
  1112. <li>push</li>
  1113. <li>url previews</li>
  1114. <li>phone-home stats</li>
  1115. <li>recaptcha validation</li>
  1116. <li>CAS auth validation</li>
  1117. <li>OpenID Connect</li>
  1118. <li>Outbound federation</li>
  1119. <li>Federation (checking public key revocation)</li>
  1120. <li>Fetching public keys of other servers</li>
  1121. <li>Downloading remote media</li>
  1122. </ul>
  1123. <p>It will <strong>not be used</strong> for:</p>
  1124. <ul>
  1125. <li>Application Services</li>
  1126. <li>Identity servers</li>
  1127. <li>In worker configurations
  1128. <ul>
  1129. <li>connections between workers</li>
  1130. <li>connections from workers to Redis</li>
  1131. </ul>
  1132. </li>
  1133. </ul>
  1134. <h2 id="troubleshooting-1"><a class="header" href="#troubleshooting-1">Troubleshooting</a></h2>
  1135. <p>If a proxy server is used with TLS (HTTPS) and no connections are established,
  1136. it is most likely due to the proxy's certificates. To test this, the validation
  1137. in Synapse can be deactivated.</p>
  1138. <p><strong>NOTE</strong>: This has an impact on security and is for testing purposes only!</p>
  1139. <p>To deactivate the certificate validation, the following setting must be added to
  1140. your <a href="setup/../usage/configuration/homeserver_sample_config.html">homserver.yaml</a>.</p>
  1141. <pre><code class="language-yaml">use_insecure_ssl_client_just_for_testing_do_not_use: true
  1142. </code></pre>
  1143. <div style="break-before: page; page-break-before: always;"></div><h1 id="overview-1"><a class="header" href="#overview-1">Overview</a></h1>
  1144. <p>This document explains how to enable VoIP relaying on your homeserver with
  1145. TURN.</p>
  1146. <p>The synapse Matrix homeserver supports integration with TURN server via the
  1147. <a href="https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00">TURN server REST API</a>. This
  1148. allows the homeserver to generate credentials that are valid for use on the
  1149. TURN server through the use of a secret shared between the homeserver and the
  1150. TURN server.</p>
  1151. <p>This documentation provides two TURN server configuration examples:</p>
  1152. <ul>
  1153. <li><a href="setup/turn/coturn.html">coturn</a></li>
  1154. <li><a href="setup/turn/eturnal.html">eturnal</a></li>
  1155. </ul>
  1156. <h2 id="requirements"><a class="header" href="#requirements">Requirements</a></h2>
  1157. <p>For TURN relaying to work, the TURN service must be hosted on a server/endpoint with a public IP.</p>
  1158. <p>Hosting TURN behind NAT requires port forwarding and for the NAT gateway to have a public IP.
  1159. However, even with appropriate configuration, NAT is known to cause issues and to often not work.</p>
  1160. <p>Afterwards, the homeserver needs some further configuration.</p>
  1161. <h2 id="synapse-setup"><a class="header" href="#synapse-setup">Synapse setup</a></h2>
  1162. <p>Your homeserver configuration file needs the following extra keys:</p>
  1163. <ol>
  1164. <li><a href="usage/configuration/config_documentation.html#turn_uris"><code>turn_uris</code></a></li>
  1165. <li><a href="usage/configuration/config_documentation.html#turn_shared_secret"><code>turn_shared_secret</code></a></li>
  1166. <li><a href="usage/configuration/config_documentation.html#turn_user_lifetime"><code>turn_user_lifetime</code></a></li>
  1167. <li><a href="usage/configuration/config_documentation.html#turn_allow_guests"><code>turn_allow_guests</code></a></li>
  1168. </ol>
  1169. <p>As an example, here is the relevant section of the config file for <code>matrix.org</code>. The
  1170. <code>turn_uris</code> are appropriate for TURN servers listening on the default ports, with no TLS.</p>
  1171. <pre><code>turn_uris: [ &quot;turn:turn.matrix.org?transport=udp&quot;, &quot;turn:turn.matrix.org?transport=tcp&quot; ]
  1172. turn_shared_secret: &quot;n0t4ctuAllymatr1Xd0TorgSshar3d5ecret4obvIousreAsons&quot;
  1173. turn_user_lifetime: 86400000
  1174. turn_allow_guests: true
  1175. </code></pre>
  1176. <p>After updating the homeserver configuration, you must restart synapse:</p>
  1177. <ul>
  1178. <li>If you use synctl:
  1179. <pre><code class="language-sh"># Depending on how Synapse is installed, synctl may already be on
  1180. # your PATH. If not, you may need to activate a virtual environment.
  1181. synctl restart
  1182. </code></pre>
  1183. </li>
  1184. <li>If you use systemd:
  1185. <pre><code class="language-sh">systemctl restart matrix-synapse.service
  1186. </code></pre>
  1187. </li>
  1188. </ul>
  1189. <p>... and then reload any clients (or wait an hour for them to refresh their
  1190. settings).</p>
  1191. <h2 id="troubleshooting-2"><a class="header" href="#troubleshooting-2">Troubleshooting</a></h2>
  1192. <p>The normal symptoms of a misconfigured TURN server are that calls between
  1193. devices on different networks ring, but get stuck at &quot;call
  1194. connecting&quot;. Unfortunately, troubleshooting this can be tricky.</p>
  1195. <p>Here are a few things to try:</p>
  1196. <ul>
  1197. <li>
  1198. <p>Check that you have opened your firewall to allow TCP and UDP traffic to the
  1199. TURN ports (normally 3478 and 5349).</p>
  1200. </li>
  1201. <li>
  1202. <p>Check that you have opened your firewall to allow UDP traffic to the UDP
  1203. relay ports (49152-65535 by default).</p>
  1204. </li>
  1205. <li>
  1206. <p>Try disabling TLS/DTLS listeners and enable only its (unencrypted)
  1207. TCP/UDP listeners. (This will only leave signaling traffic unencrypted;
  1208. voice &amp; video WebRTC traffic is always encrypted.)</p>
  1209. </li>
  1210. <li>
  1211. <p>Some WebRTC implementations (notably, that of Google Chrome) appear to get
  1212. confused by TURN servers which are reachable over IPv6 (this appears to be
  1213. an unexpected side-effect of its handling of multiple IP addresses as
  1214. defined by
  1215. <a href="https://tools.ietf.org/html/draft-ietf-rtcweb-ip-handling-12"><code>draft-ietf-rtcweb-ip-handling</code></a>).</p>
  1216. <p>Try removing any AAAA records for your TURN server, so that it is only
  1217. reachable over IPv4.</p>
  1218. </li>
  1219. <li>
  1220. <p>If your TURN server is behind NAT:</p>
  1221. <ul>
  1222. <li>
  1223. <p>double-check that your NAT gateway is correctly forwarding all TURN
  1224. ports (normally 3478 &amp; 5349 for TCP &amp; UDP TURN traffic, and 49152-65535 for the UDP
  1225. relay) to the NAT-internal address of your TURN server. If advertising
  1226. both IPv4 and IPv6 external addresses via the <code>external-ip</code> option, ensure
  1227. that the NAT is forwarding both IPv4 and IPv6 traffic to the IPv4 and IPv6
  1228. internal addresses of your TURN server. When in doubt, remove AAAA records
  1229. for your TURN server and specify only an IPv4 address as your <code>external-ip</code>.</p>
  1230. </li>
  1231. <li>
  1232. <p>ensure that your TURN server uses the NAT gateway as its default route.</p>
  1233. </li>
  1234. </ul>
  1235. </li>
  1236. <li>
  1237. <p>Enable more verbose logging, in <code>coturn</code> via the <code>verbose</code> setting:</p>
  1238. <pre><code>verbose
  1239. </code></pre>
  1240. <p>or with <code>eturnal</code> with the shell command <code>eturnalctl loglevel debug</code> or in the configuration file (the service needs to <a href="https://eturnal.net/documentation/#Operation">reload</a> for it to become effective):</p>
  1241. <pre><code class="language-yaml"> ## Logging configuration:
  1242. log_level: debug
  1243. </code></pre>
  1244. <p>... and then see if there are any clues in its logs.</p>
  1245. </li>
  1246. <li>
  1247. <p>If you are using a browser-based client under Chrome, check
  1248. <code>chrome://webrtc-internals/</code> for insights into the internals of the
  1249. negotiation. On Firefox, check the &quot;Connection Log&quot; on <code>about:webrtc</code>.</p>
  1250. <p>(Understanding the output is beyond the scope of this document!)</p>
  1251. </li>
  1252. <li>
  1253. <p>You can test your Matrix homeserver TURN setup with <a href="https://test.voip.librepush.net/">https://test.voip.librepush.net/</a>.
  1254. Note that this test is not fully reliable yet, so don't be discouraged if
  1255. the test fails.
  1256. <a href="https://github.com/matrix-org/voip-tester">Here</a> is the github repo of the
  1257. source of the tester, where you can file bug reports.</p>
  1258. </li>
  1259. <li>
  1260. <p>There is a WebRTC test tool at
  1261. <a href="https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/">https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/</a>. To
  1262. use it, you will need a username/password for your TURN server. You can
  1263. either:</p>
  1264. <ul>
  1265. <li>
  1266. <p>look for the <code>GET /_matrix/client/r0/voip/turnServer</code> request made by a
  1267. matrix client to your homeserver in your browser's network inspector. In
  1268. the response you should see <code>username</code> and <code>password</code>. Or:</p>
  1269. </li>
  1270. <li>
  1271. <p>Use the following shell commands for <code>coturn</code>:</p>
  1272. <pre><code class="language-sh">secret=staticAuthSecretHere
  1273. u=$((`date +%s` + 3600)):test
  1274. p=$(echo -n $u | openssl dgst -hmac $secret -sha1 -binary | base64)
  1275. echo -e &quot;username: $u\npassword: $p&quot;
  1276. </code></pre>
  1277. <p>or for <code>eturnal</code></p>
  1278. <pre><code class="language-sh">eturnalctl credentials
  1279. </code></pre>
  1280. </li>
  1281. <li>
  1282. <p>Or (<strong>coturn only</strong>): Temporarily configure <code>coturn</code> to accept a static
  1283. username/password. To do this, comment out <code>use-auth-secret</code> and
  1284. <code>static-auth-secret</code> and add the following:</p>
  1285. <pre><code>lt-cred-mech
  1286. user=username:password
  1287. </code></pre>
  1288. <p><strong>Note</strong>: these settings will not take effect unless <code>use-auth-secret</code>
  1289. and <code>static-auth-secret</code> are disabled.</p>
  1290. <p>Restart coturn after changing the configuration file.</p>
  1291. <p>Remember to restore the original settings to go back to testing with
  1292. Matrix clients!</p>
  1293. </li>
  1294. </ul>
  1295. <p>If the TURN server is working correctly, you should see at least one <code>relay</code>
  1296. entry in the results.</p>
  1297. </li>
  1298. </ul>
  1299. <div style="break-before: page; page-break-before: always;"></div><h1 id="coturn-turn-server"><a class="header" href="#coturn-turn-server">coturn TURN server</a></h1>
  1300. <p>The following sections describe how to install <a href="https://github.com/coturn/coturn">coturn</a> (which implements the TURN REST API).</p>
  1301. <h2 id="coturn-setup"><a class="header" href="#coturn-setup"><code>coturn</code> setup</a></h2>
  1302. <h3 id="initial-installation"><a class="header" href="#initial-installation">Initial installation</a></h3>
  1303. <p>The TURN daemon <code>coturn</code> is available from a variety of sources such as native package managers, or installation from source.</p>
  1304. <h4 id="debian-and-ubuntu-based-distributions"><a class="header" href="#debian-and-ubuntu-based-distributions">Debian and Ubuntu based distributions</a></h4>
  1305. <p>Just install the debian package:</p>
  1306. <pre><code class="language-sh">sudo apt install coturn
  1307. </code></pre>
  1308. <p>This will install and start a systemd service called <code>coturn</code>.</p>
  1309. <h4 id="source-installation"><a class="header" href="#source-installation">Source installation</a></h4>
  1310. <ol>
  1311. <li>
  1312. <p>Download the <a href="https://github.com/coturn/coturn/releases/latest">latest release</a> from github. Unpack it and <code>cd</code> into the directory.</p>
  1313. </li>
  1314. <li>
  1315. <p>Configure it:</p>
  1316. <pre><code class="language-sh">./configure
  1317. </code></pre>
  1318. <p>You may need to install <code>libevent2</code>: if so, you should do so in
  1319. the way recommended by your operating system. You can ignore
  1320. warnings about lack of database support: a database is unnecessary
  1321. for this purpose.</p>
  1322. </li>
  1323. <li>
  1324. <p>Build and install it:</p>
  1325. <pre><code class="language-sh">make
  1326. sudo make install
  1327. </code></pre>
  1328. </li>
  1329. </ol>
  1330. <h3 id="configuration"><a class="header" href="#configuration">Configuration</a></h3>
  1331. <ol>
  1332. <li>
  1333. <p>Create or edit the config file in <code>/etc/turnserver.conf</code>. The relevant
  1334. lines, with example values, are:</p>
  1335. <pre><code>use-auth-secret
  1336. static-auth-secret=[your secret key here]
  1337. realm=turn.myserver.org
  1338. </code></pre>
  1339. <p>See <code>turnserver.conf</code> for explanations of the options. One way to generate
  1340. the <code>static-auth-secret</code> is with <code>pwgen</code>:</p>
  1341. <pre><code class="language-sh">pwgen -s 64 1
  1342. </code></pre>
  1343. <p>A <code>realm</code> must be specified, but its value is somewhat arbitrary. (It is
  1344. sent to clients as part of the authentication flow.) It is conventional to
  1345. set it to be your server name.</p>
  1346. </li>
  1347. <li>
  1348. <p>You will most likely want to configure <code>coturn</code> to write logs somewhere. The
  1349. easiest way is normally to send them to the syslog:</p>
  1350. <pre><code class="language-sh">syslog
  1351. </code></pre>
  1352. <p>(in which case, the logs will be available via <code>journalctl -u coturn</code> on a
  1353. systemd system). Alternatively, <code>coturn</code> can be configured to write to a
  1354. logfile - check the example config file supplied with <code>coturn</code>.</p>
  1355. </li>
  1356. <li>
  1357. <p>Consider your security settings. TURN lets users request a relay which will
  1358. connect to arbitrary IP addresses and ports. The following configuration is
  1359. suggested as a minimum starting point:</p>
  1360. <pre><code># VoIP traffic is all UDP. There is no reason to let users connect to arbitrary TCP endpoints via the relay.
  1361. no-tcp-relay
  1362. # don't let the relay ever try to connect to private IP address ranges within your network (if any)
  1363. # given the turn server is likely behind your firewall, remember to include any privileged public IPs too.
  1364. denied-peer-ip=10.0.0.0-10.255.255.255
  1365. denied-peer-ip=192.168.0.0-192.168.255.255
  1366. denied-peer-ip=172.16.0.0-172.31.255.255
  1367. # recommended additional local peers to block, to mitigate external access to internal services.
  1368. # https://www.rtcsec.com/article/slack-webrtc-turn-compromise-and-bug-bounty/#how-to-fix-an-open-turn-relay-to-address-this-vulnerability
  1369. no-multicast-peers
  1370. denied-peer-ip=0.0.0.0-0.255.255.255
  1371. denied-peer-ip=100.64.0.0-100.127.255.255
  1372. denied-peer-ip=127.0.0.0-127.255.255.255
  1373. denied-peer-ip=169.254.0.0-169.254.255.255
  1374. denied-peer-ip=192.0.0.0-192.0.0.255
  1375. denied-peer-ip=192.0.2.0-192.0.2.255
  1376. denied-peer-ip=192.88.99.0-192.88.99.255
  1377. denied-peer-ip=198.18.0.0-198.19.255.255
  1378. denied-peer-ip=198.51.100.0-198.51.100.255
  1379. denied-peer-ip=203.0.113.0-203.0.113.255
  1380. denied-peer-ip=240.0.0.0-255.255.255.255
  1381. # special case the turn server itself so that client-&gt;TURN-&gt;TURN-&gt;client flows work
  1382. # this should be one of the turn server's listening IPs
  1383. allowed-peer-ip=10.0.0.1
  1384. # consider whether you want to limit the quota of relayed streams per user (or total) to avoid risk of DoS.
  1385. user-quota=12 # 4 streams per video call, so 12 streams = 3 simultaneous relayed calls per user.
  1386. total-quota=1200
  1387. </code></pre>
  1388. </li>
  1389. <li>
  1390. <p>Also consider supporting TLS/DTLS. To do this, add the following settings
  1391. to <code>turnserver.conf</code>:</p>
  1392. <pre><code># TLS certificates, including intermediate certs.
  1393. # For Let's Encrypt certificates, use `fullchain.pem` here.
  1394. cert=/path/to/fullchain.pem
  1395. # TLS private key file
  1396. pkey=/path/to/privkey.pem
  1397. # Ensure the configuration lines that disable TLS/DTLS are commented-out or removed
  1398. #no-tls
  1399. #no-dtls
  1400. </code></pre>
  1401. <p>In this case, replace the <code>turn:</code> schemes in the <code>turn_uris</code> settings below
  1402. with <code>turns:</code>.</p>
  1403. <p>We recommend that you only try to set up TLS/DTLS once you have set up a
  1404. basic installation and got it working.</p>
  1405. <p>NB: If your TLS certificate was provided by Let's Encrypt, TLS/DTLS will
  1406. not work with any Matrix client that uses Chromium's WebRTC library. This
  1407. currently includes Element Android &amp; iOS; for more details, see their
  1408. <a href="https://github.com/vector-im/element-android/issues/1533">respective</a>
  1409. <a href="https://github.com/vector-im/element-ios/issues/2712">issues</a> as well as the underlying
  1410. <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=11710">WebRTC issue</a>.
  1411. Consider using a ZeroSSL certificate for your TURN server as a working alternative.</p>
  1412. </li>
  1413. <li>
  1414. <p>Ensure your firewall allows traffic into the TURN server on the ports
  1415. you've configured it to listen on (By default: 3478 and 5349 for TURN
  1416. traffic (remember to allow both TCP and UDP traffic), and ports 49152-65535
  1417. for the UDP relay.)</p>
  1418. </li>
  1419. <li>
  1420. <p>If your TURN server is behind NAT, the NAT gateway must have an external,
  1421. publicly-reachable IP address. You must configure <code>coturn</code> to advertise that
  1422. address to connecting clients:</p>
  1423. <pre><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS
  1424. </code></pre>
  1425. <p>You may optionally limit the TURN server to listen only on the local
  1426. address that is mapped by NAT to the external address:</p>
  1427. <pre><code>listening-ip=INTERNAL_TURNSERVER_IPv4_ADDRESS
  1428. </code></pre>
  1429. <p>If your NAT gateway is reachable over both IPv4 and IPv6, you may
  1430. configure <code>coturn</code> to advertise each available address:</p>
  1431. <pre><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS
  1432. external-ip=EXTERNAL_NAT_IPv6_ADDRESS
  1433. </code></pre>
  1434. <p>When advertising an external IPv6 address, ensure that the firewall and
  1435. network settings of the system running your TURN server are configured to
  1436. accept IPv6 traffic, and that the TURN server is listening on the local
  1437. IPv6 address that is mapped by NAT to the external IPv6 address.</p>
  1438. </li>
  1439. <li>
  1440. <p>(Re)start the turn server:</p>
  1441. <ul>
  1442. <li>
  1443. <p>If you used the Debian package (or have set up a systemd unit yourself):</p>
  1444. <pre><code class="language-sh">sudo systemctl restart coturn
  1445. </code></pre>
  1446. </li>
  1447. <li>
  1448. <p>If you built from source:</p>
  1449. <pre><code class="language-sh">/usr/local/bin/turnserver -o
  1450. </code></pre>
  1451. </li>
  1452. </ul>
  1453. </li>
  1454. </ol>
  1455. <div style="break-before: page; page-break-before: always;"></div><h1 id="eturnal-turn-server"><a class="header" href="#eturnal-turn-server">eturnal TURN server</a></h1>
  1456. <p>The following sections describe how to install <a href="https://github.com/processone/eturnal">eturnal</a>
  1457. (which implements the TURN REST API).</p>
  1458. <h2 id="eturnal-setup"><a class="header" href="#eturnal-setup"><code>eturnal</code> setup</a></h2>
  1459. <h3 id="initial-installation-1"><a class="header" href="#initial-installation-1">Initial installation</a></h3>
  1460. <p>The <code>eturnal</code> TURN server implementation is available from a variety of sources
  1461. such as native package managers, binary packages, installation from source or
  1462. <a href="https://eturnal.net/documentation/code/docker.html">container image</a>. They are
  1463. all described <a href="https://github.com/processone/eturnal#installation">here</a>.</p>
  1464. <p>Quick-Test instructions in a <a href="https://github.com/processone/eturnal/blob/master/QUICK-TEST.md">Linux Shell</a>
  1465. or with <a href="https://github.com/processone/eturnal/blob/master/docker-k8s/QUICK-TEST.md">Docker</a>
  1466. are available as well.</p>
  1467. <h3 id="configuration-1"><a class="header" href="#configuration-1">Configuration</a></h3>
  1468. <p>After installation, <code>eturnal</code> usually ships a <a href="https://github.com/processone/eturnal/blob/master/config/eturnal.yml">default configuration file</a>
  1469. here: <code>/etc/eturnal.yml</code> (and, if not found there, there is a backup file here:
  1470. <code>/opt/eturnal/etc/eturnal.yml</code>). It uses the (indentation-sensitive!) <a href="https://en.wikipedia.org/wiki/YAML">YAML</a>
  1471. format. The file contains further explanations.</p>
  1472. <p>Here are some hints how to configure eturnal on your <a href="https://github.com/processone/eturnal#configuration">host machine</a>
  1473. or when using e.g. <a href="https://eturnal.net/documentation/code/docker.html">Docker</a>.
  1474. You may also further deep dive into the <a href="https://eturnal.net/documentation/">reference documentation</a>.</p>
  1475. <p><code>eturnal</code> runs out of the box with the default configuration. To enable TURN and
  1476. to integrate it with your homeserver, some aspects in <code>eturnal</code>'s default configuration file
  1477. must be edited:</p>
  1478. <ol>
  1479. <li>
  1480. <p>Homeserver's <a href="setup/turn/../../usage/configuration/config_documentation.html#turn_shared_secret"><code>turn_shared_secret</code></a>
  1481. and eturnal's shared <code>secret</code> for authentication</p>
  1482. <p>Both need to have the same value. Uncomment and adjust this line in <code>eturnal</code>'s
  1483. configuration file:</p>
  1484. <pre><code class="language-yaml">secret: &quot;long-and-cryptic&quot; # Shared secret, CHANGE THIS.
  1485. </code></pre>
  1486. <p>One way to generate a <code>secret</code> is with <code>pwgen</code>:</p>
  1487. <pre><code class="language-sh">pwgen -s 64 1
  1488. </code></pre>
  1489. </li>
  1490. <li>
  1491. <p>Public IP address</p>
  1492. <p>If your TURN server is behind NAT, the NAT gateway must have an external,
  1493. publicly-reachable IP address. <code>eturnal</code> tries to autodetect the public IP address,
  1494. however, it may also be configured by uncommenting and adjusting this line, so
  1495. <code>eturnal</code> advertises that address to connecting clients:</p>
  1496. <pre><code class="language-yaml">relay_ipv4_addr: &quot;203.0.113.4&quot; # The server's public IPv4 address.
  1497. </code></pre>
  1498. <p>If your NAT gateway is reachable over both IPv4 and IPv6, you may
  1499. configure <code>eturnal</code> to advertise each available address:</p>
  1500. <pre><code class="language-yaml">relay_ipv4_addr: &quot;203.0.113.4&quot; # The server's public IPv4 address.
  1501. relay_ipv6_addr: &quot;2001:db8::4&quot; # The server's public IPv6 address (optional).
  1502. </code></pre>
  1503. <p>When advertising an external IPv6 address, ensure that the firewall and
  1504. network settings of the system running your TURN server are configured to
  1505. accept IPv6 traffic, and that the TURN server is listening on the local
  1506. IPv6 address that is mapped by NAT to the external IPv6 address.</p>
  1507. </li>
  1508. <li>
  1509. <p>Logging</p>
  1510. <p>If <code>eturnal</code> was started by systemd, log files are written into the
  1511. <code>/var/log/eturnal</code> directory by default. In order to log to the <a href="https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html">journal</a>
  1512. instead, the <code>log_dir</code> option can be set to <code>stdout</code> in the configuration file.</p>
  1513. </li>
  1514. <li>
  1515. <p>Security considerations</p>
  1516. <p>Consider your security settings. TURN lets users request a relay which will
  1517. connect to arbitrary IP addresses and ports. The following configuration is
  1518. suggested as a minimum starting point, <a href="https://eturnal.net/documentation/#blacklist">see also the official documentation</a>:</p>
  1519. <pre><code class="language-yaml">## Reject TURN relaying from/to the following addresses/networks:
  1520. blacklist: # This is the default blacklist.
  1521. - &quot;127.0.0.0/8&quot; # IPv4 loopback.
  1522. - &quot;::1&quot; # IPv6 loopback.
  1523. - recommended # Expands to a number of networks recommended to be
  1524. # blocked, but includes private networks. Those
  1525. # would have to be 'whitelist'ed if eturnal serves
  1526. # local clients/peers within such networks.
  1527. </code></pre>
  1528. <p>To whitelist IP addresses or specific (private) networks, you need to <strong>add</strong> a
  1529. whitelist part into the configuration file, e.g.:</p>
  1530. <pre><code class="language-yaml">whitelist:
  1531. - &quot;192.168.0.0/16&quot;
  1532. - &quot;203.0.113.113&quot;
  1533. - &quot;2001:db8::/64&quot;
  1534. </code></pre>
  1535. <p>The more specific, the better.</p>
  1536. </li>
  1537. <li>
  1538. <p>TURNS (TURN via TLS/DTLS)</p>
  1539. <p>Also consider supporting TLS/DTLS. To do this, adjust the following settings
  1540. in the <code>eturnal.yml</code> configuration file (TLS parts should not be commented anymore):</p>
  1541. <pre><code class="language-yaml">listen:
  1542. - ip: &quot;::&quot;
  1543. port: 3478
  1544. transport: udp
  1545. - ip: &quot;::&quot;
  1546. port: 3478
  1547. transport: tcp
  1548. - ip: &quot;::&quot;
  1549. port: 5349
  1550. transport: tls
  1551. ## TLS certificate/key files (must be readable by 'eturnal' user!):
  1552. tls_crt_file: /etc/eturnal/tls/crt.pem
  1553. tls_key_file: /etc/eturnal/tls/key.pem
  1554. </code></pre>
  1555. <p>In this case, replace the <code>turn:</code> schemes in homeserver's <code>turn_uris</code> settings
  1556. with <code>turns:</code>. More is described <a href="setup/turn/../../usage/configuration/config_documentation.html#turn_uris">here</a>.</p>
  1557. <p>We recommend that you only try to set up TLS/DTLS once you have set up a
  1558. basic installation and got it working.</p>
  1559. <p>NB: If your TLS certificate was provided by Let's Encrypt, TLS/DTLS will
  1560. not work with any Matrix client that uses Chromium's WebRTC library. This
  1561. currently includes Element Android &amp; iOS; for more details, see their
  1562. <a href="https://github.com/vector-im/element-android/issues/1533">respective</a>
  1563. <a href="https://github.com/vector-im/element-ios/issues/2712">issues</a> as well as the underlying
  1564. <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=11710">WebRTC issue</a>.
  1565. Consider using a ZeroSSL certificate for your TURN server as a working alternative.</p>
  1566. </li>
  1567. <li>
  1568. <p>Firewall</p>
  1569. <p>Ensure your firewall allows traffic into the TURN server on the ports
  1570. you've configured it to listen on (By default: 3478 and 5349 for TURN
  1571. traffic (remember to allow both TCP and UDP traffic), and ports 49152-65535
  1572. for the UDP relay.)</p>
  1573. </li>
  1574. <li>
  1575. <p>Reload/ restarting <code>eturnal</code></p>
  1576. <p>Changes in the configuration file require <code>eturnal</code> to reload/ restart, this
  1577. can be achieved by:</p>
  1578. <pre><code class="language-sh">eturnalctl reload
  1579. </code></pre>
  1580. <p><code>eturnal</code> performs a configuration check before actually reloading/ restarting
  1581. and provides hints, if something is not correctly configured.</p>
  1582. </li>
  1583. </ol>
  1584. <h3 id="eturnalctl-opterations-script"><a class="header" href="#eturnalctl-opterations-script">eturnalctl opterations script</a></h3>
  1585. <p><code>eturnal</code> offers a handy <a href="https://eturnal.net/documentation/#Operation">operations script</a>
  1586. which can be called e.g. to check, whether the service is up, to restart the service,
  1587. to query how many active sessions exist, to change logging behaviour and so on.</p>
  1588. <p>Hint: If <code>eturnalctl</code> is not part of your <code>$PATH</code>, consider either sym-linking it (e.g. ´ln -s /opt/eturnal/bin/eturnalctl /usr/local/bin/eturnalctl´) or call it from the default <code>eturnal</code> directory directly: e.g. <code>/opt/eturnal/bin/eturnalctl info</code></p>
  1589. <div style="break-before: page; page-break-before: always;"></div><h1 id="delegation-of-incoming-federation-traffic"><a class="header" href="#delegation-of-incoming-federation-traffic">Delegation of incoming federation traffic</a></h1>
  1590. <p>In the following documentation, we use the term <code>server_name</code> to refer to that setting
  1591. in your homeserver configuration file. It appears at the ends of user ids, and tells
  1592. other homeservers where they can find your server.</p>
  1593. <p>By default, other homeservers will expect to be able to reach yours via
  1594. your <code>server_name</code>, on port 8448. For example, if you set your <code>server_name</code>
  1595. to <code>example.com</code> (so that your user names look like <code>@user:example.com</code>),
  1596. other servers will try to connect to yours at <code>https://example.com:8448/</code>.</p>
  1597. <p>Delegation is a Matrix feature allowing a homeserver admin to retain a
  1598. <code>server_name</code> of <code>example.com</code> so that user IDs, room aliases, etc continue
  1599. to look like <code>*:example.com</code>, whilst having federation traffic routed
  1600. to a different server and/or port (e.g. <code>synapse.example.com:443</code>).</p>
  1601. <h2 id="well-known-delegation"><a class="header" href="#well-known-delegation">.well-known delegation</a></h2>
  1602. <p>To use this method, you need to be able to configure the server at
  1603. <code>https://&lt;server_name&gt;</code> to serve a file at
  1604. <code>https://&lt;server_name&gt;/.well-known/matrix/server</code>. There are two ways to do this, shown below.</p>
  1605. <p>Note that the <code>.well-known</code> file is hosted on the default port for <code>https</code> (port 443).</p>
  1606. <h3 id="external-server"><a class="header" href="#external-server">External server</a></h3>
  1607. <p>For maximum flexibility, you need to configure an external server such as nginx, Apache
  1608. or HAProxy to serve the <code>https://&lt;server_name&gt;/.well-known/matrix/server</code> file. Setting
  1609. up such a server is out of the scope of this documentation, but note that it is often
  1610. possible to configure your <a href="reverse_proxy.html">reverse proxy</a> for this.</p>
  1611. <p>The URL <code>https://&lt;server_name&gt;/.well-known/matrix/server</code> should be configured
  1612. return a JSON structure containing the key <code>m.server</code> like this:</p>
  1613. <pre><code class="language-json">{
  1614. &quot;m.server&quot;: &quot;&lt;synapse.server.name&gt;[:&lt;yourport&gt;]&quot;
  1615. }
  1616. </code></pre>
  1617. <p>In our example (where we want federation traffic to be routed to
  1618. <code>https://synapse.example.com</code>, on port 443), this would mean that
  1619. <code>https://example.com/.well-known/matrix/server</code> should return:</p>
  1620. <pre><code class="language-json">{
  1621. &quot;m.server&quot;: &quot;synapse.example.com:443&quot;
  1622. }
  1623. </code></pre>
  1624. <p>Note, specifying a port is optional. If no port is specified, then it defaults
  1625. to 8448.</p>
  1626. <h3 id="serving-a-well-knownmatrixserver-file-with-synapse"><a class="header" href="#serving-a-well-knownmatrixserver-file-with-synapse">Serving a <code>.well-known/matrix/server</code> file with Synapse</a></h3>
  1627. <p>If you are able to set up your domain so that <code>https://&lt;server_name&gt;</code> is routed to
  1628. Synapse (i.e., the only change needed is to direct federation traffic to port 443
  1629. instead of port 8448), then it is possible to configure Synapse to serve a suitable
  1630. <code>.well-known/matrix/server</code> file. To do so, add the following to your <code>homeserver.yaml</code>
  1631. file:</p>
  1632. <pre><code class="language-yaml">serve_server_wellknown: true
  1633. </code></pre>
  1634. <p><strong>Note</strong>: this <em>only</em> works if <code>https://&lt;server_name&gt;</code> is routed to Synapse, so is
  1635. generally not suitable if Synapse is hosted at a subdomain such as
  1636. <code>https://synapse.example.com</code>.</p>
  1637. <h2 id="srv-dns-record-delegation"><a class="header" href="#srv-dns-record-delegation">SRV DNS record delegation</a></h2>
  1638. <p>It is also possible to do delegation using a SRV DNS record. However, that is generally
  1639. not recommended, as it can be difficult to configure the TLS certificates correctly in
  1640. this case, and it offers little advantage over <code>.well-known</code> delegation.</p>
  1641. <p>Please keep in mind that server delegation is a function of server-server communication,
  1642. and as such using SRV DNS records will not cover use cases involving client-server comms.
  1643. This means setting global client settings (such as a Jitsi endpoint, or disabling
  1644. creating new rooms as encrypted by default, etc) will still require that you serve a file
  1645. from the <code>https://&lt;server_name&gt;/.well-known/</code> endpoints defined in the spec! If you are
  1646. considering using SRV DNS delegation to avoid serving files from this endpoint, consider
  1647. the impact that you will not be able to change those client-based default values globally,
  1648. and will be relegated to the featureset of the configuration of each individual client.</p>
  1649. <p>However, if you really need it, you can find some documentation on what such a
  1650. record should look like and how Synapse will use it in <a href="https://matrix.org/docs/spec/server_server/latest#resolving-server-names">the Matrix
  1651. specification</a>.</p>
  1652. <h2 id="delegation-faq"><a class="header" href="#delegation-faq">Delegation FAQ</a></h2>
  1653. <h3 id="when-do-i-need-delegation"><a class="header" href="#when-do-i-need-delegation">When do I need delegation?</a></h3>
  1654. <p>If your homeserver's APIs are accessible on the default federation port (8448)
  1655. and the domain your <code>server_name</code> points to, you do not need any delegation.</p>
  1656. <p>For instance, if you registered <code>example.com</code> and pointed its DNS A record at a
  1657. fresh server, you could install Synapse on that host, giving it a <code>server_name</code>
  1658. of <code>example.com</code>, and once a reverse proxy has been set up to proxy all requests
  1659. sent to the port <code>8448</code> and serve TLS certificates for <code>example.com</code>, you
  1660. wouldn't need any delegation set up.</p>
  1661. <p><strong>However</strong>, if your homeserver's APIs aren't accessible on port 8448 and on the
  1662. domain <code>server_name</code> points to, you will need to let other servers know how to
  1663. find it using delegation.</p>
  1664. <h3 id="should-i-use-a-reverse-proxy-for-federation-traffic"><a class="header" href="#should-i-use-a-reverse-proxy-for-federation-traffic">Should I use a reverse proxy for federation traffic?</a></h3>
  1665. <p>Generally, using a reverse proxy for both the federation and client traffic is a good
  1666. idea, since it saves handling TLS traffic in Synapse. See
  1667. <a href="reverse_proxy.html">the reverse proxy documentation</a> for information on setting up a
  1668. reverse proxy.</p>
  1669. <div style="break-before: page; page-break-before: always;"></div><h1 id="upgrading-synapse"><a class="header" href="#upgrading-synapse">Upgrading Synapse</a></h1>
  1670. <p>Before upgrading check if any special steps are required to upgrade from
  1671. the version you currently have installed to the current version of
  1672. Synapse. The extra instructions that may be required are listed later in
  1673. this document.</p>
  1674. <ul>
  1675. <li>
  1676. <p>Check that your versions of Python and PostgreSQL are still
  1677. supported.</p>
  1678. <p>Synapse follows upstream lifecycles for <a href="https://endoflife.date/python">Python</a> and
  1679. <a href="https://endoflife.date/postgresql">PostgreSQL</a>, and removes support for versions
  1680. which are no longer maintained.</p>
  1681. <p>The website <a href="https://endoflife.date">https://endoflife.date</a> also offers convenient
  1682. summaries.</p>
  1683. </li>
  1684. <li>
  1685. <p>If Synapse was installed using <a href="setup/installation.html#prebuilt-packages">prebuilt packages</a>,
  1686. you will need to follow the normal process for upgrading those packages.</p>
  1687. </li>
  1688. <li>
  1689. <p>If Synapse was installed using pip then upgrade to the latest
  1690. version by running:</p>
  1691. <pre><code class="language-bash">pip install --upgrade matrix-synapse
  1692. </code></pre>
  1693. </li>
  1694. <li>
  1695. <p>If Synapse was installed from source, then:</p>
  1696. <ol>
  1697. <li>
  1698. <p>Obtain the latest version of the source code. Git users can run
  1699. <code>git pull</code> to do this.</p>
  1700. </li>
  1701. <li>
  1702. <p>If you're running Synapse in a virtualenv, make sure to activate it before
  1703. upgrading. For example, if Synapse is installed in a virtualenv in <code>~/synapse/env</code> then
  1704. run:</p>
  1705. <pre><code class="language-bash">source ~/synapse/env/bin/activate
  1706. pip install --upgrade .
  1707. </code></pre>
  1708. <p>Include any relevant extras between square brackets, e.g. <code>pip install --upgrade &quot;.[postgres,oidc]&quot;</code>.</p>
  1709. </li>
  1710. <li>
  1711. <p>If you're using <code>poetry</code> to manage a Synapse installation, run:</p>
  1712. <pre><code class="language-bash">poetry install
  1713. </code></pre>
  1714. <p>Include any relevant extras with <code>--extras</code>, e.g. <code>poetry install --extras postgres --extras oidc</code>.
  1715. It's probably easiest to run <code>poetry install --extras all</code>.</p>
  1716. </li>
  1717. <li>
  1718. <p>Restart Synapse:</p>
  1719. <pre><code class="language-bash">synctl restart
  1720. </code></pre>
  1721. </li>
  1722. </ol>
  1723. </li>
  1724. </ul>
  1725. <p>To check whether your update was successful, you can check the running
  1726. server version with:</p>
  1727. <pre><code class="language-bash"># you may need to replace 'localhost:8008' if synapse is not configured
  1728. # to listen on port 8008.
  1729. curl http://localhost:8008/_synapse/admin/v1/server_version
  1730. </code></pre>
  1731. <h2 id="rolling-back-to-older-versions"><a class="header" href="#rolling-back-to-older-versions">Rolling back to older versions</a></h2>
  1732. <p>Rolling back to previous releases can be difficult, due to database
  1733. schema changes between releases. Where we have been able to test the
  1734. rollback process, this will be noted below.</p>
  1735. <p>In general, you will need to undo any changes made during the upgrade
  1736. process, for example:</p>
  1737. <ul>
  1738. <li>
  1739. <p>pip:</p>
  1740. <pre><code class="language-bash">source env/bin/activate
  1741. # replace `1.3.0` accordingly:
  1742. pip install matrix-synapse==1.3.0
  1743. </code></pre>
  1744. </li>
  1745. <li>
  1746. <p>Debian:</p>
  1747. <pre><code class="language-bash"># replace `1.3.0` and `stretch` accordingly:
  1748. wget https://packages.matrix.org/debian/pool/main/m/matrix-synapse-py3/matrix-synapse-py3_1.3.0+stretch1_amd64.deb
  1749. dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
  1750. </code></pre>
  1751. </li>
  1752. </ul>
  1753. <p>Generally Synapse database schemas are compatible across multiple versions, once
  1754. a version of Synapse is deployed you may not be able to rollback automatically.
  1755. The following table gives the version ranges and the earliest version they can
  1756. be rolled back to. E.g. Synapse versions v1.58.0 through v1.61.1 can be rolled
  1757. back safely to v1.57.0, but starting with v1.62.0 it is only safe to rollback to
  1758. v1.61.0.</p>
  1759. <table><thead><tr><th>Versions</th><th>Compatible version</th></tr></thead><tbody>
  1760. <tr><td>v1.0.0 – v1.2.1</td><td>v1.0.0</td></tr>
  1761. <tr><td>v1.3.0 – v1.8.0</td><td>v1.3.0</td></tr>
  1762. <tr><td>v1.9.0 – v1.12.4</td><td>v1.9.0</td></tr>
  1763. <tr><td>v1.13.0 – v1.25.0</td><td>v1.13.0</td></tr>
  1764. <tr><td>v1.26.0 – v1.44.0</td><td>v1.26.0</td></tr>
  1765. <tr><td>v1.45.0 – v1.47.1</td><td>v1.38.0</td></tr>
  1766. <tr><td>v1.48.0 – v1.51.0</td><td>v1.39.0</td></tr>
  1767. <tr><td>v1.52.0 – v1.57.1</td><td>v1.49.0</td></tr>
  1768. <tr><td>v1.58.0 – v1.61.1</td><td>v1.57.0</td></tr>
  1769. <tr><td>v1.62.0 – v1.63.1</td><td>v1.61.0</td></tr>
  1770. <tr><td>v1.64.0 – v1.69.0</td><td>v1.62.0</td></tr>
  1771. <tr><td>v1.70.0 – v1.82.0</td><td>v1.68.0</td></tr>
  1772. <tr><td>v1.83.0 – v1.84.1</td><td>v1.77.0</td></tr>
  1773. <tr><td>v1.85.0 – v1.91.2</td><td>v1.83.0</td></tr>
  1774. <tr><td>v1.92.0 – v1.97.0</td><td>v1.90.0</td></tr>
  1775. <tr><td>v1.98.0 – v1.98.0</td><td>v1.96.0</td></tr>
  1776. </tbody></table>
  1777. <h1 id="upgrading-to-v1930"><a class="header" href="#upgrading-to-v1930">Upgrading to v1.93.0</a></h1>
  1778. <h2 id="minimum-supported-rust-version"><a class="header" href="#minimum-supported-rust-version">Minimum supported Rust version</a></h2>
  1779. <p>The minimum supported Rust version has been increased from v1.60.0 to v1.61.0.
  1780. Users building from source will need to ensure their <code>rustc</code> version is up to
  1781. date.</p>
  1782. <h1 id="upgrading-to-v1900"><a class="header" href="#upgrading-to-v1900">Upgrading to v1.90.0</a></h1>
  1783. <h2 id="app-service-query-parameter-authorization-is-now-a-configuration-option"><a class="header" href="#app-service-query-parameter-authorization-is-now-a-configuration-option">App service query parameter authorization is now a configuration option</a></h2>
  1784. <p>Synapse v1.81.0 deprecated application service authorization via query parameters as this is
  1785. considered insecure - and from Synapse v1.71.0 forwards the application service token has also been sent via
  1786. <a href="https://spec.matrix.org/v1.6/application-service-api/#authorization">the <code>Authorization</code> header</a>], making the insecure
  1787. query parameter authorization redundant. Since removing the ability to continue to use query parameters could break
  1788. backwards compatibility it has now been put behind a configuration option, <code>use_appservice_legacy_authorization</code>.<br />
  1789. This option defaults to false, but can be activated by adding </p>
  1790. <pre><code class="language-yaml">use_appservice_legacy_authorization: true
  1791. </code></pre>
  1792. <p>to your configuration.</p>
  1793. <h1 id="upgrading-to-v1890"><a class="header" href="#upgrading-to-v1890">Upgrading to v1.89.0</a></h1>
  1794. <h2 id="removal-of-unspecced-user-property-for-register"><a class="header" href="#removal-of-unspecced-user-property-for-register">Removal of unspecced <code>user</code> property for <code>/register</code></a></h2>
  1795. <p>Application services can no longer call <code>/register</code> with a <code>user</code> property to create new users.
  1796. The standard <code>username</code> property should be used instead. See the
  1797. <a href="https://spec.matrix.org/v1.7/application-service-api/#server-admin-style-permissions">Application Service specification</a>
  1798. for more information.</p>
  1799. <h1 id="upgrading-to-v1880"><a class="header" href="#upgrading-to-v1880">Upgrading to v1.88.0</a></h1>
  1800. <h2 id="minimum-supported-python-version"><a class="header" href="#minimum-supported-python-version">Minimum supported Python version</a></h2>
  1801. <p>The minimum supported Python version has been increased from v3.7 to v3.8.
  1802. You will need Python 3.8 to run Synapse v1.88.0 (due out July 18th, 2023).</p>
  1803. <p>If you use current versions of the Matrix.org-distributed Debian
  1804. packages or Docker images, no action is required.</p>
  1805. <h2 id="removal-of-worker_replication_-settings"><a class="header" href="#removal-of-worker_replication_-settings">Removal of <code>worker_replication_*</code> settings</a></h2>
  1806. <p>As mentioned previously in <a href="upgrade.html#upgrading-to-v1840">Upgrading to v1.84.0</a>, the following deprecated settings
  1807. are being removed in this release of Synapse:</p>
  1808. <ul>
  1809. <li><a href="https://matrix-org.github.io/synapse/v1.86/usage/configuration/config_documentation.html#worker_replication_host"><code>worker_replication_host</code></a></li>
  1810. <li><a href="https://matrix-org.github.io/synapse/v1.86/usage/configuration/config_documentation.html#worker_replication_http_port"><code>worker_replication_http_port</code></a></li>
  1811. <li><a href="https://matrix-org.github.io/synapse/v1.86/usage/configuration/config_documentation.html#worker_replication_http_tls"><code>worker_replication_http_tls</code></a></li>
  1812. </ul>
  1813. <p>Please ensure that you have migrated to using <code>main</code> on your shared configuration's <code>instance_map</code>
  1814. (or create one if necessary). This is required if you have <em><strong>any</strong></em> workers at all;
  1815. administrators of single-process (monolith) installations don't need to do anything.</p>
  1816. <p>For an illustrative example, please see <a href="upgrade.html#upgrading-to-v1840">Upgrading to v1.84.0</a> below.</p>
  1817. <h1 id="upgrading-to-v1860"><a class="header" href="#upgrading-to-v1860">Upgrading to v1.86.0</a></h1>
  1818. <h2 id="minimum-supported-rust-version-1"><a class="header" href="#minimum-supported-rust-version-1">Minimum supported Rust version</a></h2>
  1819. <p>The minimum supported Rust version has been increased from v1.58.1 to v1.60.0.
  1820. Users building from source will need to ensure their <code>rustc</code> version is up to
  1821. date.</p>
  1822. <h1 id="upgrading-to-v1850"><a class="header" href="#upgrading-to-v1850">Upgrading to v1.85.0</a></h1>
  1823. <h2 id="application-service-registration-with-user-property-deprecation"><a class="header" href="#application-service-registration-with-user-property-deprecation">Application service registration with &quot;user&quot; property deprecation</a></h2>
  1824. <p>Application services should ensure they call the <code>/register</code> endpoint with a
  1825. <code>username</code> property. The legacy <code>user</code> property is considered deprecated and
  1826. should no longer be included.</p>
  1827. <p>A future version of Synapse (v1.88.0 or later) will remove support for legacy
  1828. application service login.</p>
  1829. <h1 id="upgrading-to-v1840"><a class="header" href="#upgrading-to-v1840">Upgrading to v1.84.0</a></h1>
  1830. <h2 id="deprecation-of-worker_replication_-configuration-settings"><a class="header" href="#deprecation-of-worker_replication_-configuration-settings">Deprecation of <code>worker_replication_*</code> configuration settings</a></h2>
  1831. <p>When using workers,</p>
  1832. <ul>
  1833. <li><code>worker_replication_host</code></li>
  1834. <li><code>worker_replication_http_port</code></li>
  1835. <li><code>worker_replication_http_tls</code></li>
  1836. </ul>
  1837. <p>should now be removed from individual worker YAML configurations and the main process should instead be added to the <code>instance_map</code>
  1838. in the shared YAML configuration, using the name <code>main</code>.</p>
  1839. <p>The old <code>worker_replication_*</code> settings are now considered deprecated and are expected to be removed in Synapse v1.88.0.</p>
  1840. <h3 id="example-change"><a class="header" href="#example-change">Example change</a></h3>
  1841. <h4 id="before"><a class="header" href="#before">Before:</a></h4>
  1842. <p>Shared YAML</p>
  1843. <pre><code class="language-yaml">instance_map:
  1844. generic_worker1:
  1845. host: localhost
  1846. port: 5678
  1847. tls: false
  1848. </code></pre>
  1849. <p>Worker YAML</p>
  1850. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  1851. worker_name: generic_worker1
  1852. worker_replication_host: localhost
  1853. worker_replication_http_port: 3456
  1854. worker_replication_http_tls: false
  1855. worker_listeners:
  1856. - type: http
  1857. port: 1234
  1858. resources:
  1859. - names: [client, federation]
  1860. - type: http
  1861. port: 5678
  1862. resources:
  1863. - names: [replication]
  1864. worker_log_config: /etc/matrix-synapse/generic-worker-log.yaml
  1865. </code></pre>
  1866. <h4 id="after"><a class="header" href="#after">After:</a></h4>
  1867. <p>Shared YAML</p>
  1868. <pre><code class="language-yaml">instance_map:
  1869. main:
  1870. host: localhost
  1871. port: 3456
  1872. tls: false
  1873. generic_worker1:
  1874. host: localhost
  1875. port: 5678
  1876. tls: false
  1877. </code></pre>
  1878. <p>Worker YAML</p>
  1879. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  1880. worker_name: generic_worker1
  1881. worker_listeners:
  1882. - type: http
  1883. port: 1234
  1884. resources:
  1885. - names: [client, federation]
  1886. - type: http
  1887. port: 5678
  1888. resources:
  1889. - names: [replication]
  1890. worker_log_config: /etc/matrix-synapse/generic-worker-log.yaml
  1891. </code></pre>
  1892. <p>Notes: </p>
  1893. <ul>
  1894. <li><code>tls</code> is optional but mirrors the functionality of <code>worker_replication_http_tls</code></li>
  1895. </ul>
  1896. <h1 id="upgrading-to-v1810"><a class="header" href="#upgrading-to-v1810">Upgrading to v1.81.0</a></h1>
  1897. <h2 id="application-service-path--authentication-deprecations"><a class="header" href="#application-service-path--authentication-deprecations">Application service path &amp; authentication deprecations</a></h2>
  1898. <p>Synapse now attempts the versioned appservice paths before falling back to the
  1899. <a href="https://spec.matrix.org/v1.6/application-service-api/#legacy-routes">legacy paths</a>.
  1900. Usage of the legacy routes should be considered deprecated.</p>
  1901. <p>Additionally, Synapse has supported sending the application service access token
  1902. via <a href="https://spec.matrix.org/v1.6/application-service-api/#authorization">the <code>Authorization</code> header</a>
  1903. since v1.70.0. For backwards compatibility it is <em>also</em> sent as the <code>access_token</code>
  1904. query parameter. This is insecure and should be considered deprecated.</p>
  1905. <p>A future version of Synapse (v1.88.0 or later) will remove support for legacy
  1906. application service routes and query parameter authorization.</p>
  1907. <h1 id="upgrading-to-v1800"><a class="header" href="#upgrading-to-v1800">Upgrading to v1.80.0</a></h1>
  1908. <h2 id="reporting-events-error-code-change"><a class="header" href="#reporting-events-error-code-change">Reporting events error code change</a></h2>
  1909. <p>Before this update, the
  1910. <a href="https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3roomsroomidreporteventid"><code>POST /_matrix/client/v3/rooms/{roomId}/report/{eventId}</code></a>
  1911. endpoint would return a <code>403</code> if a user attempted to report an event that they did not have access to.
  1912. This endpoint will now return a <code>404</code> in this case instead.</p>
  1913. <p>Clients that implement event reporting should check that their error handling code will handle this
  1914. change.</p>
  1915. <h1 id="upgrading-to-v1790"><a class="header" href="#upgrading-to-v1790">Upgrading to v1.79.0</a></h1>
  1916. <h2 id="the-on_threepid_bind-module-callback-method-has-been-deprecated"><a class="header" href="#the-on_threepid_bind-module-callback-method-has-been-deprecated">The <code>on_threepid_bind</code> module callback method has been deprecated</a></h2>
  1917. <p>Synapse v1.79.0 deprecates the
  1918. <a href="modules/third_party_rules_callbacks.html#on_threepid_bind"><code>on_threepid_bind</code></a>
  1919. &quot;third-party rules&quot; Synapse module callback method in favour of a new module method,
  1920. <a href="modules/third_party_rules_callbacks.html#on_add_user_third_party_identifier"><code>on_add_user_third_party_identifier</code></a>.
  1921. <code>on_threepid_bind</code> will be removed in a future version of Synapse. You should check whether any Synapse
  1922. modules in use in your deployment are making use of <code>on_threepid_bind</code>, and update them where possible.</p>
  1923. <p>The arguments and functionality of the new method are the same.</p>
  1924. <p>The justification behind the name change is that the old method's name, <code>on_threepid_bind</code>, was
  1925. misleading. A user is considered to &quot;bind&quot; their third-party ID to their Matrix ID only if they
  1926. do so via an <a href="https://spec.matrix.org/latest/identity-service-api/">identity server</a>
  1927. (so that users on other homeservers may find them). But this method was not called in that case -
  1928. it was only called when a user added a third-party identifier on the local homeserver.</p>
  1929. <p>Module developers may also be interested in the related
  1930. <a href="modules/third_party_rules_callbacks.html#on_remove_user_third_party_identifier"><code>on_remove_user_third_party_identifier</code></a>
  1931. module callback method that was also added in Synapse v1.79.0. This new method is called when a
  1932. user removes a third-party identifier from their account.</p>
  1933. <h1 id="upgrading-to-v1780"><a class="header" href="#upgrading-to-v1780">Upgrading to v1.78.0</a></h1>
  1934. <h2 id="deprecate-the-_synapseadminv1mediaserver_namedelete-admin-api"><a class="header" href="#deprecate-the-_synapseadminv1mediaserver_namedelete-admin-api">Deprecate the <code>/_synapse/admin/v1/media/&lt;server_name&gt;/delete</code> admin API</a></h2>
  1935. <p>Synapse 1.78.0 replaces the <code>/_synapse/admin/v1/media/&lt;server_name&gt;/delete</code>
  1936. admin API with an identical endpoint at <code>/_synapse/admin/v1/media/delete</code>. Please
  1937. update your tooling to use the new endpoint. The deprecated version will be removed
  1938. in a future release.</p>
  1939. <h1 id="upgrading-to-v1760"><a class="header" href="#upgrading-to-v1760">Upgrading to v1.76.0</a></h1>
  1940. <h2 id="faster-joins-are-enabled-by-default"><a class="header" href="#faster-joins-are-enabled-by-default">Faster joins are enabled by default</a></h2>
  1941. <p>When joining a room for the first time, Synapse 1.76.0 will request a partial join from the other server by default. Previously, server admins had to opt-in to this using an experimental config flag.</p>
  1942. <p>Server admins can opt out of this feature for the time being by setting</p>
  1943. <pre><code class="language-yaml">experimental:
  1944. faster_joins: false
  1945. </code></pre>
  1946. <p>in their server config.</p>
  1947. <h2 id="changes-to-the-account-data-replication-streams"><a class="header" href="#changes-to-the-account-data-replication-streams">Changes to the account data replication streams</a></h2>
  1948. <p>Synapse has changed the format of the account data and devices replication
  1949. streams (between workers). This is a forwards- and backwards-incompatible
  1950. change: v1.75 workers cannot process account data replicated by v1.76 workers,
  1951. and vice versa.</p>
  1952. <p>Once all workers are upgraded to v1.76 (or downgraded to v1.75), account data
  1953. and device replication will resume as normal.</p>
  1954. <h2 id="minimum-version-of-poetry-is-now-132"><a class="header" href="#minimum-version-of-poetry-is-now-132">Minimum version of Poetry is now 1.3.2</a></h2>
  1955. <p>The minimum supported version of Poetry is now 1.3.2 (previously 1.2.0, <a href="upgrade.html#upgrading-to-v1670">since
  1956. Synapse 1.67</a>). If you have used <code>poetry install</code> to
  1957. install Synapse from a source checkout, you should upgrade poetry: see its
  1958. <a href="https://python-poetry.org/docs/#installation">installation instructions</a>.
  1959. For all other installation methods, no acction is required.</p>
  1960. <h1 id="upgrading-to-v1740"><a class="header" href="#upgrading-to-v1740">Upgrading to v1.74.0</a></h1>
  1961. <h2 id="unicode-support-in-user-search"><a class="header" href="#unicode-support-in-user-search">Unicode support in user search</a></h2>
  1962. <p>This version introduces optional support for an <a href="https://github.com/matrix-org/synapse/pull/14464">improved user search dealing with Unicode characters</a>.</p>
  1963. <p>If you want to take advantage of this feature you need to install PyICU,
  1964. the ICU native dependency and its development headers
  1965. so that PyICU can build since no prebuilt wheels are available.</p>
  1966. <p>You can follow <a href="https://pypi.org/project/PyICU/">the PyICU documentation</a> to do so,
  1967. and then do <code>pip install matrix-synapse[user-search]</code> for a PyPI install.</p>
  1968. <p>Docker images and Debian packages need nothing specific as they already
  1969. include or specify ICU as an explicit dependency.</p>
  1970. <h2 id="user-directory-rebuild"><a class="header" href="#user-directory-rebuild">User directory rebuild</a></h2>
  1971. <p>Synapse 1.74 queues a background update
  1972. <a href="https://github.com/matrix-org/synapse/pull/14643">to rebuild the user directory</a>,
  1973. in order to fix missing or erroneous entries.</p>
  1974. <p>When this update begins, the user directory will be cleared out and rebuilt from
  1975. scratch. User directory lookups will be incomplete until the rebuild completes.
  1976. Admins can monitor the rebuild's progress by using the
  1977. <a href="usage/administration/admin_api/background_updates.html#status">Background update Admin API</a>.</p>
  1978. <h1 id="upgrading-to-v1730"><a class="header" href="#upgrading-to-v1730">Upgrading to v1.73.0</a></h1>
  1979. <h2 id="legacy-prometheus-metric-names-have-now-been-removed"><a class="header" href="#legacy-prometheus-metric-names-have-now-been-removed">Legacy Prometheus metric names have now been removed</a></h2>
  1980. <p>Synapse v1.69.0 included the deprecation of legacy Prometheus metric names
  1981. and offered an option to disable them.
  1982. Synapse v1.71.0 disabled legacy Prometheus metric names by default.</p>
  1983. <p>This version, v1.73.0, removes those legacy Prometheus metric names entirely.
  1984. This also means that the <code>enable_legacy_metrics</code> configuration option has been
  1985. removed; it will no longer be possible to re-enable the legacy metric names.</p>
  1986. <p>If you use metrics and have not yet updated your Grafana dashboard(s),
  1987. Prometheus console(s) or alerting rule(s), please consider doing so when upgrading
  1988. to this version.
  1989. Note that the included Grafana dashboard was updated in v1.72.0 to correct some
  1990. metric names which were missed when legacy metrics were disabled by default.</p>
  1991. <p>See <a href="upgrade.html#deprecation-of-legacy-prometheus-metric-names">v1.69.0: Deprecation of legacy Prometheus metric names</a>
  1992. for more context.</p>
  1993. <h1 id="upgrading-to-v1720"><a class="header" href="#upgrading-to-v1720">Upgrading to v1.72.0</a></h1>
  1994. <h2 id="dropping-support-for-postgresql-10"><a class="header" href="#dropping-support-for-postgresql-10">Dropping support for PostgreSQL 10</a></h2>
  1995. <p>In line with our <a href="deprecation_policy.html">deprecation policy</a>, we've dropped
  1996. support for PostgreSQL 10, as it is no longer supported upstream.</p>
  1997. <p>This release of Synapse requires PostgreSQL 11+.</p>
  1998. <h1 id="upgrading-to-v1710"><a class="header" href="#upgrading-to-v1710">Upgrading to v1.71.0</a></h1>
  1999. <h2 id="removal-of-the-generate_short_term_login_token-module-api-method"><a class="header" href="#removal-of-the-generate_short_term_login_token-module-api-method">Removal of the <code>generate_short_term_login_token</code> module API method</a></h2>
  2000. <p>As announced with the release of <a href="upgrade.html#deprecation-of-the-generate_short_term_login_token-module-api-method">Synapse 1.69.0</a>, the deprecated <code>generate_short_term_login_token</code> module method has been removed.</p>
  2001. <p>Modules relying on it can instead use the <code>create_login_token</code> method.</p>
  2002. <h2 id="changes-to-the-events-received-by-application-services-interest"><a class="header" href="#changes-to-the-events-received-by-application-services-interest">Changes to the events received by application services (interest)</a></h2>
  2003. <p>To align with spec (changed in
  2004. <a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3905">MSC3905</a>), Synapse now
  2005. only considers local users to be interesting. In other words, the <code>users</code> namespace
  2006. regex is only be applied against local users of the homeserver.</p>
  2007. <p>Please note, this probably doesn't affect the expected behavior of your application
  2008. service, since an interesting local user in a room still means all messages in the room
  2009. (from local or remote users) will still be considered interesting. And matching a room
  2010. with the <code>rooms</code> or <code>aliases</code> namespace regex will still consider all events sent in the
  2011. room to be interesting to the application service.</p>
  2012. <p>If one of your application service's <code>users</code> regex was intending to match a remote user,
  2013. this will no longer match as you expect. The behavioral mismatch between matching all
  2014. local users and some remote users is why the spec was changed/clarified and this
  2015. caveat is no longer supported.</p>
  2016. <h2 id="legacy-prometheus-metric-names-are-now-disabled-by-default"><a class="header" href="#legacy-prometheus-metric-names-are-now-disabled-by-default">Legacy Prometheus metric names are now disabled by default</a></h2>
  2017. <p>Synapse v1.71.0 disables legacy Prometheus metric names by default.
  2018. For administrators that still rely on them and have not yet had chance to update their
  2019. uses of the metrics, it's still possible to specify <code>enable_legacy_metrics: true</code> in
  2020. the configuration to re-enable them temporarily.</p>
  2021. <p>Synapse v1.73.0 will <strong>remove legacy metric names altogether</strong> and at that point,
  2022. it will no longer be possible to re-enable them.</p>
  2023. <p>If you do not use metrics or you have already updated your Grafana dashboard(s),
  2024. Prometheus console(s) and alerting rule(s), there is no action needed.</p>
  2025. <p>See <a href="upgrade.html#deprecation-of-legacy-prometheus-metric-names">v1.69.0: Deprecation of legacy Prometheus metric names</a>.</p>
  2026. <h1 id="upgrading-to-v1690"><a class="header" href="#upgrading-to-v1690">Upgrading to v1.69.0</a></h1>
  2027. <h2 id="changes-to-the-receipts-replication-streams"><a class="header" href="#changes-to-the-receipts-replication-streams">Changes to the receipts replication streams</a></h2>
  2028. <p>Synapse now includes information indicating if a receipt applies to a thread when
  2029. replicating it to other workers. This is a forwards- and backwards-incompatible
  2030. change: v1.68 and workers cannot process receipts replicated by v1.69 workers, and
  2031. vice versa.</p>
  2032. <p>Once all workers are upgraded to v1.69 (or downgraded to v1.68), receipts
  2033. replication will resume as normal.</p>
  2034. <h2 id="deprecation-of-legacy-prometheus-metric-names"><a class="header" href="#deprecation-of-legacy-prometheus-metric-names">Deprecation of legacy Prometheus metric names</a></h2>
  2035. <p>In current versions of Synapse, some Prometheus metrics are emitted under two different names,
  2036. with one of the names being older but non-compliant with OpenMetrics and Prometheus conventions
  2037. and one of the names being newer but compliant.</p>
  2038. <p>Synapse v1.71.0 will turn the old metric names off <em>by default</em>.
  2039. For administrators that still rely on them and have not had chance to update their
  2040. uses of the metrics, it's possible to specify <code>enable_legacy_metrics: true</code> in
  2041. the configuration to re-enable them temporarily.</p>
  2042. <p>Synapse v1.73.0 will <strong>remove legacy metric names altogether</strong> and it will no longer
  2043. be possible to re-enable them.</p>
  2044. <p>The Grafana dashboard, Prometheus recording rules and Prometheus Consoles included
  2045. in the <code>contrib</code> directory in the Synapse repository have been updated to no longer
  2046. rely on the legacy names. These can be used on a current version of Synapse
  2047. because current versions of Synapse emit both old and new names.</p>
  2048. <p>You may need to update your alerting rules or any other rules that depend on
  2049. the names of Prometheus metrics.
  2050. If you want to test your changes before legacy names are disabled by default,
  2051. you may specify <code>enable_legacy_metrics: false</code> in your homeserver configuration.</p>
  2052. <p>A list of affected metrics is available on the <a href="https://matrix-org.github.io/synapse/v1.69/metrics-howto.html?highlight=metrics%20deprecated#renaming-of-metrics--deprecation-of-old-names-in-12">Metrics How-to page</a>.</p>
  2053. <h2 id="deprecation-of-the-generate_short_term_login_token-module-api-method"><a class="header" href="#deprecation-of-the-generate_short_term_login_token-module-api-method">Deprecation of the <code>generate_short_term_login_token</code> module API method</a></h2>
  2054. <p>The following method of the module API has been deprecated, and is scheduled to
  2055. be remove in v1.71.0:</p>
  2056. <pre><code class="language-python">def generate_short_term_login_token(
  2057. self,
  2058. user_id: str,
  2059. duration_in_ms: int = (2 * 60 * 1000),
  2060. auth_provider_id: str = &quot;&quot;,
  2061. auth_provider_session_id: Optional[str] = None,
  2062. ) -&gt; str:
  2063. ...
  2064. </code></pre>
  2065. <p>It has been replaced by an asynchronous equivalent:</p>
  2066. <pre><code class="language-python">async def create_login_token(
  2067. self,
  2068. user_id: str,
  2069. duration_in_ms: int = (2 * 60 * 1000),
  2070. auth_provider_id: Optional[str] = None,
  2071. auth_provider_session_id: Optional[str] = None,
  2072. ) -&gt; str:
  2073. ...
  2074. </code></pre>
  2075. <p>Synapse will log a warning when a module uses the deprecated method, to help
  2076. administrators find modules using it.</p>
  2077. <h1 id="upgrading-to-v1680"><a class="header" href="#upgrading-to-v1680">Upgrading to v1.68.0</a></h1>
  2078. <p>Two changes announced in the upgrade notes for v1.67.0 have now landed in v1.68.0.</p>
  2079. <h2 id="sqlite-version-requirement"><a class="header" href="#sqlite-version-requirement">SQLite version requirement</a></h2>
  2080. <p>Synapse now requires a SQLite version of 3.27.0 or higher if SQLite is configured as
  2081. Synapse's database.</p>
  2082. <p>Installations using</p>
  2083. <ul>
  2084. <li>Docker images <a href="https://hub.docker.com/r/matrixdotorg/synapse">from <code>matrixdotorg</code></a>,</li>
  2085. <li>Debian packages <a href="https://packages.matrix.org/">from Matrix.org</a>, or</li>
  2086. <li>a PostgreSQL database</li>
  2087. </ul>
  2088. <p>are not affected.</p>
  2089. <h2 id="rust-requirement-when-building-from-source"><a class="header" href="#rust-requirement-when-building-from-source">Rust requirement when building from source.</a></h2>
  2090. <p>Building from a source checkout of Synapse now requires a recent Rust compiler
  2091. (currently Rust 1.58.1, but see also the
  2092. <a href="https://matrix-org.github.io/synapse/latest/deprecation_policy.html">Platform Dependency Policy</a>).</p>
  2093. <p>Installations using</p>
  2094. <ul>
  2095. <li>Docker images <a href="https://hub.docker.com/r/matrixdotorg/synapse">from <code>matrixdotorg</code></a>,</li>
  2096. <li>Debian packages <a href="https://packages.matrix.org/">from Matrix.org</a>, or</li>
  2097. <li>PyPI wheels via <code>pip install matrix-synapse</code> (on supported platforms and architectures)</li>
  2098. </ul>
  2099. <p>will not be affected.</p>
  2100. <h1 id="upgrading-to-v1670"><a class="header" href="#upgrading-to-v1670">Upgrading to v1.67.0</a></h1>
  2101. <h2 id="direct-tcp-replication-is-no-longer-supported-migrate-to-redis"><a class="header" href="#direct-tcp-replication-is-no-longer-supported-migrate-to-redis">Direct TCP replication is no longer supported: migrate to Redis</a></h2>
  2102. <p>Redis support was added in v1.13.0 with it becoming the recommended method in
  2103. v1.18.0. It replaced the old direct TCP connections (which was deprecated as of
  2104. v1.18.0) to the main process. With Redis, rather than all the workers connecting
  2105. to the main process, all the workers and the main process connect to Redis,
  2106. which relays replication commands between processes. This can give a significant
  2107. CPU saving on the main process and is a prerequisite for upcoming
  2108. performance improvements.</p>
  2109. <p>To migrate to Redis add the <a href="./workers.html#shared-configuration"><code>redis</code> config</a>,
  2110. and remove the TCP <code>replication</code> listener from config of the master and
  2111. <code>worker_replication_port</code> from worker config. Note that a HTTP listener with a
  2112. <code>replication</code> resource is still required.</p>
  2113. <h2 id="minimum-version-of-poetry-is-now-v120"><a class="header" href="#minimum-version-of-poetry-is-now-v120">Minimum version of Poetry is now v1.2.0</a></h2>
  2114. <p>The minimum supported version of poetry is now 1.2. This should only affect
  2115. those installing from a source checkout.</p>
  2116. <h2 id="rust-requirement-in-the-next-release"><a class="header" href="#rust-requirement-in-the-next-release">Rust requirement in the next release</a></h2>
  2117. <p>From the next major release (v1.68.0) installing Synapse from a source checkout
  2118. will require a recent Rust compiler. Those using packages or
  2119. <code>pip install matrix-synapse</code> will not be affected.</p>
  2120. <p>The simplest way of installing Rust is via <a href="https://rustup.rs/">rustup.rs</a></p>
  2121. <h2 id="sqlite-version-requirement-in-the-next-release"><a class="header" href="#sqlite-version-requirement-in-the-next-release">SQLite version requirement in the next release</a></h2>
  2122. <p>From the next major release (v1.68.0) Synapse will require SQLite 3.27.0 or
  2123. higher. Synapse v1.67.0 will be the last major release supporting SQLite
  2124. versions 3.22 to 3.26.</p>
  2125. <p>Those using Docker images or Debian packages from Matrix.org will not be
  2126. affected. If you have installed from source, you should check the version of
  2127. SQLite used by Python with:</p>
  2128. <pre><code class="language-shell">python -c &quot;import sqlite3; print(sqlite3.sqlite_version)&quot;
  2129. </code></pre>
  2130. <p>If this is too old, refer to your distribution for advice on upgrading.</p>
  2131. <h1 id="upgrading-to-v1660"><a class="header" href="#upgrading-to-v1660">Upgrading to v1.66.0</a></h1>
  2132. <h2 id="delegation-of-email-validation-no-longer-supported"><a class="header" href="#delegation-of-email-validation-no-longer-supported">Delegation of email validation no longer supported</a></h2>
  2133. <p>As of this version, Synapse no longer allows the tasks of verifying email address
  2134. ownership, and password reset confirmation, to be delegated to an identity server.
  2135. This removal was previously planned for Synapse 1.64.0, but was
  2136. <a href="https://github.com/matrix-org/synapse/issues/13421">delayed</a> until now to give
  2137. homeserver administrators more notice of the change.</p>
  2138. <p>To continue to allow users to add email addresses to their homeserver accounts,
  2139. and perform password resets, make sure that Synapse is configured with a working
  2140. email server in the <a href="https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email"><code>email</code> configuration
  2141. section</a>
  2142. (including, at a minimum, a <code>notif_from</code> setting.)</p>
  2143. <p>Specifying an <code>email</code> setting under <code>account_threepid_delegates</code> will now cause
  2144. an error at startup.</p>
  2145. <h1 id="upgrading-to-v1640"><a class="header" href="#upgrading-to-v1640">Upgrading to v1.64.0</a></h1>
  2146. <h2 id="deprecation-of-the-ability-to-delegate-e-mail-verification-to-identity-servers"><a class="header" href="#deprecation-of-the-ability-to-delegate-e-mail-verification-to-identity-servers">Deprecation of the ability to delegate e-mail verification to identity servers</a></h2>
  2147. <p>Synapse v1.66.0 will remove the ability to delegate the tasks of verifying email address ownership, and password reset confirmation, to an identity server.</p>
  2148. <p>If you require your homeserver to verify e-mail addresses or to support password resets via e-mail, please configure your homeserver with SMTP access so that it can send e-mails on its own behalf.
  2149. <a href="https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email">Consult the configuration documentation for more information.</a></p>
  2150. <p>The option that will be removed is <code>account_threepid_delegates.email</code>.</p>
  2151. <h2 id="changes-to-the-event-replication-streams"><a class="header" href="#changes-to-the-event-replication-streams">Changes to the event replication streams</a></h2>
  2152. <p>Synapse now includes a flag indicating if an event is an outlier when
  2153. replicating it to other workers. This is a forwards- and backwards-incompatible
  2154. change: v1.63 and workers cannot process events replicated by v1.64 workers, and
  2155. vice versa.</p>
  2156. <p>Once all workers are upgraded to v1.64 (or downgraded to v1.63), event
  2157. replication will resume as normal.</p>
  2158. <h2 id="frozendict-release"><a class="header" href="#frozendict-release">frozendict release</a></h2>
  2159. <p><a href="https://github.com/Marco-Sulla/python-frozendict/releases/tag/v2.3.3">frozendict 2.3.3</a>
  2160. has recently been released, which fixes a memory leak that occurs during <code>/sync</code>
  2161. requests. We advise server administrators who installed Synapse via pip to upgrade
  2162. frozendict with <code>pip install --upgrade frozendict</code>. The Docker image
  2163. <code>matrixdotorg/synapse</code> and the Debian packages from <code>packages.matrix.org</code> already
  2164. include the updated library.</p>
  2165. <h1 id="upgrading-to-v1620"><a class="header" href="#upgrading-to-v1620">Upgrading to v1.62.0</a></h1>
  2166. <h2 id="new-signatures-for-spam-checker-callbacks"><a class="header" href="#new-signatures-for-spam-checker-callbacks">New signatures for spam checker callbacks</a></h2>
  2167. <p>As a followup to changes in v1.60.0, the following spam-checker callbacks have changed signature:</p>
  2168. <ul>
  2169. <li><code>user_may_join_room</code></li>
  2170. <li><code>user_may_invite</code></li>
  2171. <li><code>user_may_send_3pid_invite</code></li>
  2172. <li><code>user_may_create_room</code></li>
  2173. <li><code>user_may_create_room_alias</code></li>
  2174. <li><code>user_may_publish_room</code></li>
  2175. <li><code>check_media_file_for_spam</code></li>
  2176. </ul>
  2177. <p>For each of these methods, the previous callback signature has been deprecated.</p>
  2178. <p>Whereas callbacks used to return <code>bool</code>, they should now return <code>Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;]</code>.</p>
  2179. <p>For instance, if your module implements <code>user_may_join_room</code> as follows:</p>
  2180. <pre><code class="language-python">async def user_may_join_room(self, user_id: str, room_id: str, is_invited: bool)
  2181. if ...:
  2182. # Request is spam
  2183. return False
  2184. # Request is not spam
  2185. return True
  2186. </code></pre>
  2187. <p>you should rewrite it as follows:</p>
  2188. <pre><code class="language-python">async def user_may_join_room(self, user_id: str, room_id: str, is_invited: bool)
  2189. if ...:
  2190. # Request is spam, mark it as forbidden (you may use some more precise error
  2191. # code if it is useful).
  2192. return synapse.module_api.errors.Codes.FORBIDDEN
  2193. # Request is not spam, mark it as such.
  2194. return synapse.module_api.NOT_SPAM
  2195. </code></pre>
  2196. <h1 id="upgrading-to-v1610"><a class="header" href="#upgrading-to-v1610">Upgrading to v1.61.0</a></h1>
  2197. <h2 id="removal-of-deprecated-communitygroups"><a class="header" href="#removal-of-deprecated-communitygroups">Removal of deprecated community/groups</a></h2>
  2198. <p>This release of Synapse will remove deprecated community/groups from codebase.</p>
  2199. <h3 id="worker-endpoints"><a class="header" href="#worker-endpoints">Worker endpoints</a></h3>
  2200. <p>For those who have deployed workers, following worker endpoints will no longer
  2201. exist and they can be removed from the reverse proxy configuration:</p>
  2202. <ul>
  2203. <li><code>^/_matrix/federation/v1/get_groups_publicised$</code></li>
  2204. <li><code>^/_matrix/client/(r0|v3|unstable)/joined_groups$</code></li>
  2205. <li><code>^/_matrix/client/(r0|v3|unstable)/publicised_groups$</code></li>
  2206. <li><code>^/_matrix/client/(r0|v3|unstable)/publicised_groups/</code></li>
  2207. <li><code>^/_matrix/federation/v1/groups/</code></li>
  2208. <li><code>^/_matrix/client/(r0|v3|unstable)/groups/</code></li>
  2209. </ul>
  2210. <h1 id="upgrading-to-v1600"><a class="header" href="#upgrading-to-v1600">Upgrading to v1.60.0</a></h1>
  2211. <h2 id="adding-a-new-unique-index-to-state_group_edges-could-fail-if-your-database-is-corrupted"><a class="header" href="#adding-a-new-unique-index-to-state_group_edges-could-fail-if-your-database-is-corrupted">Adding a new unique index to <code>state_group_edges</code> could fail if your database is corrupted</a></h2>
  2212. <p>This release of Synapse will add a unique index to the <code>state_group_edges</code> table, in order
  2213. to prevent accidentally introducing duplicate information (for example, because a database
  2214. backup was restored multiple times).</p>
  2215. <p>Duplicate rows being present in this table could cause drastic performance problems; see
  2216. <a href="https://github.com/matrix-org/synapse/issues/11779">issue 11779</a> for more details.</p>
  2217. <p>If your Synapse database already has had duplicate rows introduced into this table,
  2218. this could fail, with either of these errors:</p>
  2219. <p><strong>On Postgres:</strong></p>
  2220. <pre><code>synapse.storage.background_updates - 623 - INFO - background_updates-0 - Adding index state_group_edges_unique_idx to state_group_edges
  2221. synapse.storage.background_updates - 282 - ERROR - background_updates-0 - Error doing update
  2222. ...
  2223. psycopg2.errors.UniqueViolation: could not create unique index &quot;state_group_edges_unique_idx&quot;
  2224. DETAIL: Key (state_group, prev_state_group)=(2, 1) is duplicated.
  2225. </code></pre>
  2226. <p>(The numbers may be different.)</p>
  2227. <p><strong>On SQLite:</strong></p>
  2228. <pre><code>synapse.storage.background_updates - 623 - INFO - background_updates-0 - Adding index state_group_edges_unique_idx to state_group_edges
  2229. synapse.storage.background_updates - 282 - ERROR - background_updates-0 - Error doing update
  2230. ...
  2231. sqlite3.IntegrityError: UNIQUE constraint failed: state_group_edges.state_group, state_group_edges.prev_state_group
  2232. </code></pre>
  2233. <details>
  2234. <summary><b>Expand this section for steps to resolve this problem</b></summary>
  2235. <h3 id="on-postgres"><a class="header" href="#on-postgres">On Postgres</a></h3>
  2236. <p>Connect to your database with <code>psql</code>.</p>
  2237. <pre><code class="language-sql">BEGIN;
  2238. DELETE FROM state_group_edges WHERE (ctid, state_group, prev_state_group) IN (
  2239. SELECT row_id, state_group, prev_state_group
  2240. FROM (
  2241. SELECT
  2242. ctid AS row_id,
  2243. MIN(ctid) OVER (PARTITION BY state_group, prev_state_group) AS min_row_id,
  2244. state_group,
  2245. prev_state_group
  2246. FROM state_group_edges
  2247. ) AS t1
  2248. WHERE row_id &lt;&gt; min_row_id
  2249. );
  2250. COMMIT;
  2251. </code></pre>
  2252. <h3 id="on-sqlite"><a class="header" href="#on-sqlite">On SQLite</a></h3>
  2253. <p>At the command-line, use <code>sqlite3 path/to/your-homeserver-database.db</code>:</p>
  2254. <pre><code class="language-sql">BEGIN;
  2255. DELETE FROM state_group_edges WHERE (rowid, state_group, prev_state_group) IN (
  2256. SELECT row_id, state_group, prev_state_group
  2257. FROM (
  2258. SELECT
  2259. rowid AS row_id,
  2260. MIN(rowid) OVER (PARTITION BY state_group, prev_state_group) AS min_row_id,
  2261. state_group,
  2262. prev_state_group
  2263. FROM state_group_edges
  2264. )
  2265. WHERE row_id &lt;&gt; min_row_id
  2266. );
  2267. COMMIT;
  2268. </code></pre>
  2269. <h3 id="for-more-details"><a class="header" href="#for-more-details">For more details</a></h3>
  2270. <p><a href="https://github.com/matrix-org/synapse/issues/11779#issuecomment-1131545970">This comment on issue 11779</a>
  2271. has queries that can be used to check a database for this problem in advance.</p>
  2272. </details>
  2273. <h2 id="new-signature-for-the-spam-checker-callback-check_event_for_spam"><a class="header" href="#new-signature-for-the-spam-checker-callback-check_event_for_spam">New signature for the spam checker callback <code>check_event_for_spam</code></a></h2>
  2274. <p>The previous signature has been deprecated.</p>
  2275. <p>Whereas <code>check_event_for_spam</code> callbacks used to return <code>Union[str, bool]</code>, they should now return <code>Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;]</code>.</p>
  2276. <p>This is part of an ongoing refactoring of the SpamChecker API to make it less ambiguous and more powerful.</p>
  2277. <p>If your module implements <code>check_event_for_spam</code> as follows:</p>
  2278. <pre><code class="language-python">async def check_event_for_spam(event):
  2279. if ...:
  2280. # Event is spam
  2281. return True
  2282. # Event is not spam
  2283. return False
  2284. </code></pre>
  2285. <p>you should rewrite it as follows:</p>
  2286. <pre><code class="language-python">async def check_event_for_spam(event):
  2287. if ...:
  2288. # Event is spam, mark it as forbidden (you may use some more precise error
  2289. # code if it is useful).
  2290. return synapse.module_api.errors.Codes.FORBIDDEN
  2291. # Event is not spam, mark it as such.
  2292. return synapse.module_api.NOT_SPAM
  2293. </code></pre>
  2294. <h1 id="upgrading-to-v1590"><a class="header" href="#upgrading-to-v1590">Upgrading to v1.59.0</a></h1>
  2295. <h2 id="device-name-lookup-over-federation-has-been-disabled-by-default"><a class="header" href="#device-name-lookup-over-federation-has-been-disabled-by-default">Device name lookup over federation has been disabled by default</a></h2>
  2296. <p>The names of user devices are no longer visible to users on other homeservers by default.
  2297. Device IDs are unaffected, as these are necessary to facilitate end-to-end encryption.</p>
  2298. <p>To re-enable this functionality, set the
  2299. <a href="https://matrix-org.github.io/synapse/v1.59/usage/configuration/config_documentation.html#federation"><code>allow_device_name_lookup_over_federation</code></a>
  2300. homeserver config option to <code>true</code>.</p>
  2301. <h2 id="deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types"><a class="header" href="#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types">Deprecation of the <code>synapse.app.appservice</code> and <code>synapse.app.user_dir</code> worker application types</a></h2>
  2302. <p>The <code>synapse.app.appservice</code> worker application type allowed you to configure a
  2303. single worker to use to notify application services of new events, as long
  2304. as this functionality was disabled on the main process with <code>notify_appservices: False</code>.
  2305. Further, the <code>synapse.app.user_dir</code> worker application type allowed you to configure
  2306. a single worker to be responsible for updating the user directory, as long as this
  2307. was disabled on the main process with <code>update_user_directory: False</code>.</p>
  2308. <p>To unify Synapse's worker types, the <code>synapse.app.appservice</code> worker application
  2309. type and the <code>notify_appservices</code> configuration option have been deprecated.
  2310. The <code>synapse.app.user_dir</code> worker application type and <code>update_user_directory</code>
  2311. configuration option have also been deprecated.</p>
  2312. <p>To get the same functionality as was provided by the deprecated options, it's now recommended that the <code>synapse.app.generic_worker</code>
  2313. worker application type is used and that the <code>notify_appservices_from_worker</code> and/or
  2314. <code>update_user_directory_from_worker</code> options are set to the name of a worker.</p>
  2315. <p>For the time being, the old options can be used alongside the new options to make
  2316. it easier to transition between the two configurations, however please note that:</p>
  2317. <ul>
  2318. <li>the options must not contradict each other (otherwise Synapse won't start); and</li>
  2319. <li>the <code>notify_appservices</code> and <code>update_user_directory</code> options will be removed in a future release of Synapse.</li>
  2320. </ul>
  2321. <p>Please see the <a href="workers.html#notifying-application-services"><em>Notifying Application Services</em></a> and
  2322. <a href="workers.html#updating-the-user-directory"><em>Updating the User Directory</em></a> sections of the worker
  2323. documentation for more information.</p>
  2324. <h1 id="upgrading-to-v1580"><a class="header" href="#upgrading-to-v1580">Upgrading to v1.58.0</a></h1>
  2325. <h2 id="groupscommunities-feature-has-been-disabled-by-default"><a class="header" href="#groupscommunities-feature-has-been-disabled-by-default">Groups/communities feature has been disabled by default</a></h2>
  2326. <p>The non-standard groups/communities feature in Synapse has been disabled by default
  2327. and will be removed in Synapse v1.61.0.</p>
  2328. <h1 id="upgrading-to-v1570"><a class="header" href="#upgrading-to-v1570">Upgrading to v1.57.0</a></h1>
  2329. <h2 id="changes-to-database-schema-for-application-services"><a class="header" href="#changes-to-database-schema-for-application-services">Changes to database schema for application services</a></h2>
  2330. <p>Synapse v1.57.0 includes a <a href="https://github.com/matrix-org/synapse/pull/12209">change</a> to the
  2331. way transaction IDs are managed for application services. If your deployment uses a dedicated
  2332. worker for application service traffic, <strong>it must be stopped</strong> when the database is upgraded
  2333. (which normally happens when the main process is upgraded), to ensure the change is made safely
  2334. without any risk of reusing transaction IDs.</p>
  2335. <p>Deployments which do not use separate worker processes can be upgraded as normal. Similarly,
  2336. deployments where no application services are in use can be upgraded as normal.</p>
  2337. <details>
  2338. <summary><b>Recovering from an incorrect upgrade</b></summary>
  2339. <p>If the database schema is upgraded <em>without</em> stopping the worker responsible
  2340. for AS traffic, then the following error may be given when attempting to start
  2341. a Synapse worker or master process:</p>
  2342. <pre><code>**********************************************************************************
  2343. Error during initialisation:
  2344. Postgres sequence 'application_services_txn_id_seq' is inconsistent with associated
  2345. table 'application_services_txns'. This can happen if Synapse has been downgraded and
  2346. then upgraded again, or due to a bad migration.
  2347. To fix this error, shut down Synapse (including any and all workers)
  2348. and run the following SQL:
  2349. SELECT setval('application_services_txn_id_seq', (
  2350. SELECT GREATEST(MAX(txn_id), 0) FROM application_services_txns
  2351. ));
  2352. See docs/postgres.md for more information.
  2353. There may be more information in the logs.
  2354. **********************************************************************************
  2355. </code></pre>
  2356. <p>This error may also be seen if Synapse is <em>downgraded</em> to an earlier version,
  2357. and then upgraded again to v1.57.0 or later.</p>
  2358. <p>In either case:</p>
  2359. <ol>
  2360. <li>Ensure that the worker responsible for AS traffic is stopped.</li>
  2361. <li>Run the SQL command given in the error message via <code>psql</code>.</li>
  2362. </ol>
  2363. <p>Synapse should then start correctly.</p>
  2364. </details>
  2365. <h1 id="upgrading-to-v1560"><a class="header" href="#upgrading-to-v1560">Upgrading to v1.56.0</a></h1>
  2366. <h2 id="open-registration-without-verification-is-now-disabled-by-default"><a class="header" href="#open-registration-without-verification-is-now-disabled-by-default">Open registration without verification is now disabled by default</a></h2>
  2367. <p>Synapse will refuse to start if registration is enabled without email, captcha, or token-based verification unless the new config
  2368. flag <code>enable_registration_without_verification</code> is set to &quot;true&quot;.</p>
  2369. <h2 id="groupscommunities-feature-has-been-deprecated"><a class="header" href="#groupscommunities-feature-has-been-deprecated">Groups/communities feature has been deprecated</a></h2>
  2370. <p>The non-standard groups/communities feature in Synapse has been deprecated and will
  2371. be disabled by default in Synapse v1.58.0.</p>
  2372. <p>You can test disabling it by adding the following to your homeserver configuration:</p>
  2373. <pre><code class="language-yaml">experimental_features:
  2374. groups_enabled: false
  2375. </code></pre>
  2376. <h2 id="change-in-behaviour-for-postgresql-databases-with-unsafe-locale"><a class="header" href="#change-in-behaviour-for-postgresql-databases-with-unsafe-locale">Change in behaviour for PostgreSQL databases with unsafe locale</a></h2>
  2377. <p>Synapse now refuses to start when using PostgreSQL with non-<code>C</code> values for <code>COLLATE</code> and
  2378. <code>CTYPE</code> unless the config flag <code>allow_unsafe_locale</code>, found in the database section of
  2379. the configuration file, is set to <code>true</code>. See the <a href="https://matrix-org.github.io/synapse/latest/postgres.html#fixing-incorrect-collate-or-ctype">PostgreSQL documentation</a>
  2380. for more information and instructions on how to fix a database with incorrect values.</p>
  2381. <h1 id="upgrading-to-v1550"><a class="header" href="#upgrading-to-v1550">Upgrading to v1.55.0</a></h1>
  2382. <h2 id="synctl-script-has-been-moved"><a class="header" href="#synctl-script-has-been-moved"><code>synctl</code> script has been moved</a></h2>
  2383. <p>The <code>synctl</code> script
  2384. <a href="https://github.com/matrix-org/synapse/pull/12140">has been made</a> an
  2385. <a href="https://packaging.python.org/en/latest/specifications/entry-points/">entry point</a>
  2386. and no longer exists at the root of Synapse's source tree. If you wish to use
  2387. <code>synctl</code> to manage your homeserver, you should invoke <code>synctl</code> directly, e.g.
  2388. <code>synctl start</code> instead of <code>./synctl start</code> or <code>/path/to/synctl start</code>.</p>
  2389. <p>You will need to ensure <code>synctl</code> is on your <code>PATH</code>.</p>
  2390. <ul>
  2391. <li>This is automatically the case when using
  2392. <a href="https://packages.matrix.org/debian/">Debian packages</a> or
  2393. <a href="https://hub.docker.com/r/matrixdotorg/synapse">docker images</a>
  2394. provided by Matrix.org.</li>
  2395. <li>When installing from a wheel, sdist, or PyPI, a <code>synctl</code> executable is added
  2396. to your Python installation's <code>bin</code>. This should be on your <code>PATH</code>
  2397. automatically, though you might need to activate a virtual environment
  2398. depending on how you installed Synapse.</li>
  2399. </ul>
  2400. <h2 id="compatibility-dropped-for-mjolnir-131-and-earlier"><a class="header" href="#compatibility-dropped-for-mjolnir-131-and-earlier">Compatibility dropped for Mjolnir 1.3.1 and earlier</a></h2>
  2401. <p>Synapse v1.55.0 drops support for Mjolnir 1.3.1 and earlier.
  2402. If you use the Mjolnir module to moderate your homeserver,
  2403. please upgrade Mjolnir to version 1.3.2 or later before upgrading Synapse.</p>
  2404. <h1 id="upgrading-to-v1540"><a class="header" href="#upgrading-to-v1540">Upgrading to v1.54.0</a></h1>
  2405. <h2 id="legacy-structured-logging-configuration-removal"><a class="header" href="#legacy-structured-logging-configuration-removal">Legacy structured logging configuration removal</a></h2>
  2406. <p>This release removes support for the <code>structured: true</code> logging configuration
  2407. which was deprecated in Synapse v1.23.0. If your logging configuration contains
  2408. <code>structured: true</code> then it should be modified based on the
  2409. <a href="https://matrix-org.github.io/synapse/v1.56/structured_logging.html#upgrading-from-legacy-structured-logging-configuration">structured logging documentation</a>.</p>
  2410. <h1 id="upgrading-to-v1530"><a class="header" href="#upgrading-to-v1530">Upgrading to v1.53.0</a></h1>
  2411. <h2 id="dropping-support-for-webclient-listeners-and-non-https-web_client_location"><a class="header" href="#dropping-support-for-webclient-listeners-and-non-https-web_client_location">Dropping support for <code>webclient</code> listeners and non-HTTP(S) <code>web_client_location</code></a></h2>
  2412. <p>Per the deprecation notice in Synapse v1.51.0, listeners of type <code>webclient</code>
  2413. are no longer supported and configuring them is a now a configuration error.</p>
  2414. <p>Configuring a non-HTTP(S) <code>web_client_location</code> configuration is is now a
  2415. configuration error. Since the <code>webclient</code> listener is no longer supported, this
  2416. setting only applies to the root path <code>/</code> of Synapse's web server and no longer
  2417. the <code>/_matrix/client/</code> path.</p>
  2418. <h2 id="stablisation-of-msc3231"><a class="header" href="#stablisation-of-msc3231">Stablisation of MSC3231</a></h2>
  2419. <p>The unstable validity-check endpoint for the
  2420. <a href="https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv1registermloginregistration_tokenvalidity">Registration Tokens</a>
  2421. feature has been stabilised and moved from:</p>
  2422. <p><code>/_matrix/client/unstable/org.matrix.msc3231/register/org.matrix.msc3231.login.registration_token/validity</code></p>
  2423. <p>to:</p>
  2424. <p><code>/_matrix/client/v1/register/m.login.registration_token/validity</code></p>
  2425. <p>Please update any relevant reverse proxy or firewall configurations appropriately.</p>
  2426. <h2 id="time-based-cache-expiry-is-now-enabled-by-default"><a class="header" href="#time-based-cache-expiry-is-now-enabled-by-default">Time-based cache expiry is now enabled by default</a></h2>
  2427. <p>Formerly, entries in the cache were not evicted regardless of whether they were accessed after storing.
  2428. This behavior has now changed. By default entries in the cache are now evicted after 30m of not being accessed.
  2429. To change the default behavior, go to the <code>caches</code> section of the config and change the <code>expire_caches</code> and
  2430. <code>cache_entry_ttl</code> flags as necessary. Please note that these flags replace the <code>expiry_time</code> flag in the config.
  2431. The <code>expiry_time</code> flag will still continue to work, but it has been deprecated and will be removed in the future.</p>
  2432. <h2 id="deprecation-of-capability-orgmatrixmsc3283"><a class="header" href="#deprecation-of-capability-orgmatrixmsc3283">Deprecation of <code>capability</code> <code>org.matrix.msc3283.*</code></a></h2>
  2433. <p>The <code>capabilities</code> of MSC3283 from the REST API <code>/_matrix/client/r0/capabilities</code>
  2434. becomes stable.</p>
  2435. <p>The old <code>capabilities</code></p>
  2436. <ul>
  2437. <li><code>org.matrix.msc3283.set_displayname</code>,</li>
  2438. <li><code>org.matrix.msc3283.set_avatar_url</code> and</li>
  2439. <li><code>org.matrix.msc3283.3pid_changes</code></li>
  2440. </ul>
  2441. <p>are deprecated and scheduled to be removed in Synapse v1.54.0.</p>
  2442. <p>The new <code>capabilities</code></p>
  2443. <ul>
  2444. <li><code>m.set_displayname</code>,</li>
  2445. <li><code>m.set_avatar_url</code> and</li>
  2446. <li><code>m.3pid_changes</code></li>
  2447. </ul>
  2448. <p>are now active by default.</p>
  2449. <h2 id="removal-of-user_may_create_room_with_invites"><a class="header" href="#removal-of-user_may_create_room_with_invites">Removal of <code>user_may_create_room_with_invites</code></a></h2>
  2450. <p>As announced with the release of <a href="upgrade.html#deprecation-of-the-user_may_create_room_with_invites-module-callback">Synapse 1.47.0</a>,
  2451. the deprecated <code>user_may_create_room_with_invites</code> module callback has been removed.</p>
  2452. <p>Modules relying on it can instead implement <a href="https://matrix-org.github.io/synapse/latest/modules/spam_checker_callbacks.html#user_may_invite"><code>user_may_invite</code></a>
  2453. and use the <a href="https://github.com/matrix-org/synapse/blob/872f23b95fa980a61b0866c1475e84491991fa20/synapse/module_api/__init__.py#L869-L876"><code>get_room_state</code></a>
  2454. module API to infer whether the invite is happening while creating a room (see <a href="https://github.com/matrix-org/synapse-domain-rule-checker/blob/e7d092dd9f2a7f844928771dbfd9fd24c2332e48/synapse_domain_rule_checker/__init__.py#L56-L89">this function</a>
  2455. as an example). Alternately, modules can also implement <a href="https://matrix-org.github.io/synapse/latest/modules/third_party_rules_callbacks.html#on_create_room"><code>on_create_room</code></a>.</p>
  2456. <h1 id="upgrading-to-v1520"><a class="header" href="#upgrading-to-v1520">Upgrading to v1.52.0</a></h1>
  2457. <h2 id="twisted-security-release"><a class="header" href="#twisted-security-release">Twisted security release</a></h2>
  2458. <p>Note that <a href="https://github.com/twisted/twisted/releases/tag/twisted-22.1.0">Twisted 22.1.0</a>
  2459. has recently been released, which fixes a <a href="https://github.com/twisted/twisted/security/advisories/GHSA-92x2-jw7w-xvvx">security issue</a>
  2460. within the Twisted library. We do not believe Synapse is affected by this vulnerability,
  2461. though we advise server administrators who installed Synapse via pip to upgrade Twisted
  2462. with <code>pip install --upgrade Twisted treq</code> as a matter of good practice. The Docker image
  2463. <code>matrixdotorg/synapse</code> and the Debian packages from <code>packages.matrix.org</code> are using the
  2464. updated library.</p>
  2465. <h1 id="upgrading-to-v1510"><a class="header" href="#upgrading-to-v1510">Upgrading to v1.51.0</a></h1>
  2466. <h2 id="deprecation-of-webclient-listeners-and-non-https-web_client_location"><a class="header" href="#deprecation-of-webclient-listeners-and-non-https-web_client_location">Deprecation of <code>webclient</code> listeners and non-HTTP(S) <code>web_client_location</code></a></h2>
  2467. <p>Listeners of type <code>webclient</code> are deprecated and scheduled to be removed in
  2468. Synapse v1.53.0.</p>
  2469. <p>Similarly, a non-HTTP(S) <code>web_client_location</code> configuration is deprecated and
  2470. will become a configuration error in Synapse v1.53.0.</p>
  2471. <h1 id="upgrading-to-v1500"><a class="header" href="#upgrading-to-v1500">Upgrading to v1.50.0</a></h1>
  2472. <h2 id="dropping-support-for-old-python-and-postgres-versions"><a class="header" href="#dropping-support-for-old-python-and-postgres-versions">Dropping support for old Python and Postgres versions</a></h2>
  2473. <p>In line with our <a href="deprecation_policy.html">deprecation policy</a>,
  2474. we've dropped support for Python 3.6 and PostgreSQL 9.6, as they are no
  2475. longer supported upstream.</p>
  2476. <p>This release of Synapse requires Python 3.7+ and PostgreSQL 10+.</p>
  2477. <h1 id="upgrading-to-v1470"><a class="header" href="#upgrading-to-v1470">Upgrading to v1.47.0</a></h1>
  2478. <h2 id="removal-of-old-room-admin-api"><a class="header" href="#removal-of-old-room-admin-api">Removal of old Room Admin API</a></h2>
  2479. <p>The following admin APIs were deprecated in <a href="https://github.com/matrix-org/synapse/blob/v1.34.0/CHANGES.md#deprecations-and-removals">Synapse 1.34</a>
  2480. (released on 2021-05-17) and have now been removed:</p>
  2481. <ul>
  2482. <li><code>POST /_synapse/admin/v1/&lt;room_id&gt;/delete</code></li>
  2483. </ul>
  2484. <p>Any scripts still using the above APIs should be converted to use the
  2485. <a href="https://matrix-org.github.io/synapse/latest/admin_api/rooms.html#delete-room-api">Delete Room API</a>.</p>
  2486. <h2 id="deprecation-of-the-user_may_create_room_with_invites-module-callback"><a class="header" href="#deprecation-of-the-user_may_create_room_with_invites-module-callback">Deprecation of the <code>user_may_create_room_with_invites</code> module callback</a></h2>
  2487. <p>The <code>user_may_create_room_with_invites</code> is deprecated and will be removed in a future
  2488. version of Synapse. Modules implementing this callback can instead implement
  2489. <a href="https://matrix-org.github.io/synapse/latest/modules/spam_checker_callbacks.html#user_may_invite"><code>user_may_invite</code></a>
  2490. and use the <a href="https://github.com/matrix-org/synapse/blob/872f23b95fa980a61b0866c1475e84491991fa20/synapse/module_api/__init__.py#L869-L876"><code>get_room_state</code></a>
  2491. module API method to infer whether the invite is happening in the context of creating a
  2492. room.</p>
  2493. <p>We plan to remove this callback in January 2022.</p>
  2494. <h1 id="upgrading-to-v1450"><a class="header" href="#upgrading-to-v1450">Upgrading to v1.45.0</a></h1>
  2495. <h2 id="changes-required-to-media-storage-provider-modules-when-reading-from-the-synapse-configuration-object"><a class="header" href="#changes-required-to-media-storage-provider-modules-when-reading-from-the-synapse-configuration-object">Changes required to media storage provider modules when reading from the Synapse configuration object</a></h2>
  2496. <p>Media storage provider modules that read from the Synapse configuration object (i.e. that
  2497. read the value of <code>hs.config.[...]</code>) now need to specify the configuration section they're
  2498. reading from. This means that if a module reads the value of e.g. <code>hs.config.media_store_path</code>,
  2499. it needs to replace it with <code>hs.config.media.media_store_path</code>.</p>
  2500. <h1 id="upgrading-to-v1440"><a class="header" href="#upgrading-to-v1440">Upgrading to v1.44.0</a></h1>
  2501. <h2 id="the-url-preview-cache-is-no-longer-mirrored-to-storage-providers"><a class="header" href="#the-url-preview-cache-is-no-longer-mirrored-to-storage-providers">The URL preview cache is no longer mirrored to storage providers</a></h2>
  2502. <p>The <code>url_cache/</code> and <code>url_cache_thumbnails/</code> directories in the media store are
  2503. no longer mirrored to storage providers. These two directories can be safely
  2504. deleted from any configured storage providers to reclaim space.</p>
  2505. <h1 id="upgrading-to-v1430"><a class="header" href="#upgrading-to-v1430">Upgrading to v1.43.0</a></h1>
  2506. <h2 id="the-spaces-summary-apis-can-now-be-handled-by-workers"><a class="header" href="#the-spaces-summary-apis-can-now-be-handled-by-workers">The spaces summary APIs can now be handled by workers</a></h2>
  2507. <p>The <a href="https://matrix-org.github.io/synapse/latest/workers.html#available-worker-applications">available worker applications documentation</a>
  2508. has been updated to reflect that calls to the <code>/spaces</code>, <code>/hierarchy</code>, and
  2509. <code>/summary</code> endpoints can now be routed to workers for both client API and
  2510. federation requests.</p>
  2511. <h1 id="upgrading-to-v1420"><a class="header" href="#upgrading-to-v1420">Upgrading to v1.42.0</a></h1>
  2512. <h2 id="removal-of-old-room-admin-api-1"><a class="header" href="#removal-of-old-room-admin-api-1">Removal of old Room Admin API</a></h2>
  2513. <p>The following admin APIs were deprecated in <a href="https://github.com/matrix-org/synapse/blob/v1.25.0/CHANGES.md#removal-warning">Synapse 1.25</a>
  2514. (released on 2021-01-13) and have now been removed:</p>
  2515. <ul>
  2516. <li><code>POST /_synapse/admin/v1/purge_room</code></li>
  2517. <li><code>POST /_synapse/admin/v1/shutdown_room/&lt;room_id&gt;</code></li>
  2518. </ul>
  2519. <p>Any scripts still using the above APIs should be converted to use the
  2520. <a href="https://matrix-org.github.io/synapse/latest/admin_api/rooms.html#delete-room-api">Delete Room API</a>.</p>
  2521. <h2 id="user-interactive-authentication-fallback-templates-can-now-display-errors"><a class="header" href="#user-interactive-authentication-fallback-templates-can-now-display-errors">User-interactive authentication fallback templates can now display errors</a></h2>
  2522. <p>This may affect you if you make use of custom HTML templates for the
  2523. <a href="https://github.com/matrix-org/synapse/tree/develop/synapse/res/templates/recaptcha.html">reCAPTCHA (<code>synapse/res/templates/recaptcha.html</code>)</a> or
  2524. <a href="https://github.com/matrix-org/synapse/tree/develop/synapse/res/templates/terms.html">terms (<code>synapse/res/templates/terms.html</code>)</a> fallback pages.</p>
  2525. <p>The template is now provided an <code>error</code> variable if the authentication
  2526. process failed. See the default templates linked above for an example.</p>
  2527. <h2 id="removal-of-out-of-date-email-pushers"><a class="header" href="#removal-of-out-of-date-email-pushers">Removal of out-of-date email pushers</a></h2>
  2528. <p>Users will stop receiving message updates via email for addresses that were
  2529. once, but not still, linked to their account.</p>
  2530. <h1 id="upgrading-to-v1410"><a class="header" href="#upgrading-to-v1410">Upgrading to v1.41.0</a></h1>
  2531. <h2 id="add-support-for-routing-outbound-http-requests-via-a-proxy-for-federation"><a class="header" href="#add-support-for-routing-outbound-http-requests-via-a-proxy-for-federation">Add support for routing outbound HTTP requests via a proxy for federation</a></h2>
  2532. <p>Since Synapse 1.6.0 (2019-11-26) you can set a proxy for outbound HTTP requests via
  2533. http_proxy/https_proxy environment variables. This proxy was set for:</p>
  2534. <ul>
  2535. <li>push</li>
  2536. <li>url previews</li>
  2537. <li>phone-home stats</li>
  2538. <li>recaptcha validation</li>
  2539. <li>CAS auth validation</li>
  2540. <li>OpenID Connect</li>
  2541. <li>Federation (checking public key revocation)</li>
  2542. </ul>
  2543. <p>In this version we have added support for outbound requests for:</p>
  2544. <ul>
  2545. <li>Outbound federation</li>
  2546. <li>Downloading remote media</li>
  2547. <li>Fetching public keys of other servers</li>
  2548. </ul>
  2549. <p>These requests use the same proxy configuration. If you have a proxy configuration we
  2550. recommend to verify the configuration. It may be necessary to adjust the <code>no_proxy</code>
  2551. environment variable.</p>
  2552. <p>See <a href="setup/forward_proxy.html">using a forward proxy with Synapse documentation</a> for
  2553. details.</p>
  2554. <h2 id="deprecation-of-template_dir"><a class="header" href="#deprecation-of-template_dir">Deprecation of <code>template_dir</code></a></h2>
  2555. <p>The <code>template_dir</code> settings in the <code>sso</code>, <code>account_validity</code> and <code>email</code> sections of the
  2556. configuration file are now deprecated. Server admins should use the new
  2557. <code>templates.custom_template_directory</code> setting in the configuration file and use one single
  2558. custom template directory for all aforementioned features. Template file names remain
  2559. unchanged. See <a href="https://matrix-org.github.io/synapse/latest/templates.html">the related documentation</a>
  2560. for more information and examples.</p>
  2561. <p>We plan to remove support for these settings in October 2021.</p>
  2562. <h2 id="_synapseadminv1usersuseridmedia-must-be-handled-by-media-workers"><a class="header" href="#_synapseadminv1usersuseridmedia-must-be-handled-by-media-workers"><code>/_synapse/admin/v1/users/{userId}/media</code> must be handled by media workers</a></h2>
  2563. <p>The <a href="https://matrix-org.github.io/synapse/latest/workers.html#synapseappmedia_repository">media repository worker documentation</a>
  2564. has been updated to reflect that calls to <code>/_synapse/admin/v1/users/{userId}/media</code>
  2565. must now be handled by media repository workers. This is due to the new <code>DELETE</code> method
  2566. of this endpoint modifying the media store.</p>
  2567. <h1 id="upgrading-to-v1390"><a class="header" href="#upgrading-to-v1390">Upgrading to v1.39.0</a></h1>
  2568. <h2 id="deprecation-of-the-current-third-party-rules-module-interface"><a class="header" href="#deprecation-of-the-current-third-party-rules-module-interface">Deprecation of the current third-party rules module interface</a></h2>
  2569. <p>The current third-party rules module interface is deprecated in favour of the new generic
  2570. modules system introduced in Synapse v1.37.0. Authors of third-party rules modules can refer
  2571. to <a href="modules/porting_legacy_module.html">this documentation</a>
  2572. to update their modules. Synapse administrators can refer to <a href="modules/index.html">this documentation</a>
  2573. to update their configuration once the modules they are using have been updated.</p>
  2574. <p>We plan to remove support for the current third-party rules interface in September 2021.</p>
  2575. <h1 id="upgrading-to-v1380"><a class="header" href="#upgrading-to-v1380">Upgrading to v1.38.0</a></h1>
  2576. <h2 id="re-indexing-of-events-table-on-postgres-databases"><a class="header" href="#re-indexing-of-events-table-on-postgres-databases">Re-indexing of <code>events</code> table on Postgres databases</a></h2>
  2577. <p>This release includes a database schema update which requires re-indexing one of
  2578. the larger tables in the database, <code>events</code>. This could result in increased
  2579. disk I/O for several hours or days after upgrading while the migration
  2580. completes. Furthermore, because we have to keep the old indexes until the new
  2581. indexes are ready, it could result in a significant, temporary, increase in
  2582. disk space.</p>
  2583. <p>To get a rough idea of the disk space required, check the current size of one
  2584. of the indexes. For example, from a <code>psql</code> shell, run the following sql:</p>
  2585. <pre><code class="language-sql">SELECT pg_size_pretty(pg_relation_size('events_order_room'));
  2586. </code></pre>
  2587. <p>We need to rebuild <strong>four</strong> indexes, so you will need to multiply this result
  2588. by four to give an estimate of the disk space required. For example, on one
  2589. particular server:</p>
  2590. <pre><code>synapse=# select pg_size_pretty(pg_relation_size('events_order_room'));
  2591. pg_size_pretty
  2592. ----------------
  2593. 288 MB
  2594. (1 row)
  2595. </code></pre>
  2596. <p>On this server, it would be wise to ensure that at least 1152MB are free.</p>
  2597. <p>The additional disk space will be freed once the migration completes.</p>
  2598. <p>SQLite databases are unaffected by this change.</p>
  2599. <h1 id="upgrading-to-v1370"><a class="header" href="#upgrading-to-v1370">Upgrading to v1.37.0</a></h1>
  2600. <h2 id="deprecation-of-the-current-spam-checker-interface"><a class="header" href="#deprecation-of-the-current-spam-checker-interface">Deprecation of the current spam checker interface</a></h2>
  2601. <p>The current spam checker interface is deprecated in favour of a new generic modules system.
  2602. Authors of spam checker modules can refer to [this
  2603. documentation](modules/porting_legacy_module.md
  2604. to update their modules. Synapse administrators can refer to <a href="modules/index.html">this
  2605. documentation</a>
  2606. to update their configuration once the modules they are using have been updated.</p>
  2607. <p>We plan to remove support for the current spam checker interface in August 2021.</p>
  2608. <p>More module interfaces will be ported over to this new generic system in future versions
  2609. of Synapse.</p>
  2610. <h1 id="upgrading-to-v1340"><a class="header" href="#upgrading-to-v1340">Upgrading to v1.34.0</a></h1>
  2611. <h2 id="room_invite_state_types-configuration-setting"><a class="header" href="#room_invite_state_types-configuration-setting"><code>room_invite_state_types</code> configuration setting</a></h2>
  2612. <p>The <code>room_invite_state_types</code> configuration setting has been deprecated
  2613. and replaced with <code>room_prejoin_state</code>. See the <a href="https://github.com/matrix-org/synapse/blob/v1.34.0/docs/sample_config.yaml#L1515">sample configuration
  2614. file</a>.</p>
  2615. <p>If you have set <code>room_invite_state_types</code> to the default value you
  2616. should simply remove it from your configuration file. The default value
  2617. used to be:</p>
  2618. <pre><code class="language-yaml">room_invite_state_types:
  2619. - &quot;m.room.join_rules&quot;
  2620. - &quot;m.room.canonical_alias&quot;
  2621. - &quot;m.room.avatar&quot;
  2622. - &quot;m.room.encryption&quot;
  2623. - &quot;m.room.name&quot;
  2624. </code></pre>
  2625. <p>If you have customised this value, you should remove
  2626. <code>room_invite_state_types</code> and configure <code>room_prejoin_state</code> instead.</p>
  2627. <h1 id="upgrading-to-v1330"><a class="header" href="#upgrading-to-v1330">Upgrading to v1.33.0</a></h1>
  2628. <h2 id="account-validity-html-templates-can-now-display-a-users-expiration-date"><a class="header" href="#account-validity-html-templates-can-now-display-a-users-expiration-date">Account Validity HTML templates can now display a user's expiration date</a></h2>
  2629. <p>This may affect you if you have enabled the account validity feature,
  2630. and have made use of a custom HTML template specified by the
  2631. <code>account_validity.template_dir</code> or
  2632. <code>account_validity.account_renewed_html_path</code> Synapse config options.</p>
  2633. <p>The template can now accept an <code>expiration_ts</code> variable, which
  2634. represents the unix timestamp in milliseconds for the future date of
  2635. which their account has been renewed until. See the <a href="https://github.com/matrix-org/synapse/blob/release-v1.33.0/synapse/res/templates/account_renewed.html">default
  2636. template</a>
  2637. for an example of usage.</p>
  2638. <p>ALso note that a new HTML template, <code>account_previously_renewed.html</code>,
  2639. has been added. This is is shown to users when they attempt to renew
  2640. their account with a valid renewal token that has already been used
  2641. before. The default template contents can been found
  2642. <a href="https://github.com/matrix-org/synapse/blob/release-v1.33.0/synapse/res/templates/account_previously_renewed.html">here</a>,
  2643. and can also accept an <code>expiration_ts</code> variable. This template replaces
  2644. the error message users would previously see upon attempting to use a
  2645. valid renewal token more than once.</p>
  2646. <h1 id="upgrading-to-v1320"><a class="header" href="#upgrading-to-v1320">Upgrading to v1.32.0</a></h1>
  2647. <h2 id="regression-causing-connected-prometheus-instances-to-become-overwhelmed"><a class="header" href="#regression-causing-connected-prometheus-instances-to-become-overwhelmed">Regression causing connected Prometheus instances to become overwhelmed</a></h2>
  2648. <p>This release introduces <a href="https://github.com/matrix-org/synapse/issues/9853">a
  2649. regression</a> that can
  2650. overwhelm connected Prometheus instances. This issue is not present in
  2651. Synapse v1.32.0rc1.</p>
  2652. <p>If you have been affected, please downgrade to 1.31.0. You then may need
  2653. to remove excess writeahead logs in order for Prometheus to recover.
  2654. Instructions for doing so are provided
  2655. <a href="https://github.com/matrix-org/synapse/pull/9854#issuecomment-823472183">here</a>.</p>
  2656. <h2 id="dropping-support-for-old-python-postgres-and-sqlite-versions"><a class="header" href="#dropping-support-for-old-python-postgres-and-sqlite-versions">Dropping support for old Python, Postgres and SQLite versions</a></h2>
  2657. <p>In line with our <a href="deprecation_policy.html">deprecation policy</a>,
  2658. we've dropped support for Python 3.5 and PostgreSQL 9.5, as they are no
  2659. longer supported upstream.</p>
  2660. <p>This release of Synapse requires Python 3.6+ and PostgreSQL 9.6+ or
  2661. SQLite 3.22+.</p>
  2662. <h2 id="removal-of-old-list-accounts-admin-api"><a class="header" href="#removal-of-old-list-accounts-admin-api">Removal of old List Accounts Admin API</a></h2>
  2663. <p>The deprecated v1 &quot;list accounts&quot; admin API
  2664. (<code>GET /_synapse/admin/v1/users/&lt;user_id&gt;</code>) has been removed in this
  2665. version.</p>
  2666. <p>The <a href="admin_api/user_admin_api.html#list-accounts">v2 list accounts API</a>
  2667. has been available since Synapse 1.7.0 (2019-12-13), and is accessible
  2668. under <code>GET /_synapse/admin/v2/users</code>.</p>
  2669. <p>The deprecation of the old endpoint was announced with Synapse 1.28.0
  2670. (released on 2021-02-25).</p>
  2671. <h2 id="application-services-must-use-type-mloginapplication_service-when-registering-users"><a class="header" href="#application-services-must-use-type-mloginapplication_service-when-registering-users">Application Services must use type <code>m.login.application_service</code> when registering users</a></h2>
  2672. <p>In compliance with the <a href="https://matrix.org/docs/spec/application_service/r0.1.2#server-admin-style-permissions">Application Service
  2673. spec</a>,
  2674. Application Services are now required to use the
  2675. <code>m.login.application_service</code> type when registering users via the
  2676. <code>/_matrix/client/r0/register</code> endpoint. This behaviour was deprecated in
  2677. Synapse v1.30.0.</p>
  2678. <p>Please ensure your Application Services are up to date.</p>
  2679. <h1 id="upgrading-to-v1290"><a class="header" href="#upgrading-to-v1290">Upgrading to v1.29.0</a></h1>
  2680. <h2 id="requirement-for-x-forwarded-proto-header"><a class="header" href="#requirement-for-x-forwarded-proto-header">Requirement for X-Forwarded-Proto header</a></h2>
  2681. <p>When using Synapse with a reverse proxy (in particular, when using the
  2682. <code>x_forwarded</code> option on an HTTP listener), Synapse now
  2683. expects to receive an <code>X-Forwarded-Proto</code> header on incoming
  2684. HTTP requests. If it is not set, Synapse will log a warning on each
  2685. received request.</p>
  2686. <p>To avoid the warning, administrators using a reverse proxy should ensure
  2687. that the reverse proxy sets <code>X-Forwarded-Proto</code> header to
  2688. <code>https</code> or <code>http</code> to indicate the protocol used
  2689. by the client.</p>
  2690. <p>Synapse also requires the <code>Host</code> header to be preserved.</p>
  2691. <p>See the <a href="reverse_proxy.html">reverse proxy documentation</a>, where the
  2692. example configurations have been updated to show how to set these
  2693. headers.</p>
  2694. <p>(Users of <a href="https://caddyserver.com/">Caddy</a> are unaffected, since we
  2695. believe it sets <code>X-Forwarded-Proto</code> by default.)</p>
  2696. <h1 id="upgrading-to-v1270"><a class="header" href="#upgrading-to-v1270">Upgrading to v1.27.0</a></h1>
  2697. <h2 id="changes-to-callback-uri-for-oauth2--openid-connect-and-saml2"><a class="header" href="#changes-to-callback-uri-for-oauth2--openid-connect-and-saml2">Changes to callback URI for OAuth2 / OpenID Connect and SAML2</a></h2>
  2698. <p>This version changes the URI used for callbacks from OAuth2 and SAML2
  2699. identity providers:</p>
  2700. <ul>
  2701. <li>
  2702. <p>If your server is configured for single sign-on via an OpenID
  2703. Connect or OAuth2 identity provider, you will need to add
  2704. <code>[synapse public baseurl]/_synapse/client/oidc/callback</code> to the list
  2705. of permitted &quot;redirect URIs&quot; at the identity provider.</p>
  2706. <p>See the <a href="openid.html">OpenID docs</a> for more information on setting
  2707. up OpenID Connect.</p>
  2708. </li>
  2709. <li>
  2710. <p>If your server is configured for single sign-on via a SAML2 identity
  2711. provider, you will need to add
  2712. <code>[synapse public baseurl]/_synapse/client/saml2/authn_response</code> as a
  2713. permitted &quot;ACS location&quot; (also known as &quot;allowed callback URLs&quot;)
  2714. at the identity provider.</p>
  2715. <p>The &quot;Issuer&quot; in the &quot;AuthnRequest&quot; to the SAML2 identity
  2716. provider is also updated to
  2717. <code>[synapse public baseurl]/_synapse/client/saml2/metadata.xml</code>. If
  2718. your SAML2 identity provider uses this property to validate or
  2719. otherwise identify Synapse, its configuration will need to be
  2720. updated to use the new URL. Alternatively you could create a new,
  2721. separate &quot;EntityDescriptor&quot; in your SAML2 identity provider with
  2722. the new URLs and leave the URLs in the existing &quot;EntityDescriptor&quot;
  2723. as they were.</p>
  2724. </li>
  2725. </ul>
  2726. <h2 id="changes-to-html-templates"><a class="header" href="#changes-to-html-templates">Changes to HTML templates</a></h2>
  2727. <p>The HTML templates for SSO and email notifications now have <a href="https://jinja.palletsprojects.com/en/2.11.x/api/#autoescaping">Jinja2's
  2728. autoescape</a>
  2729. enabled for files ending in <code>.html</code>, <code>.htm</code>, and <code>.xml</code>. If you have
  2730. customised these templates and see issues when viewing them you might
  2731. need to update them. It is expected that most configurations will need
  2732. no changes.</p>
  2733. <p>If you have customised the templates <em>names</em> for these templates, it is
  2734. recommended to verify they end in <code>.html</code> to ensure autoescape is
  2735. enabled.</p>
  2736. <p>The above applies to the following templates:</p>
  2737. <ul>
  2738. <li><code>add_threepid.html</code></li>
  2739. <li><code>add_threepid_failure.html</code></li>
  2740. <li><code>add_threepid_success.html</code></li>
  2741. <li><code>notice_expiry.html</code></li>
  2742. <li><code>notice_expiry.html</code></li>
  2743. <li><code>notif_mail.html</code> (which, by default, includes <code>room.html</code> and
  2744. <code>notif.html</code>)</li>
  2745. <li><code>password_reset.html</code></li>
  2746. <li><code>password_reset_confirmation.html</code></li>
  2747. <li><code>password_reset_failure.html</code></li>
  2748. <li><code>password_reset_success.html</code></li>
  2749. <li><code>registration.html</code></li>
  2750. <li><code>registration_failure.html</code></li>
  2751. <li><code>registration_success.html</code></li>
  2752. <li><code>sso_account_deactivated.html</code></li>
  2753. <li><code>sso_auth_bad_user.html</code></li>
  2754. <li><code>sso_auth_confirm.html</code></li>
  2755. <li><code>sso_auth_success.html</code></li>
  2756. <li><code>sso_error.html</code></li>
  2757. <li><code>sso_login_idp_picker.html</code></li>
  2758. <li><code>sso_redirect_confirm.html</code></li>
  2759. </ul>
  2760. <h1 id="upgrading-to-v1260"><a class="header" href="#upgrading-to-v1260">Upgrading to v1.26.0</a></h1>
  2761. <h2 id="rolling-back-to-v1250-after-a-failed-upgrade"><a class="header" href="#rolling-back-to-v1250-after-a-failed-upgrade">Rolling back to v1.25.0 after a failed upgrade</a></h2>
  2762. <p>v1.26.0 includes a lot of large changes. If something problematic
  2763. occurs, you may want to roll-back to a previous version of Synapse.
  2764. Because v1.26.0 also includes a new database schema version, reverting
  2765. that version is also required alongside the generic rollback
  2766. instructions mentioned above. In short, to roll back to v1.25.0 you need
  2767. to:</p>
  2768. <ol>
  2769. <li>
  2770. <p>Stop the server</p>
  2771. </li>
  2772. <li>
  2773. <p>Decrease the schema version in the database:</p>
  2774. <pre><code class="language-sql">UPDATE schema_version SET version = 58;
  2775. </code></pre>
  2776. </li>
  2777. <li>
  2778. <p>Delete the ignored users &amp; chain cover data:</p>
  2779. <pre><code class="language-sql">DROP TABLE IF EXISTS ignored_users;
  2780. UPDATE rooms SET has_auth_chain_index = false;
  2781. </code></pre>
  2782. <p>For PostgreSQL run:</p>
  2783. <pre><code class="language-sql">TRUNCATE event_auth_chain_links;
  2784. TRUNCATE event_auth_chains;
  2785. </code></pre>
  2786. <p>For SQLite run:</p>
  2787. <pre><code class="language-sql">DELETE FROM event_auth_chain_links;
  2788. DELETE FROM event_auth_chains;
  2789. </code></pre>
  2790. </li>
  2791. <li>
  2792. <p>Mark the deltas as not run (so they will re-run on upgrade).</p>
  2793. <pre><code class="language-sql">DELETE FROM applied_schema_deltas WHERE version = 59 AND file = &quot;59/01ignored_user.py&quot;;
  2794. DELETE FROM applied_schema_deltas WHERE version = 59 AND file = &quot;59/06chain_cover_index.sql&quot;;
  2795. </code></pre>
  2796. </li>
  2797. <li>
  2798. <p>Downgrade Synapse by following the instructions for your
  2799. installation method in the &quot;Rolling back to older versions&quot;
  2800. section above.</p>
  2801. </li>
  2802. </ol>
  2803. <h1 id="upgrading-to-v1250"><a class="header" href="#upgrading-to-v1250">Upgrading to v1.25.0</a></h1>
  2804. <h2 id="last-release-supporting-python-35"><a class="header" href="#last-release-supporting-python-35">Last release supporting Python 3.5</a></h2>
  2805. <p>This is the last release of Synapse which guarantees support with Python
  2806. 3.5, which passed its upstream End of Life date several months ago.</p>
  2807. <p>We will attempt to maintain support through March 2021, but without
  2808. guarantees.</p>
  2809. <p>In the future, Synapse will follow upstream schedules for ending support
  2810. of older versions of Python and PostgreSQL. Please upgrade to at least
  2811. Python 3.6 and PostgreSQL 9.6 as soon as possible.</p>
  2812. <h2 id="blacklisting-ip-ranges"><a class="header" href="#blacklisting-ip-ranges">Blacklisting IP ranges</a></h2>
  2813. <p>Synapse v1.25.0 includes new settings, <code>ip_range_blacklist</code> and
  2814. <code>ip_range_whitelist</code>, for controlling outgoing requests from Synapse for
  2815. federation, identity servers, push, and for checking key validity for
  2816. third-party invite events. The previous setting,
  2817. <code>federation_ip_range_blacklist</code>, is deprecated. The new
  2818. <code>ip_range_blacklist</code> defaults to private IP ranges if it is not defined.</p>
  2819. <p>If you have never customised <code>federation_ip_range_blacklist</code> it is
  2820. recommended that you remove that setting.</p>
  2821. <p>If you have customised <code>federation_ip_range_blacklist</code> you should update
  2822. the setting name to <code>ip_range_blacklist</code>.</p>
  2823. <p>If you have a custom push server that is reached via private IP space
  2824. you may need to customise <code>ip_range_blacklist</code> or <code>ip_range_whitelist</code>.</p>
  2825. <h1 id="upgrading-to-v1240"><a class="header" href="#upgrading-to-v1240">Upgrading to v1.24.0</a></h1>
  2826. <h2 id="custom-openid-connect-mapping-provider-breaking-change"><a class="header" href="#custom-openid-connect-mapping-provider-breaking-change">Custom OpenID Connect mapping provider breaking change</a></h2>
  2827. <p>This release allows the OpenID Connect mapping provider to perform
  2828. normalisation of the localpart of the Matrix ID. This allows for the
  2829. mapping provider to specify different algorithms, instead of the
  2830. <a href="https://matrix.org/docs/spec/appendices#mapping-from-other-character-sets">default
  2831. way</a>.</p>
  2832. <p>If your Synapse configuration uses a custom mapping provider
  2833. (<code>oidc_config.user_mapping_provider.module</code> is specified and
  2834. not equal to
  2835. <code>synapse.handlers.oidc_handler.JinjaOidcMappingProvider</code>)
  2836. then you <em>must</em> ensure that <code>map_user_attributes</code> of the
  2837. mapping provider performs some normalisation of the
  2838. <code>localpart</code> returned. To match previous behaviour you can
  2839. use the <code>map_username_to_mxid_localpart</code> function provided
  2840. by Synapse. An example is shown below:</p>
  2841. <pre><code class="language-python">from synapse.types import map_username_to_mxid_localpart
  2842. class MyMappingProvider:
  2843. def map_user_attributes(self, userinfo, token):
  2844. # ... your custom logic ...
  2845. sso_user_id = ...
  2846. localpart = map_username_to_mxid_localpart(sso_user_id)
  2847. return {&quot;localpart&quot;: localpart}
  2848. </code></pre>
  2849. <h2 id="removal-historical-synapse-admin-api"><a class="header" href="#removal-historical-synapse-admin-api">Removal historical Synapse Admin API</a></h2>
  2850. <p>Historically, the Synapse Admin API has been accessible under:</p>
  2851. <ul>
  2852. <li><code>/_matrix/client/api/v1/admin</code></li>
  2853. <li><code>/_matrix/client/unstable/admin</code></li>
  2854. <li><code>/_matrix/client/r0/admin</code></li>
  2855. <li><code>/_synapse/admin/v1</code></li>
  2856. </ul>
  2857. <p>The endpoints with <code>/_matrix/client/*</code> prefixes have been removed as of
  2858. v1.24.0. The Admin API is now only accessible under:</p>
  2859. <ul>
  2860. <li><code>/_synapse/admin/v1</code></li>
  2861. </ul>
  2862. <p>The only exception is the <code>/admin/whois</code> endpoint, which is
  2863. <a href="https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-admin-whois-userid">also available via the client-server
  2864. API</a>.</p>
  2865. <p>The deprecation of the old endpoints was announced with Synapse 1.20.0
  2866. (released on 2020-09-22) and makes it easier for homeserver admins to
  2867. lock down external access to the Admin API endpoints.</p>
  2868. <h1 id="upgrading-to-v1230"><a class="header" href="#upgrading-to-v1230">Upgrading to v1.23.0</a></h1>
  2869. <h2 id="structured-logging-configuration-breaking-changes"><a class="header" href="#structured-logging-configuration-breaking-changes">Structured logging configuration breaking changes</a></h2>
  2870. <p>This release deprecates use of the <code>structured: true</code> logging
  2871. configuration for structured logging. If your logging configuration
  2872. contains <code>structured: true</code> then it should be modified based on the
  2873. <a href="https://matrix-org.github.io/synapse/v1.56/structured_logging.html#upgrading-from-legacy-structured-logging-configuration">structured logging documentation</a>.</p>
  2874. <p>The <code>structured</code> and <code>drains</code> logging options are now deprecated and
  2875. should be replaced by standard logging configuration of <code>handlers</code> and
  2876. <code>formatters</code>.</p>
  2877. <p>A future will release of Synapse will make using <code>structured: true</code> an
  2878. error.</p>
  2879. <h1 id="upgrading-to-v1220"><a class="header" href="#upgrading-to-v1220">Upgrading to v1.22.0</a></h1>
  2880. <h2 id="thirdpartyeventrules-breaking-changes"><a class="header" href="#thirdpartyeventrules-breaking-changes">ThirdPartyEventRules breaking changes</a></h2>
  2881. <p>This release introduces a backwards-incompatible change to modules
  2882. making use of <code>ThirdPartyEventRules</code> in Synapse. If you make use of a
  2883. module defined under the <code>third_party_event_rules</code> config option, please
  2884. make sure it is updated to handle the below change:</p>
  2885. <p>The <code>http_client</code> argument is no longer passed to modules as they are
  2886. initialised. Instead, modules are expected to make use of the
  2887. <code>http_client</code> property on the <code>ModuleApi</code> class. Modules are now passed
  2888. a <code>module_api</code> argument during initialisation, which is an instance of
  2889. <code>ModuleApi</code>. <code>ModuleApi</code> instances have a <code>http_client</code> property which
  2890. acts the same as the <code>http_client</code> argument previously passed to
  2891. <code>ThirdPartyEventRules</code> modules.</p>
  2892. <h1 id="upgrading-to-v1210"><a class="header" href="#upgrading-to-v1210">Upgrading to v1.21.0</a></h1>
  2893. <h2 id="forwarding-_synapseclient-through-your-reverse-proxy"><a class="header" href="#forwarding-_synapseclient-through-your-reverse-proxy">Forwarding <code>/_synapse/client</code> through your reverse proxy</a></h2>
  2894. <p>The <a href="reverse_proxy.html">reverse proxy documentation</a>
  2895. has been updated to include reverse proxy directives for
  2896. <code>/_synapse/client/*</code> endpoints. As the user password reset flow now uses
  2897. endpoints under this prefix, <strong>you must update your reverse proxy
  2898. configurations for user password reset to work</strong>.</p>
  2899. <p>Additionally, note that the <a href="workers.html">Synapse worker documentation</a> has been updated to</p>
  2900. <p>: state that the <code>/_synapse/client/password_reset/email/submit_token</code>
  2901. endpoint can be handled</p>
  2902. <p>by all workers. If you make use of Synapse's worker feature, please
  2903. update your reverse proxy configuration to reflect this change.</p>
  2904. <h2 id="new-html-templates"><a class="header" href="#new-html-templates">New HTML templates</a></h2>
  2905. <p>A new HTML template,
  2906. <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/res/templates/password_reset_confirmation.html">password_reset_confirmation.html</a>,
  2907. has been added to the <code>synapse/res/templates</code> directory. If you are
  2908. using a custom template directory, you may want to copy the template
  2909. over and modify it.</p>
  2910. <p>Note that as of v1.20.0, templates do not need to be included in custom
  2911. template directories for Synapse to start. The default templates will be
  2912. used if a custom template cannot be found.</p>
  2913. <p>This page will appear to the user after clicking a password reset link
  2914. that has been emailed to them.</p>
  2915. <p>To complete password reset, the page must include a way to make a
  2916. <code>POST</code> request to
  2917. <code>/_synapse/client/password_reset/{medium}/submit_token</code> with the query
  2918. parameters from the original link, presented as a URL-encoded form. See
  2919. the file itself for more details.</p>
  2920. <h2 id="updated-single-sign-on-html-templates"><a class="header" href="#updated-single-sign-on-html-templates">Updated Single Sign-on HTML Templates</a></h2>
  2921. <p>The <code>saml_error.html</code> template was removed from Synapse and replaced
  2922. with the <code>sso_error.html</code> template. If your Synapse is configured to use
  2923. SAML and a custom <code>sso_redirect_confirm_template_dir</code> configuration then
  2924. any customisations of the <code>saml_error.html</code> template will need to be
  2925. merged into the <code>sso_error.html</code> template. These templates are similar,
  2926. but the parameters are slightly different:</p>
  2927. <ul>
  2928. <li>The <code>msg</code> parameter should be renamed to <code>error_description</code>.</li>
  2929. <li>There is no longer a <code>code</code> parameter for the response code.</li>
  2930. <li>A string <code>error</code> parameter is available that includes a short hint
  2931. of why a user is seeing the error page.</li>
  2932. </ul>
  2933. <h1 id="upgrading-to-v1180"><a class="header" href="#upgrading-to-v1180">Upgrading to v1.18.0</a></h1>
  2934. <h2 id="docker--py3-suffix-will-be-removed-in-future-versions"><a class="header" href="#docker--py3-suffix-will-be-removed-in-future-versions">Docker <code>-py3</code> suffix will be removed in future versions</a></h2>
  2935. <p>From 10th August 2020, we will no longer publish Docker images with the
  2936. <code>-py3</code> tag suffix. The images tagged with the
  2937. <code>-py3</code> suffix have been identical to the non-suffixed tags
  2938. since release 0.99.0, and the suffix is obsolete.</p>
  2939. <p>On 10th August, we will remove the <code>latest-py3</code> tag.
  2940. Existing per-release tags (such as <code>v1.18.0-py3</code> will not
  2941. be removed, but no new <code>-py3</code> tags will be added.</p>
  2942. <p>Scripts relying on the <code>-py3</code> suffix will need to be
  2943. updated.</p>
  2944. <h2 id="redis-replication-is-now-recommended-in-lieu-of-tcp-replication"><a class="header" href="#redis-replication-is-now-recommended-in-lieu-of-tcp-replication">Redis replication is now recommended in lieu of TCP replication</a></h2>
  2945. <p>When setting up worker processes, we now recommend the use of a Redis
  2946. server for replication. <strong>The old direct TCP connection method is
  2947. deprecated and will be removed in a future release.</strong> See
  2948. the <a href="https://matrix-org.github.io/synapse/v1.66/workers.html">worker documentation</a> for more details.</p>
  2949. <h1 id="upgrading-to-v1140"><a class="header" href="#upgrading-to-v1140">Upgrading to v1.14.0</a></h1>
  2950. <p>This version includes a database update which is run as part of the
  2951. upgrade, and which may take a couple of minutes in the case of a large
  2952. server. Synapse will not respond to HTTP requests while this update is
  2953. taking place.</p>
  2954. <h1 id="upgrading-to-v1130"><a class="header" href="#upgrading-to-v1130">Upgrading to v1.13.0</a></h1>
  2955. <h2 id="incorrect-database-migration-in-old-synapse-versions"><a class="header" href="#incorrect-database-migration-in-old-synapse-versions">Incorrect database migration in old synapse versions</a></h2>
  2956. <p>A bug was introduced in Synapse 1.4.0 which could cause the room
  2957. directory to be incomplete or empty if Synapse was upgraded directly
  2958. from v1.2.1 or earlier, to versions between v1.4.0 and v1.12.x.</p>
  2959. <p>This will <em>not</em> be a problem for Synapse installations which were:</p>
  2960. <p>: - created at v1.4.0 or later,
  2961. - upgraded via v1.3.x, or
  2962. - upgraded straight from v1.2.1 or earlier to v1.13.0 or later.</p>
  2963. <p>If completeness of the room directory is a concern, installations which
  2964. are affected can be repaired as follows:</p>
  2965. <ol>
  2966. <li>
  2967. <p>Run the following sql from a <code>psql</code> or
  2968. <code>sqlite3</code> console:</p>
  2969. <pre><code class="language-sql">INSERT INTO background_updates (update_name, progress_json, depends_on) VALUES
  2970. ('populate_stats_process_rooms', '{}', 'current_state_events_membership');
  2971. INSERT INTO background_updates (update_name, progress_json, depends_on) VALUES
  2972. ('populate_stats_process_users', '{}', 'populate_stats_process_rooms');
  2973. </code></pre>
  2974. </li>
  2975. <li>
  2976. <p>Restart synapse.</p>
  2977. </li>
  2978. </ol>
  2979. <h2 id="new-single-sign-on-html-templates"><a class="header" href="#new-single-sign-on-html-templates">New Single Sign-on HTML Templates</a></h2>
  2980. <p>New templates (<code>sso_auth_confirm.html</code>, <code>sso_auth_success.html</code>, and
  2981. <code>sso_account_deactivated.html</code>) were added to Synapse. If your Synapse
  2982. is configured to use SSO and a custom
  2983. <code>sso_redirect_confirm_template_dir</code> configuration then these templates
  2984. will need to be copied from
  2985. <a href="https://github.com/matrix-org/synapse/tree/develop/synapse/res/templates"><code>synapse/res/templates</code></a> into that directory.</p>
  2986. <h2 id="synapse-sso-plugins-method-deprecation"><a class="header" href="#synapse-sso-plugins-method-deprecation">Synapse SSO Plugins Method Deprecation</a></h2>
  2987. <p>Plugins using the <code>complete_sso_login</code> method of
  2988. <code>synapse.module_api.ModuleApi</code> should update to using the async/await
  2989. version <code>complete_sso_login_async</code> which includes additional checks. The
  2990. non-async version is considered deprecated.</p>
  2991. <h2 id="rolling-back-to-v1124-after-a-failed-upgrade"><a class="header" href="#rolling-back-to-v1124-after-a-failed-upgrade">Rolling back to v1.12.4 after a failed upgrade</a></h2>
  2992. <p>v1.13.0 includes a lot of large changes. If something problematic
  2993. occurs, you may want to roll-back to a previous version of Synapse.
  2994. Because v1.13.0 also includes a new database schema version, reverting
  2995. that version is also required alongside the generic rollback
  2996. instructions mentioned above. In short, to roll back to v1.12.4 you need
  2997. to:</p>
  2998. <ol>
  2999. <li>
  3000. <p>Stop the server</p>
  3001. </li>
  3002. <li>
  3003. <p>Decrease the schema version in the database:</p>
  3004. <pre><code class="language-sql">UPDATE schema_version SET version = 57;
  3005. </code></pre>
  3006. </li>
  3007. <li>
  3008. <p>Downgrade Synapse by following the instructions for your
  3009. installation method in the &quot;Rolling back to older versions&quot;
  3010. section above.</p>
  3011. </li>
  3012. </ol>
  3013. <h1 id="upgrading-to-v1120"><a class="header" href="#upgrading-to-v1120">Upgrading to v1.12.0</a></h1>
  3014. <p>This version includes a database update which is run as part of the
  3015. upgrade, and which may take some time (several hours in the case of a
  3016. large server). Synapse will not respond to HTTP requests while this
  3017. update is taking place.</p>
  3018. <p>This is only likely to be a problem in the case of a server which is
  3019. participating in many rooms.</p>
  3020. <ol start="0">
  3021. <li>
  3022. <p>As with all upgrades, it is recommended that you have a recent
  3023. backup of your database which can be used for recovery in the event
  3024. of any problems.</p>
  3025. </li>
  3026. <li>
  3027. <p>As an initial check to see if you will be affected, you can try
  3028. running the following query from the <code>psql</code> or
  3029. <code>sqlite3</code> console. It is safe to run it while Synapse is
  3030. still running.</p>
  3031. <pre><code class="language-sql">SELECT MAX(q.v) FROM (
  3032. SELECT (
  3033. SELECT ej.json AS v
  3034. FROM state_events se INNER JOIN event_json ej USING (event_id)
  3035. WHERE se.room_id=rooms.room_id AND se.type='m.room.create' AND se.state_key=''
  3036. LIMIT 1
  3037. ) FROM rooms WHERE rooms.room_version IS NULL
  3038. ) q;
  3039. </code></pre>
  3040. <p>This query will take about the same amount of time as the upgrade
  3041. process: ie, if it takes 5 minutes, then it is likely that Synapse
  3042. will be unresponsive for 5 minutes during the upgrade.</p>
  3043. <p>If you consider an outage of this duration to be acceptable, no
  3044. further action is necessary and you can simply start Synapse 1.12.0.</p>
  3045. <p>If you would prefer to reduce the downtime, continue with the steps
  3046. below.</p>
  3047. </li>
  3048. <li>
  3049. <p>The easiest workaround for this issue is to manually create a new
  3050. index before upgrading. On PostgreSQL, his can be done as follows:</p>
  3051. <pre><code class="language-sql">CREATE INDEX CONCURRENTLY tmp_upgrade_1_12_0_index
  3052. ON state_events(room_id) WHERE type = 'm.room.create';
  3053. </code></pre>
  3054. <p>The above query may take some time, but is also safe to run while
  3055. Synapse is running.</p>
  3056. <p>We assume that no SQLite users have databases large enough to be
  3057. affected. If you <em>are</em> affected, you can run a similar query,
  3058. omitting the <code>CONCURRENTLY</code> keyword. Note however that this
  3059. operation may in itself cause Synapse to stop running for some time.
  3060. Synapse admins are reminded that <a href="postgres.html">SQLite is not recommended for use
  3061. outside a test environment</a>.</p>
  3062. </li>
  3063. <li>
  3064. <p>Once the index has been created, the <code>SELECT</code> query in step 1 above
  3065. should complete quickly. It is therefore safe to upgrade to Synapse
  3066. 1.12.0.</p>
  3067. </li>
  3068. <li>
  3069. <p>Once Synapse 1.12.0 has successfully started and is responding to
  3070. HTTP requests, the temporary index can be removed:</p>
  3071. <pre><code class="language-sql">DROP INDEX tmp_upgrade_1_12_0_index;
  3072. </code></pre>
  3073. </li>
  3074. </ol>
  3075. <h1 id="upgrading-to-v1100"><a class="header" href="#upgrading-to-v1100">Upgrading to v1.10.0</a></h1>
  3076. <p>Synapse will now log a warning on start up if used with a PostgreSQL
  3077. database that has a non-recommended locale set.</p>
  3078. <p>See <a href="postgres.html">Postgres</a> for details.</p>
  3079. <h1 id="upgrading-to-v180"><a class="header" href="#upgrading-to-v180">Upgrading to v1.8.0</a></h1>
  3080. <p>Specifying a <code>log_file</code> config option will now cause Synapse to refuse
  3081. to start, and should be replaced by with the <code>log_config</code> option.
  3082. Support for the <code>log_file</code> option was removed in v1.3.0 and has since
  3083. had no effect.</p>
  3084. <h1 id="upgrading-to-v170"><a class="header" href="#upgrading-to-v170">Upgrading to v1.7.0</a></h1>
  3085. <p>In an attempt to configure Synapse in a privacy preserving way, the
  3086. default behaviours of <code>allow_public_rooms_without_auth</code> and
  3087. <code>allow_public_rooms_over_federation</code> have been inverted. This means that
  3088. by default, only authenticated users querying the Client/Server API will
  3089. be able to query the room directory, and relatedly that the server will
  3090. not share room directory information with other servers over federation.</p>
  3091. <p>If your installation does not explicitly set these settings one way or
  3092. the other and you want either setting to be <code>true</code> then it will
  3093. necessary to update your homeserver configuration file accordingly.</p>
  3094. <p>For more details on the surrounding context see our
  3095. <a href="https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers">explainer</a>.</p>
  3096. <h1 id="upgrading-to-v150"><a class="header" href="#upgrading-to-v150">Upgrading to v1.5.0</a></h1>
  3097. <p>This release includes a database migration which may take several
  3098. minutes to complete if there are a large number (more than a million or
  3099. so) of entries in the <code>devices</code> table. This is only likely to a be a
  3100. problem on very large installations.</p>
  3101. <h1 id="upgrading-to-v140"><a class="header" href="#upgrading-to-v140">Upgrading to v1.4.0</a></h1>
  3102. <h2 id="new-custom-templates"><a class="header" href="#new-custom-templates">New custom templates</a></h2>
  3103. <p>If you have configured a custom template directory with the
  3104. <code>email.template_dir</code> option, be aware that there are new templates
  3105. regarding registration and threepid management (see below) that must be
  3106. included.</p>
  3107. <ul>
  3108. <li><code>registration.html</code> and <code>registration.txt</code></li>
  3109. <li><code>registration_success.html</code> and <code>registration_failure.html</code></li>
  3110. <li><code>add_threepid.html</code> and <code>add_threepid.txt</code></li>
  3111. <li><code>add_threepid_failure.html</code> and <code>add_threepid_success.html</code></li>
  3112. </ul>
  3113. <p>Synapse will expect these files to exist inside the configured template
  3114. directory, and <strong>will fail to start</strong> if they are absent. To view the
  3115. default templates, see
  3116. <a href="https://github.com/matrix-org/synapse/tree/master/synapse/res/templates">synapse/res/templates</a>.</p>
  3117. <h2 id="3pid-verification-changes"><a class="header" href="#3pid-verification-changes">3pid verification changes</a></h2>
  3118. <p><strong>Note: As of this release, users will be unable to add phone numbers or
  3119. email addresses to their accounts, without changes to the Synapse
  3120. configuration. This includes adding an email address during
  3121. registration.</strong></p>
  3122. <p>It is possible for a user to associate an email address or phone number
  3123. with their account, for a number of reasons:</p>
  3124. <ul>
  3125. <li>for use when logging in, as an alternative to the user id.</li>
  3126. <li>in the case of email, as an alternative contact to help with account
  3127. recovery.</li>
  3128. <li>in the case of email, to receive notifications of missed messages.</li>
  3129. </ul>
  3130. <p>Before an email address or phone number can be added to a user's
  3131. account, or before such an address is used to carry out a
  3132. password-reset, Synapse must confirm the operation with the owner of the
  3133. email address or phone number. It does this by sending an email or text
  3134. giving the user a link or token to confirm receipt. This process is
  3135. known as '3pid verification'. ('3pid', or 'threepid', stands for
  3136. third-party identifier, and we use it to refer to external identifiers
  3137. such as email addresses and phone numbers.)</p>
  3138. <p>Previous versions of Synapse delegated the task of 3pid verification to
  3139. an identity server by default. In most cases this server is <code>vector.im</code>
  3140. or <code>matrix.org</code>.</p>
  3141. <p>In Synapse 1.4.0, for security and privacy reasons, the homeserver will
  3142. no longer delegate this task to an identity server by default. Instead,
  3143. the server administrator will need to explicitly decide how they would
  3144. like the verification messages to be sent.</p>
  3145. <p>In the medium term, the <code>vector.im</code> and <code>matrix.org</code> identity servers
  3146. will disable support for delegated 3pid verification entirely. However,
  3147. in order to ease the transition, they will retain the capability for a
  3148. limited period. Delegated email verification will be disabled on Monday
  3149. 2nd December 2019 (giving roughly 2 months notice). Disabling delegated
  3150. SMS verification will follow some time after that once SMS verification
  3151. support lands in Synapse.</p>
  3152. <p>Once delegated 3pid verification support has been disabled in the
  3153. <code>vector.im</code> and <code>matrix.org</code> identity servers, all Synapse versions that
  3154. depend on those instances will be unable to verify email and phone
  3155. numbers through them. There are no imminent plans to remove delegated
  3156. 3pid verification from Sydent generally. (Sydent is the identity server
  3157. project that backs the <code>vector.im</code> and <code>matrix.org</code> instances).</p>
  3158. <h3 id="email-1"><a class="header" href="#email-1">Email</a></h3>
  3159. <p>Following upgrade, to continue verifying email (e.g. as part of the
  3160. registration process), admins can either:-</p>
  3161. <ul>
  3162. <li>Configure Synapse to use an email server.</li>
  3163. <li>Run or choose an identity server which allows delegated email
  3164. verification and delegate to it.</li>
  3165. </ul>
  3166. <h4 id="configure-smtp-in-synapse"><a class="header" href="#configure-smtp-in-synapse">Configure SMTP in Synapse</a></h4>
  3167. <p>To configure an SMTP server for Synapse, modify the configuration
  3168. section headed <code>email</code>, and be sure to have at least the
  3169. <code>smtp_host, smtp_port</code> and <code>notif_from</code> fields filled out.</p>
  3170. <p>You may also need to set <code>smtp_user</code>, <code>smtp_pass</code>, and
  3171. <code>require_transport_security</code>.</p>
  3172. <p>See the <a href="usage/configuration/homeserver_sample_config.html">sample configuration file</a>
  3173. for more details on these settings.</p>
  3174. <h4 id="delegate-email-to-an-identity-server"><a class="header" href="#delegate-email-to-an-identity-server">Delegate email to an identity server</a></h4>
  3175. <p>Some admins will wish to continue using email verification as part of
  3176. the registration process, but will not immediately have an appropriate
  3177. SMTP server at hand.</p>
  3178. <p>To this end, we will continue to support email verification delegation
  3179. via the <code>vector.im</code> and <code>matrix.org</code> identity servers for two months.
  3180. Support for delegated email verification will be disabled on Monday 2nd
  3181. December.</p>
  3182. <p>The <code>account_threepid_delegates</code> dictionary defines whether the
  3183. homeserver should delegate an external server (typically an <a href="https://matrix.org/docs/spec/identity_service/r0.2.1">identity
  3184. server</a>) to handle
  3185. sending confirmation messages via email and SMS.</p>
  3186. <p>So to delegate email verification, in <code>homeserver.yaml</code>, set
  3187. <code>account_threepid_delegates.email</code> to the base URL of an identity
  3188. server. For example:</p>
  3189. <pre><code class="language-yaml">account_threepid_delegates:
  3190. email: https://example.com # Delegate email sending to example.com
  3191. </code></pre>
  3192. <p>Note that <code>account_threepid_delegates.email</code> replaces the deprecated
  3193. <code>email.trust_identity_server_for_password_resets</code>: if
  3194. <code>email.trust_identity_server_for_password_resets</code> is set to <code>true</code>, and
  3195. <code>account_threepid_delegates.email</code> is not set, then the first entry in
  3196. <code>trusted_third_party_id_servers</code> will be used as the
  3197. <code>account_threepid_delegate</code> for email. This is to ensure compatibility
  3198. with existing Synapse installs that set up external server handling for
  3199. these tasks before v1.4.0. If
  3200. <code>email.trust_identity_server_for_password_resets</code> is <code>true</code> and no
  3201. trusted identity server domains are configured, Synapse will report an
  3202. error and refuse to start.</p>
  3203. <p>If <code>email.trust_identity_server_for_password_resets</code> is <code>false</code> or
  3204. absent and no <code>email</code> delegate is configured in
  3205. <code>account_threepid_delegates</code>, then Synapse will send email verification
  3206. messages itself, using the configured SMTP server (see above). that
  3207. type.</p>
  3208. <h3 id="phone-numbers"><a class="header" href="#phone-numbers">Phone numbers</a></h3>
  3209. <p>Synapse does not support phone-number verification itself, so the only
  3210. way to maintain the ability for users to add phone numbers to their
  3211. accounts will be by continuing to delegate phone number verification to
  3212. the <code>matrix.org</code> and <code>vector.im</code> identity servers (or another identity
  3213. server that supports SMS sending).</p>
  3214. <p>The <code>account_threepid_delegates</code> dictionary defines whether the
  3215. homeserver should delegate an external server (typically an <a href="https://matrix.org/docs/spec/identity_service/r0.2.1">identity
  3216. server</a>) to handle
  3217. sending confirmation messages via email and SMS.</p>
  3218. <p>So to delegate phone number verification, in <code>homeserver.yaml</code>, set
  3219. <code>account_threepid_delegates.msisdn</code> to the base URL of an identity
  3220. server. For example:</p>
  3221. <pre><code class="language-yaml">account_threepid_delegates:
  3222. msisdn: https://example.com # Delegate sms sending to example.com
  3223. </code></pre>
  3224. <p>The <code>matrix.org</code> and <code>vector.im</code> identity servers will continue to
  3225. support delegated phone number verification via SMS until such time as
  3226. it is possible for admins to configure their servers to perform phone
  3227. number verification directly. More details will follow in a future
  3228. release.</p>
  3229. <h2 id="rolling-back-to-v131"><a class="header" href="#rolling-back-to-v131">Rolling back to v1.3.1</a></h2>
  3230. <p>If you encounter problems with v1.4.0, it should be possible to roll
  3231. back to v1.3.1, subject to the following:</p>
  3232. <ul>
  3233. <li>
  3234. <p>The 'room statistics' engine was heavily reworked in this release
  3235. (see <a href="https://github.com/matrix-org/synapse/pull/5971">#5971</a>),
  3236. including significant changes to the database schema, which are not
  3237. easily reverted. This will cause the room statistics engine to stop
  3238. updating when you downgrade.</p>
  3239. <p>The room statistics are essentially unused in v1.3.1 (in future
  3240. versions of Synapse, they will be used to populate the room
  3241. directory), so there should be no loss of functionality. However,
  3242. the statistics engine will write errors to the logs, which can be
  3243. avoided by setting the following in <code>homeserver.yaml</code>:</p>
  3244. <pre><code class="language-yaml">stats:
  3245. enabled: false
  3246. </code></pre>
  3247. <p>Don't forget to re-enable it when you upgrade again, in preparation
  3248. for its use in the room directory!</p>
  3249. </li>
  3250. </ul>
  3251. <h1 id="upgrading-to-v120"><a class="header" href="#upgrading-to-v120">Upgrading to v1.2.0</a></h1>
  3252. <p>Some counter metrics have been renamed, with the old names deprecated.
  3253. See <a href="metrics-howto.html#renaming-of-metrics--deprecation-of-old-names-in-12">the metrics
  3254. documentation</a>
  3255. for details.</p>
  3256. <h1 id="upgrading-to-v110"><a class="header" href="#upgrading-to-v110">Upgrading to v1.1.0</a></h1>
  3257. <p>Synapse v1.1.0 removes support for older Python and PostgreSQL versions,
  3258. as outlined in <a href="https://matrix.org/blog/2019/04/08/synapse-deprecating-postgres-9-4-and-python-2-x">our deprecation
  3259. notice</a>.</p>
  3260. <h2 id="minimum-python-version"><a class="header" href="#minimum-python-version">Minimum Python Version</a></h2>
  3261. <p>Synapse v1.1.0 has a minimum Python requirement of Python 3.5. Python
  3262. 3.6 or Python 3.7 are recommended as they have improved internal string
  3263. handling, significantly reducing memory usage.</p>
  3264. <p>If you use current versions of the Matrix.org-distributed Debian
  3265. packages or Docker images, action is not required.</p>
  3266. <p>If you install Synapse in a Python virtual environment, please see
  3267. &quot;Upgrading to v0.34.0&quot; for notes on setting up a new virtualenv under
  3268. Python 3.</p>
  3269. <h2 id="minimum-postgresql-version"><a class="header" href="#minimum-postgresql-version">Minimum PostgreSQL Version</a></h2>
  3270. <p>If using PostgreSQL under Synapse, you will need to use PostgreSQL 9.5
  3271. or above. Please see the <a href="https://www.postgresql.org/docs/11/upgrading.html">PostgreSQL
  3272. documentation</a> for
  3273. more details on upgrading your database.</p>
  3274. <h1 id="upgrading-to-v10"><a class="header" href="#upgrading-to-v10">Upgrading to v1.0</a></h1>
  3275. <h2 id="validation-of-tls-certificates"><a class="header" href="#validation-of-tls-certificates">Validation of TLS certificates</a></h2>
  3276. <p>Synapse v1.0 is the first release to enforce validation of TLS
  3277. certificates for the federation API. It is therefore essential that your
  3278. certificates are correctly configured.</p>
  3279. <p>Note, v1.0 installations will also no longer be able to federate with
  3280. servers that have not correctly configured their certificates.</p>
  3281. <p>In rare cases, it may be desirable to disable certificate checking: for
  3282. example, it might be essential to be able to federate with a given
  3283. legacy server in a closed federation. This can be done in one of two
  3284. ways:-</p>
  3285. <ul>
  3286. <li>Configure the global switch <code>federation_verify_certificates</code> to
  3287. <code>false</code>.</li>
  3288. <li>Configure a whitelist of server domains to trust via
  3289. <code>federation_certificate_verification_whitelist</code>.</li>
  3290. </ul>
  3291. <p>See the <a href="usage/configuration/homeserver_sample_config.html">sample configuration file</a>
  3292. for more details on these settings.</p>
  3293. <h2 id="email-2"><a class="header" href="#email-2">Email</a></h2>
  3294. <p>When a user requests a password reset, Synapse will send an email to the
  3295. user to confirm the request.</p>
  3296. <p>Previous versions of Synapse delegated the job of sending this email to
  3297. an identity server. If the identity server was somehow malicious or
  3298. became compromised, it would be theoretically possible to hijack an
  3299. account through this means.</p>
  3300. <p>Therefore, by default, Synapse v1.0 will send the confirmation email
  3301. itself. If Synapse is not configured with an SMTP server, password reset
  3302. via email will be disabled.</p>
  3303. <p>To configure an SMTP server for Synapse, modify the configuration
  3304. section headed <code>email</code>, and be sure to have at least the <code>smtp_host</code>,
  3305. <code>smtp_port</code> and <code>notif_from</code> fields filled out. You may also need to set
  3306. <code>smtp_user</code>, <code>smtp_pass</code>, and <code>require_transport_security</code>.</p>
  3307. <p>If you are absolutely certain that you wish to continue using an
  3308. identity server for password resets, set
  3309. <code>trust_identity_server_for_password_resets</code> to <code>true</code>.</p>
  3310. <p>See the <a href="usage/configuration/homeserver_sample_config.html">sample configuration file</a>
  3311. for more details on these settings.</p>
  3312. <h2 id="new-email-templates"><a class="header" href="#new-email-templates">New email templates</a></h2>
  3313. <p>Some new templates have been added to the default template directory for the purpose of
  3314. the homeserver sending its own password reset emails. If you have configured a
  3315. custom <code>template_dir</code> in your Synapse config, these files will need to be added.</p>
  3316. <p><code>password_reset.html</code> and <code>password_reset.txt</code> are HTML and plain text
  3317. templates respectively that contain the contents of what will be emailed
  3318. to the user upon attempting to reset their password via email.
  3319. <code>password_reset_success.html</code> and <code>password_reset_failure.html</code> are HTML
  3320. files that the content of which (assuming no redirect URL is set) will
  3321. be shown to the user after they attempt to click the link in the email
  3322. sent to them.</p>
  3323. <h1 id="upgrading-to-v0990"><a class="header" href="#upgrading-to-v0990">Upgrading to v0.99.0</a></h1>
  3324. <p>Please be aware that, before Synapse v1.0 is released around March 2019,
  3325. you will need to replace any self-signed certificates with those
  3326. verified by a root CA. Information on how to do so can be found at the
  3327. ACME docs.</p>
  3328. <h1 id="upgrading-to-v0340"><a class="header" href="#upgrading-to-v0340">Upgrading to v0.34.0</a></h1>
  3329. <ol>
  3330. <li>
  3331. <p>This release is the first to fully support Python 3. Synapse will
  3332. now run on Python versions 3.5, or 3.6 (as well as 2.7). We
  3333. recommend switching to Python 3, as it has been shown to give
  3334. performance improvements.</p>
  3335. <p>For users who have installed Synapse into a virtualenv, we recommend
  3336. doing this by creating a new virtualenv. For example:</p>
  3337. <pre><code class="language-sh">virtualenv -p python3 ~/synapse/env3
  3338. source ~/synapse/env3/bin/activate
  3339. pip install matrix-synapse
  3340. </code></pre>
  3341. <p>You can then start synapse as normal, having activated the new
  3342. virtualenv:</p>
  3343. <pre><code class="language-sh">cd ~/synapse
  3344. source env3/bin/activate
  3345. synctl start
  3346. </code></pre>
  3347. <p>Users who have installed from distribution packages should see the
  3348. relevant package documentation. See below for notes on Debian
  3349. packages.</p>
  3350. <ul>
  3351. <li>
  3352. <p>When upgrading to Python 3, you <strong>must</strong> make sure that your log
  3353. files are configured as UTF-8, by adding <code>encoding: utf8</code> to the
  3354. <code>RotatingFileHandler</code> configuration (if you have one) in your
  3355. <code>&lt;server&gt;.log.config</code> file. For example, if your <code>log.config</code>
  3356. file contains:</p>
  3357. <pre><code class="language-yaml">handlers:
  3358. file:
  3359. class: logging.handlers.RotatingFileHandler
  3360. formatter: precise
  3361. filename: homeserver.log
  3362. maxBytes: 104857600
  3363. backupCount: 10
  3364. filters: [context]
  3365. console:
  3366. class: logging.StreamHandler
  3367. formatter: precise
  3368. filters: [context]
  3369. </code></pre>
  3370. <p>Then you should update this to be:</p>
  3371. <pre><code class="language-yaml">handlers:
  3372. file:
  3373. class: logging.handlers.RotatingFileHandler
  3374. formatter: precise
  3375. filename: homeserver.log
  3376. maxBytes: 104857600
  3377. backupCount: 10
  3378. filters: [context]
  3379. encoding: utf8
  3380. console:
  3381. class: logging.StreamHandler
  3382. formatter: precise
  3383. filters: [context]
  3384. </code></pre>
  3385. <p>There is no need to revert this change if downgrading to
  3386. Python 2.</p>
  3387. </li>
  3388. </ul>
  3389. <p>We are also making available Debian packages which will run Synapse
  3390. on Python 3. You can switch to these packages with
  3391. <code>apt-get install matrix-synapse-py3</code>, however, please read
  3392. <a href="https://github.com/matrix-org/synapse/blob/release-v0.34.0/debian/NEWS">debian/NEWS</a>
  3393. before doing so. The existing <code>matrix-synapse</code> packages will
  3394. continue to use Python 2 for the time being.</p>
  3395. </li>
  3396. <li>
  3397. <p>This release removes the <code>riot.im</code> from the default list of trusted
  3398. identity servers.</p>
  3399. <p>If <code>riot.im</code> is in your homeserver's list of
  3400. <code>trusted_third_party_id_servers</code>, you should remove it. It was added
  3401. in case a hypothetical future identity server was put there. If you
  3402. don't remove it, users may be unable to deactivate their accounts.</p>
  3403. </li>
  3404. <li>
  3405. <p>This release no longer installs the (unmaintained) Matrix Console
  3406. web client as part of the default installation. It is possible to
  3407. re-enable it by installing it separately and setting the
  3408. <code>web_client_location</code> config option, but please consider switching
  3409. to another client.</p>
  3410. </li>
  3411. </ol>
  3412. <h1 id="upgrading-to-v0337"><a class="header" href="#upgrading-to-v0337">Upgrading to v0.33.7</a></h1>
  3413. <p>This release removes the example email notification templates from
  3414. <code>res/templates</code> (they are now internal to the python package). This
  3415. should only affect you if you (a) deploy your Synapse instance from a
  3416. git checkout or a github snapshot URL, and (b) have email notifications
  3417. enabled.</p>
  3418. <p>If you have email notifications enabled, you should ensure that
  3419. <code>email.template_dir</code> is either configured to point at a directory where
  3420. you have installed customised templates, or leave it unset to use the
  3421. default templates.</p>
  3422. <h1 id="upgrading-to-v0273"><a class="header" href="#upgrading-to-v0273">Upgrading to v0.27.3</a></h1>
  3423. <p>This release expands the anonymous usage stats sent if the opt-in
  3424. <code>report_stats</code> configuration is set to <code>true</code>. We now capture RSS memory
  3425. and cpu use at a very coarse level. This requires administrators to
  3426. install the optional <code>psutil</code> python module.</p>
  3427. <p>We would appreciate it if you could assist by ensuring this module is
  3428. available and <code>report_stats</code> is enabled. This will let us see if
  3429. performance changes to synapse are having an impact to the general
  3430. community.</p>
  3431. <h1 id="upgrading-to-v0150"><a class="header" href="#upgrading-to-v0150">Upgrading to v0.15.0</a></h1>
  3432. <p>If you want to use the new URL previewing API
  3433. (<code>/_matrix/media/r0/preview_url</code>) then you have to explicitly enable it
  3434. in the config and update your dependencies dependencies. See README.rst
  3435. for details.</p>
  3436. <h1 id="upgrading-to-v0110"><a class="header" href="#upgrading-to-v0110">Upgrading to v0.11.0</a></h1>
  3437. <p>This release includes the option to send anonymous usage stats to
  3438. matrix.org, and requires that administrators explicitly opt in or out by
  3439. setting the <code>report_stats</code> option to either <code>true</code> or <code>false</code>.</p>
  3440. <p>We would really appreciate it if you could help our project out by
  3441. reporting anonymized usage statistics from your homeserver. Only very
  3442. basic aggregate data (e.g. number of users) will be reported, but it
  3443. helps us to track the growth of the Matrix community, and helps us to
  3444. make Matrix a success, as well as to convince other networks that they
  3445. should peer with us.</p>
  3446. <h1 id="upgrading-to-v090"><a class="header" href="#upgrading-to-v090">Upgrading to v0.9.0</a></h1>
  3447. <p>Application services have had a breaking API change in this version.</p>
  3448. <p>They can no longer register themselves with a home server using the AS
  3449. HTTP API. This decision was made because a compromised application
  3450. service with free reign to register any regex in effect grants full
  3451. read/write access to the home server if a regex of <code>.*</code> is used. An
  3452. attack where a compromised AS re-registers itself with <code>.*</code> was deemed
  3453. too big of a security risk to ignore, and so the ability to register
  3454. with the HS remotely has been removed.</p>
  3455. <p>It has been replaced by specifying a list of application service
  3456. registrations in <code>homeserver.yaml</code>:</p>
  3457. <pre><code class="language-yaml">app_service_config_files: [&quot;registration-01.yaml&quot;, &quot;registration-02.yaml&quot;]
  3458. </code></pre>
  3459. <p>Where <code>registration-01.yaml</code> looks like:</p>
  3460. <pre><code class="language-yaml">url: &lt;String&gt; # e.g. &quot;https://my.application.service.com&quot;
  3461. as_token: &lt;String&gt;
  3462. hs_token: &lt;String&gt;
  3463. sender_localpart: &lt;String&gt; # This is a new field which denotes the user_id localpart when using the AS token
  3464. namespaces:
  3465. users:
  3466. - exclusive: &lt;Boolean&gt;
  3467. regex: &lt;String&gt; # e.g. &quot;@prefix_.*&quot;
  3468. aliases:
  3469. - exclusive: &lt;Boolean&gt;
  3470. regex: &lt;String&gt;
  3471. rooms:
  3472. - exclusive: &lt;Boolean&gt;
  3473. regex: &lt;String&gt;
  3474. </code></pre>
  3475. <h1 id="upgrading-to-v080"><a class="header" href="#upgrading-to-v080">Upgrading to v0.8.0</a></h1>
  3476. <p>Servers which use captchas will need to add their public key to:</p>
  3477. <pre><code>static/client/register/register_config.js
  3478. window.matrixRegistrationConfig = {
  3479. recaptcha_public_key: &quot;YOUR_PUBLIC_KEY&quot;
  3480. };
  3481. </code></pre>
  3482. <p>This is required in order to support registration fallback (typically
  3483. used on mobile devices).</p>
  3484. <h1 id="upgrading-to-v070"><a class="header" href="#upgrading-to-v070">Upgrading to v0.7.0</a></h1>
  3485. <p>New dependencies are:</p>
  3486. <ul>
  3487. <li>pydenticon</li>
  3488. <li>simplejson</li>
  3489. <li>syutil</li>
  3490. <li>matrix-angular-sdk</li>
  3491. </ul>
  3492. <p>To pull in these dependencies in a virtual env, run:</p>
  3493. <pre><code>python synapse/python_dependencies.py | xargs -n 1 pip install
  3494. </code></pre>
  3495. <h1 id="upgrading-to-v060"><a class="header" href="#upgrading-to-v060">Upgrading to v0.6.0</a></h1>
  3496. <p>To pull in new dependencies, run:</p>
  3497. <pre><code>python setup.py develop --user
  3498. </code></pre>
  3499. <p>This update includes a change to the database schema. To upgrade you
  3500. first need to upgrade the database by running:</p>
  3501. <pre><code>python scripts/upgrade_db_to_v0.6.0.py &lt;db&gt; &lt;server_name&gt; &lt;signing_key&gt;
  3502. </code></pre>
  3503. <p>Where <code>&lt;db&gt;</code> is the location of the database,
  3504. <code>&lt;server_name&gt;</code> is the server name as specified in the
  3505. synapse configuration, and <code>&lt;signing_key&gt;</code> is the location
  3506. of the signing key as specified in the synapse configuration.</p>
  3507. <p>This may take some time to complete. Failures of signatures and content
  3508. hashes can safely be ignored.</p>
  3509. <h1 id="upgrading-to-v051"><a class="header" href="#upgrading-to-v051">Upgrading to v0.5.1</a></h1>
  3510. <p>Depending on precisely when you installed v0.5.0 you may have ended up
  3511. with a stale release of the reference matrix webclient installed as a
  3512. python module. To uninstall it and ensure you are depending on the
  3513. latest module, please run:</p>
  3514. <pre><code>$ pip uninstall syweb
  3515. </code></pre>
  3516. <h1 id="upgrading-to-v050"><a class="header" href="#upgrading-to-v050">Upgrading to v0.5.0</a></h1>
  3517. <p>The webclient has been split out into a separate repository/package in
  3518. this release. Before you restart your homeserver you will need to pull
  3519. in the webclient package by running:</p>
  3520. <pre><code>python setup.py develop --user
  3521. </code></pre>
  3522. <p>This release completely changes the database schema and so requires
  3523. upgrading it before starting the new version of the homeserver.</p>
  3524. <p>The script &quot;database-prepare-for-0.5.0.sh&quot; should be used to upgrade
  3525. the database. This will save all user information, such as logins and
  3526. profiles, but will otherwise purge the database. This includes messages,
  3527. which rooms the home server was a member of and room alias mappings.</p>
  3528. <p>If you would like to keep your history, please take a copy of your
  3529. database file and ask for help in #matrix:matrix.org. The upgrade
  3530. process is, unfortunately, non trivial and requires human intervention
  3531. to resolve any resulting conflicts during the upgrade process.</p>
  3532. <p>Before running the command the homeserver should be first completely
  3533. shutdown. To run it, simply specify the location of the database, e.g.:</p>
  3534. <blockquote>
  3535. <p>./scripts/database-prepare-for-0.5.0.sh &quot;homeserver.db&quot;</p>
  3536. </blockquote>
  3537. <p>Once this has successfully completed it will be safe to restart the
  3538. homeserver. You may notice that the homeserver takes a few seconds
  3539. longer to restart than usual as it reinitializes the database.</p>
  3540. <p>On startup of the new version, users can either rejoin remote rooms
  3541. using room aliases or by being reinvited. Alternatively, if any other
  3542. homeserver sends a message to a room that the homeserver was previously
  3543. in the local HS will automatically rejoin the room.</p>
  3544. <h1 id="upgrading-to-v040"><a class="header" href="#upgrading-to-v040">Upgrading to v0.4.0</a></h1>
  3545. <p>This release needs an updated syutil version. Run:</p>
  3546. <pre><code>python setup.py develop
  3547. </code></pre>
  3548. <p>You will also need to upgrade your configuration as the signing key
  3549. format has changed. Run:</p>
  3550. <pre><code>python -m synapse.app.homeserver --config-path &lt;CONFIG&gt; --generate-config
  3551. </code></pre>
  3552. <h1 id="upgrading-to-v030"><a class="header" href="#upgrading-to-v030">Upgrading to v0.3.0</a></h1>
  3553. <p>This registration API now closely matches the login API. This introduces
  3554. a bit more backwards and forwards between the HS and the client, but
  3555. this improves the overall flexibility of the API. You can now GET on
  3556. /register to retrieve a list of valid registration flows. Upon choosing
  3557. one, they are submitted in the same way as login, e.g:</p>
  3558. <pre><code>{
  3559. type: m.login.password,
  3560. user: foo,
  3561. password: bar
  3562. }
  3563. </code></pre>
  3564. <p>The default HS supports 2 flows, with and without Identity Server email
  3565. authentication. Enabling captcha on the HS will add in an extra step to
  3566. all flows: <code>m.login.recaptcha</code> which must be completed before you can
  3567. transition to the next stage. There is a new login type:
  3568. <code>m.login.email.identity</code> which contains the <code>threepidCreds</code> key which
  3569. were previously sent in the original register request. For more
  3570. information on this, see the specification.</p>
  3571. <h2 id="web-client"><a class="header" href="#web-client">Web Client</a></h2>
  3572. <p>The VoIP specification has changed between v0.2.0 and v0.3.0. Users
  3573. should refresh any browser tabs to get the latest web client code. Users
  3574. on v0.2.0 of the web client will not be able to call those on v0.3.0 and
  3575. vice versa.</p>
  3576. <h1 id="upgrading-to-v020"><a class="header" href="#upgrading-to-v020">Upgrading to v0.2.0</a></h1>
  3577. <p>The home server now requires setting up of SSL config before it can run.
  3578. To automatically generate default config use:</p>
  3579. <pre><code>$ python synapse/app/homeserver.py \
  3580. --server-name machine.my.domain.name \
  3581. --bind-port 8448 \
  3582. --config-path homeserver.config \
  3583. --generate-config
  3584. </code></pre>
  3585. <p>This config can be edited if desired, for example to specify a different
  3586. SSL certificate to use. Once done you can run the home server using:</p>
  3587. <pre><code>$ python synapse/app/homeserver.py --config-path homeserver.config
  3588. </code></pre>
  3589. <p>See the README.rst for more information.</p>
  3590. <p>Also note that some config options have been renamed, including:</p>
  3591. <ul>
  3592. <li>&quot;host&quot; to &quot;server-name&quot;</li>
  3593. <li>&quot;database&quot; to &quot;database-path&quot;</li>
  3594. <li>&quot;port&quot; to &quot;bind-port&quot; and &quot;unsecure-port&quot;</li>
  3595. </ul>
  3596. <h1 id="upgrading-to-v001"><a class="header" href="#upgrading-to-v001">Upgrading to v0.0.1</a></h1>
  3597. <p>This release completely changes the database schema and so requires
  3598. upgrading it before starting the new version of the homeserver.</p>
  3599. <p>The script &quot;database-prepare-for-0.0.1.sh&quot; should be used to upgrade
  3600. the database. This will save all user information, such as logins and
  3601. profiles, but will otherwise purge the database. This includes messages,
  3602. which rooms the home server was a member of and room alias mappings.</p>
  3603. <p>Before running the command the homeserver should be first completely
  3604. shutdown. To run it, simply specify the location of the database, e.g.:</p>
  3605. <blockquote>
  3606. <p>./scripts/database-prepare-for-0.0.1.sh &quot;homeserver.db&quot;</p>
  3607. </blockquote>
  3608. <p>Once this has successfully completed it will be safe to restart the
  3609. homeserver. You may notice that the homeserver takes a few seconds
  3610. longer to restart than usual as it reinitializes the database.</p>
  3611. <p>On startup of the new version, users can either rejoin remote rooms
  3612. using room aliases or by being reinvited. Alternatively, if any other
  3613. homeserver sends a message to a room that the homeserver was previously
  3614. in the local HS will automatically rejoin the room.</p>
  3615. <div style="break-before: page; page-break-before: always;"></div><h1 id="setting-up-federation"><a class="header" href="#setting-up-federation">Setting up federation</a></h1>
  3616. <p>Federation is the process by which users on different servers can participate
  3617. in the same room. For this to work, those other servers must be able to contact
  3618. yours to send messages.</p>
  3619. <p>The <code>server_name</code> configured in the Synapse configuration file (often
  3620. <code>homeserver.yaml</code>) defines how resources (users, rooms, etc.) will be
  3621. identified (eg: <code>@user:example.com</code>, <code>#room:example.com</code>). By default,
  3622. it is also the domain that other servers will use to try to reach your
  3623. server (via port 8448). This is easy to set up and will work provided
  3624. you set the <code>server_name</code> to match your machine's public DNS hostname.</p>
  3625. <p>For this default configuration to work, you will need to listen for TLS
  3626. connections on port 8448. The preferred way to do that is by using a
  3627. reverse proxy: see <a href="reverse_proxy.html">the reverse proxy documentation</a> for instructions
  3628. on how to correctly set one up.</p>
  3629. <p>In some cases you might not want to run Synapse on the machine that has
  3630. the <code>server_name</code> as its public DNS hostname, or you might want federation
  3631. traffic to use a different port than 8448. For example, you might want to
  3632. have your user names look like <code>@user:example.com</code>, but you want to run
  3633. Synapse on <code>synapse.example.com</code> on port 443. This can be done using
  3634. delegation, which allows an admin to control where federation traffic should
  3635. be sent. See <a href="delegate.html">the delegation documentation</a> for instructions on how to set this up.</p>
  3636. <p>Once federation has been configured, you should be able to join a room over
  3637. federation. A good place to start is <code>#synapse:matrix.org</code> - a room for
  3638. Synapse admins.</p>
  3639. <h2 id="troubleshooting-3"><a class="header" href="#troubleshooting-3">Troubleshooting</a></h2>
  3640. <p>You can use the <a href="https://matrix.org/federationtester">federation tester</a>
  3641. to check if your homeserver is configured correctly. Alternatively try the
  3642. <a href="https://matrix.org/federationtester/api/report?server_name=DOMAIN">JSON API used by the federation tester</a>.
  3643. Note that you'll have to modify this URL to replace <code>DOMAIN</code> with your
  3644. <code>server_name</code>. Hitting the API directly provides extra detail.</p>
  3645. <p>The typical failure mode for federation is that when the server tries to join
  3646. a room, it is rejected with &quot;401: Unauthorized&quot;. Generally this means that other
  3647. servers in the room could not access yours. (Joining a room over federation is
  3648. a complicated dance which requires connections in both directions).</p>
  3649. <p>Another common problem is that people on other servers can't join rooms that
  3650. you invite them to. This can be caused by an incorrectly-configured reverse
  3651. proxy: see <a href="reverse_proxy.html">the reverse proxy documentation</a> for instructions on how
  3652. to correctly configure a reverse proxy.</p>
  3653. <h3 id="known-issues"><a class="header" href="#known-issues">Known issues</a></h3>
  3654. <p><strong>HTTP <code>308 Permanent Redirect</code> redirects are not followed</strong>: Due to missing features
  3655. in the HTTP library used by Synapse, 308 redirects are currently not followed by
  3656. federating servers, which can cause <code>M_UNKNOWN</code> or <code>401 Unauthorized</code> errors. This
  3657. may affect users who are redirecting apex-to-www (e.g. <code>example.com</code> -&gt; <code>www.example.com</code>),
  3658. and especially users of the Kubernetes <em>Nginx Ingress</em> module, which uses 308 redirect
  3659. codes by default. For those Kubernetes users, <a href="https://stackoverflow.com/a/52617528/5096871">this Stackoverflow post</a>
  3660. might be helpful. For other users, switching to a <code>301 Moved Permanently</code> code may be
  3661. an option. 308 redirect codes will be supported properly in a future
  3662. release of Synapse.</p>
  3663. <h2 id="running-a-demo-federation-of-synapses"><a class="header" href="#running-a-demo-federation-of-synapses">Running a demo federation of Synapses</a></h2>
  3664. <p>If you want to get up and running quickly with a trio of homeservers in a
  3665. private federation, there is a script in the <code>demo</code> directory. This is mainly
  3666. useful just for development purposes. See
  3667. <a href="https://matrix-org.github.io/synapse/develop/development/demo.html">demo scripts</a>.</p>
  3668. <div style="break-before: page; page-break-before: always;"></div><h1 id="configuration-2"><a class="header" href="#configuration-2">Configuration</a></h1>
  3669. <p>This section contains information on tweaking Synapse via the various options in the configuration file. A configuration
  3670. file should have been generated when you <a href="usage/configuration/../../setup/installation.html">installed Synapse</a>.</p>
  3671. <div style="break-before: page; page-break-before: always;"></div><h1 id="configuring-synapse"><a class="header" href="#configuring-synapse">Configuring Synapse</a></h1>
  3672. <p>This is intended as a guide to the Synapse configuration. The behavior of a Synapse instance can be modified
  3673. through the many configuration settings documented here — each config option is explained,
  3674. including what the default is, how to change the default and what sort of behaviour the setting governs.
  3675. Also included is an example configuration for each setting. If you don't want to spend a lot of time
  3676. thinking about options, the config as generated sets sensible defaults for all values. Do note however that the
  3677. database defaults to SQLite, which is not recommended for production usage. You can read more on this subject
  3678. <a href="usage/configuration/../../setup/installation.html#using-postgresql">here</a>.</p>
  3679. <h2 id="config-conventions"><a class="header" href="#config-conventions">Config Conventions</a></h2>
  3680. <p>Configuration options that take a time period can be set using a number
  3681. followed by a letter. Letters have the following meanings:</p>
  3682. <ul>
  3683. <li><code>s</code> = second</li>
  3684. <li><code>m</code> = minute</li>
  3685. <li><code>h</code> = hour</li>
  3686. <li><code>d</code> = day</li>
  3687. <li><code>w</code> = week</li>
  3688. <li><code>y</code> = year</li>
  3689. </ul>
  3690. <p>For example, setting <code>redaction_retention_period: 5m</code> would remove redacted
  3691. messages from the database after 5 minutes, rather than 5 months.</p>
  3692. <p>In addition, configuration options referring to size use the following suffixes:</p>
  3693. <ul>
  3694. <li><code>K</code> = KiB, or 1024 bytes</li>
  3695. <li><code>M</code> = MiB, or 1,048,576 bytes</li>
  3696. <li><code>G</code> = GiB, or 1,073,741,824 bytes</li>
  3697. <li><code>T</code> = TiB, or 1,099,511,627,776 bytes</li>
  3698. </ul>
  3699. <p>For example, setting <code>max_avatar_size: 10M</code> means that Synapse will not accept files larger than 10,485,760 bytes
  3700. for a user avatar.</p>
  3701. <h2 id="config-validation"><a class="header" href="#config-validation">Config Validation</a></h2>
  3702. <p>The configuration file can be validated with the following command:</p>
  3703. <pre><code class="language-bash">python -m synapse.config read &lt;config key to print&gt; -c &lt;path to config&gt;
  3704. </code></pre>
  3705. <p>To validate the entire file, omit <code>read &lt;config key to print&gt;</code>:</p>
  3706. <pre><code class="language-bash">python -m synapse.config -c &lt;path to config&gt;
  3707. </code></pre>
  3708. <p>To see how to set other options, check the help reference:</p>
  3709. <pre><code class="language-bash">python -m synapse.config --help
  3710. </code></pre>
  3711. <h3 id="yaml"><a class="header" href="#yaml">YAML</a></h3>
  3712. <p>The configuration file is a <a href="https://yaml.org/">YAML</a> file, which means that certain syntax rules
  3713. apply if you want your config file to be read properly. A few helpful things to know:</p>
  3714. <ul>
  3715. <li>
  3716. <p><code>#</code> before any option in the config will comment out that setting and either a default (if available) will
  3717. be applied or Synapse will ignore the setting. Thus, in example #1 below, the setting will be read and
  3718. applied, but in example #2 the setting will not be read and a default will be applied.</p>
  3719. <p>Example #1:</p>
  3720. <pre><code class="language-yaml">pid_file: DATADIR/homeserver.pid
  3721. </code></pre>
  3722. <p>Example #2:</p>
  3723. <pre><code class="language-yaml">#pid_file: DATADIR/homeserver.pid
  3724. </code></pre>
  3725. </li>
  3726. <li>
  3727. <p>Indentation matters! The indentation before a setting
  3728. will determine whether a given setting is read as part of another
  3729. setting, or considered on its own. Thus, in example #1, the <code>enabled</code> setting
  3730. is read as a sub-option of the <code>presence</code> setting, and will be properly applied.</p>
  3731. <p>However, the lack of indentation before the <code>enabled</code> setting in example #2 means
  3732. that when reading the config, Synapse will consider both <code>presence</code> and <code>enabled</code> as
  3733. different settings. In this case, <code>presence</code> has no value, and thus a default applied, and <code>enabled</code>
  3734. is an option that Synapse doesn't recognize and thus ignores.</p>
  3735. <p>Example #1:</p>
  3736. <pre><code class="language-yaml">presence:
  3737. enabled: false
  3738. </code></pre>
  3739. <p>Example #2:</p>
  3740. <pre><code class="language-yaml">presence:
  3741. enabled: false
  3742. </code></pre>
  3743. <p>In this manual, all top-level settings (ones with no indentation) are identified
  3744. at the beginning of their section (i.e. &quot;### <code>example_setting</code>&quot;) and
  3745. the sub-options, if any, are identified and listed in the body of the section.
  3746. In addition, each setting has an example of its usage, with the proper indentation
  3747. shown.</p>
  3748. </li>
  3749. </ul>
  3750. <h2 id="modules"><a class="header" href="#modules">Modules</a></h2>
  3751. <p>Server admins can expand Synapse's functionality with external modules.</p>
  3752. <p>See <a href="usage/configuration/../../modules/index.html">here</a> for more
  3753. documentation on how to configure or create custom modules for Synapse.</p>
  3754. <hr />
  3755. <h3 id="modules-1"><a class="header" href="#modules-1"><code>modules</code></a></h3>
  3756. <p>Use the <code>module</code> sub-option to add modules under this option to extend functionality.
  3757. The <code>module</code> setting then has a sub-option, <code>config</code>, which can be used to define some configuration
  3758. for the <code>module</code>.</p>
  3759. <p>Defaults to none.</p>
  3760. <p>Example configuration:</p>
  3761. <pre><code class="language-yaml">modules:
  3762. - module: my_super_module.MySuperClass
  3763. config:
  3764. do_thing: true
  3765. - module: my_other_super_module.SomeClass
  3766. config: {}
  3767. </code></pre>
  3768. <hr />
  3769. <h2 id="server"><a class="header" href="#server">Server</a></h2>
  3770. <p>Define your homeserver name and other base options.</p>
  3771. <hr />
  3772. <h3 id="server_name"><a class="header" href="#server_name"><code>server_name</code></a></h3>
  3773. <p>This sets the public-facing domain of the server.</p>
  3774. <p>The <code>server_name</code> name will appear at the end of usernames and room addresses
  3775. created on your server. For example if the <code>server_name</code> was example.com,
  3776. usernames on your server would be in the format <code>@user:example.com</code></p>
  3777. <p>In most cases you should avoid using a matrix specific subdomain such as
  3778. matrix.example.com or synapse.example.com as the <code>server_name</code> for the same
  3779. reasons you wouldn't use user@email.example.com as your email address.
  3780. See <a href="usage/configuration/../../delegate.html">here</a>
  3781. for information on how to host Synapse on a subdomain while preserving
  3782. a clean <code>server_name</code>.</p>
  3783. <p>The <code>server_name</code> cannot be changed later so it is important to
  3784. configure this correctly before you start Synapse. It should be all
  3785. lowercase and may contain an explicit port.</p>
  3786. <p>There is no default for this option.</p>
  3787. <p>Example configuration #1:</p>
  3788. <pre><code class="language-yaml">server_name: matrix.org
  3789. </code></pre>
  3790. <p>Example configuration #2:</p>
  3791. <pre><code class="language-yaml">server_name: localhost:8080
  3792. </code></pre>
  3793. <hr />
  3794. <h3 id="pid_file"><a class="header" href="#pid_file"><code>pid_file</code></a></h3>
  3795. <p>When running Synapse as a daemon, the file to store the pid in. Defaults to none.</p>
  3796. <p>Example configuration:</p>
  3797. <pre><code class="language-yaml">pid_file: DATADIR/homeserver.pid
  3798. </code></pre>
  3799. <hr />
  3800. <h3 id="web_client_location"><a class="header" href="#web_client_location"><code>web_client_location</code></a></h3>
  3801. <p>The absolute URL to the web client which <code>/</code> will redirect to. Defaults to none.</p>
  3802. <p>Example configuration:</p>
  3803. <pre><code class="language-yaml">web_client_location: https://riot.example.com/
  3804. </code></pre>
  3805. <hr />
  3806. <h3 id="public_baseurl"><a class="header" href="#public_baseurl"><code>public_baseurl</code></a></h3>
  3807. <p>The public-facing base URL that clients use to access this Homeserver (not
  3808. including _matrix/...). This is the same URL a user might enter into the
  3809. 'Custom Homeserver URL' field on their client. If you use Synapse with a
  3810. reverse proxy, this should be the URL to reach Synapse via the proxy.
  3811. Otherwise, it should be the URL to reach Synapse's client HTTP listener (see
  3812. <a href="usage/configuration/config_documentation.html#listeners">'listeners'</a> below).</p>
  3813. <p>Defaults to <code>https://&lt;server_name&gt;/</code>.</p>
  3814. <p>Example configuration:</p>
  3815. <pre><code class="language-yaml">public_baseurl: https://example.com/
  3816. </code></pre>
  3817. <hr />
  3818. <h3 id="serve_server_wellknown"><a class="header" href="#serve_server_wellknown"><code>serve_server_wellknown</code></a></h3>
  3819. <p>By default, other servers will try to reach our server on port 8448, which can
  3820. be inconvenient in some environments.</p>
  3821. <p>Provided <code>https://&lt;server_name&gt;/</code> on port 443 is routed to Synapse, this
  3822. option configures Synapse to serve a file at <code>https://&lt;server_name&gt;/.well-known/matrix/server</code>.
  3823. This will tell other servers to send traffic to port 443 instead.</p>
  3824. <p>This option currently defaults to false.</p>
  3825. <p>See <a href="usage/configuration/../../delegate.html">Delegation of incoming federation traffic</a> for more
  3826. information.</p>
  3827. <p>Example configuration:</p>
  3828. <pre><code class="language-yaml">serve_server_wellknown: true
  3829. </code></pre>
  3830. <hr />
  3831. <h3 id="extra_well_known_client_content"><a class="header" href="#extra_well_known_client_content"><code>extra_well_known_client_content </code></a></h3>
  3832. <p>This option allows server runners to add arbitrary key-value pairs to the <a href="https://spec.matrix.org/latest/client-server-api/#well-known-uri">client-facing <code>.well-known</code> response</a>.
  3833. Note that the <code>public_baseurl</code> config option must be provided for Synapse to serve a response to <code>/.well-known/matrix/client</code> at all.</p>
  3834. <p>If this option is provided, it parses the given yaml to json and
  3835. serves it on <code>/.well-known/matrix/client</code> endpoint
  3836. alongside the standard properties.</p>
  3837. <p><em>Added in Synapse 1.62.0.</em></p>
  3838. <p>Example configuration:</p>
  3839. <pre><code class="language-yaml">extra_well_known_client_content :
  3840. option1: value1
  3841. option2: value2
  3842. </code></pre>
  3843. <hr />
  3844. <h3 id="soft_file_limit"><a class="header" href="#soft_file_limit"><code>soft_file_limit</code></a></h3>
  3845. <p>Set the soft limit on the number of file descriptors synapse can use.
  3846. Zero is used to indicate synapse should set the soft limit to the hard limit.
  3847. Defaults to 0.</p>
  3848. <p>Example configuration:</p>
  3849. <pre><code class="language-yaml">soft_file_limit: 3
  3850. </code></pre>
  3851. <hr />
  3852. <h3 id="presence"><a class="header" href="#presence"><code>presence</code></a></h3>
  3853. <p>Presence tracking allows users to see the state (e.g online/offline)
  3854. of other local and remote users. Set the <code>enabled</code> sub-option to false to
  3855. disable presence tracking on this homeserver. Defaults to true.
  3856. This option replaces the previous top-level 'use_presence' option.</p>
  3857. <p>Example configuration:</p>
  3858. <pre><code class="language-yaml">presence:
  3859. enabled: false
  3860. </code></pre>
  3861. <p><code>enabled</code> can also be set to a special value of &quot;untracked&quot; which ignores updates
  3862. received via clients and federation, while still accepting updates from the
  3863. <a href="usage/configuration/../../modules/index.html">module API</a>.</p>
  3864. <p><em>The &quot;untracked&quot; option was added in Synapse 1.96.0.</em></p>
  3865. <hr />
  3866. <h3 id="require_auth_for_profile_requests"><a class="header" href="#require_auth_for_profile_requests"><code>require_auth_for_profile_requests</code></a></h3>
  3867. <p>Whether to require authentication to retrieve profile data (avatars, display names) of other
  3868. users through the client API. Defaults to false. Note that profile data is also available
  3869. via the federation API, unless <code>allow_profile_lookup_over_federation</code> is set to false.</p>
  3870. <p>Example configuration:</p>
  3871. <pre><code class="language-yaml">require_auth_for_profile_requests: true
  3872. </code></pre>
  3873. <hr />
  3874. <h3 id="limit_profile_requests_to_users_who_share_rooms"><a class="header" href="#limit_profile_requests_to_users_who_share_rooms"><code>limit_profile_requests_to_users_who_share_rooms</code></a></h3>
  3875. <p>Use this option to require a user to share a room with another user in order
  3876. to retrieve their profile information. Only checked on Client-Server
  3877. requests. Profile requests from other servers should be checked by the
  3878. requesting server. Defaults to false.</p>
  3879. <p>Example configuration:</p>
  3880. <pre><code class="language-yaml">limit_profile_requests_to_users_who_share_rooms: true
  3881. </code></pre>
  3882. <hr />
  3883. <h3 id="include_profile_data_on_invite"><a class="header" href="#include_profile_data_on_invite"><code>include_profile_data_on_invite</code></a></h3>
  3884. <p>Use this option to prevent a user's profile data from being retrieved and
  3885. displayed in a room until they have joined it. By default, a user's
  3886. profile data is included in an invite event, regardless of the values
  3887. of the above two settings, and whether or not the users share a server.
  3888. Defaults to true.</p>
  3889. <p>Example configuration:</p>
  3890. <pre><code class="language-yaml">include_profile_data_on_invite: false
  3891. </code></pre>
  3892. <hr />
  3893. <h3 id="allow_public_rooms_without_auth"><a class="header" href="#allow_public_rooms_without_auth"><code>allow_public_rooms_without_auth</code></a></h3>
  3894. <p>If set to true, removes the need for authentication to access the server's
  3895. public rooms directory through the client API, meaning that anyone can
  3896. query the room directory. Defaults to false.</p>
  3897. <p>Example configuration:</p>
  3898. <pre><code class="language-yaml">allow_public_rooms_without_auth: true
  3899. </code></pre>
  3900. <hr />
  3901. <h3 id="allow_public_rooms_over_federation"><a class="header" href="#allow_public_rooms_over_federation"><code>allow_public_rooms_over_federation</code></a></h3>
  3902. <p>If set to true, allows any other homeserver to fetch the server's public
  3903. rooms directory via federation. Defaults to false.</p>
  3904. <p>Example configuration:</p>
  3905. <pre><code class="language-yaml">allow_public_rooms_over_federation: true
  3906. </code></pre>
  3907. <hr />
  3908. <h3 id="default_room_version"><a class="header" href="#default_room_version"><code>default_room_version</code></a></h3>
  3909. <p>The default room version for newly created rooms on this server.</p>
  3910. <p>Known room versions are listed <a href="https://spec.matrix.org/latest/rooms/#complete-list-of-room-versions">here</a></p>
  3911. <p>For example, for room version 1, <code>default_room_version</code> should be set
  3912. to &quot;1&quot;.</p>
  3913. <p>Currently defaults to <a href="https://spec.matrix.org/v1.5/rooms/v10/">&quot;10&quot;</a>.</p>
  3914. <p><em>Changed in Synapse 1.76:</em> the default version room version was increased from <a href="https://spec.matrix.org/v1.5/rooms/v9/">9</a> to <a href="https://spec.matrix.org/v1.5/rooms/v10/">10</a>.</p>
  3915. <p>Example configuration:</p>
  3916. <pre><code class="language-yaml">default_room_version: &quot;8&quot;
  3917. </code></pre>
  3918. <hr />
  3919. <h3 id="gc_thresholds"><a class="header" href="#gc_thresholds"><code>gc_thresholds</code></a></h3>
  3920. <p>The garbage collection threshold parameters to pass to <code>gc.set_threshold</code>, if defined.
  3921. Defaults to none.</p>
  3922. <p>Example configuration:</p>
  3923. <pre><code class="language-yaml">gc_thresholds: [700, 10, 10]
  3924. </code></pre>
  3925. <hr />
  3926. <h3 id="gc_min_interval"><a class="header" href="#gc_min_interval"><code>gc_min_interval</code></a></h3>
  3927. <p>The minimum time in seconds between each GC for a generation, regardless of
  3928. the GC thresholds. This ensures that we don't do GC too frequently. A value of <code>[1s, 10s, 30s]</code>
  3929. indicates that a second must pass between consecutive generation 0 GCs, etc.</p>
  3930. <p>Defaults to <code>[1s, 10s, 30s]</code>.</p>
  3931. <p>Example configuration:</p>
  3932. <pre><code class="language-yaml">gc_min_interval: [0.5s, 30s, 1m]
  3933. </code></pre>
  3934. <hr />
  3935. <h3 id="filter_timeline_limit"><a class="header" href="#filter_timeline_limit"><code>filter_timeline_limit</code></a></h3>
  3936. <p>Set the limit on the returned events in the timeline in the get
  3937. and sync operations. Defaults to 100. A value of -1 means no upper limit.</p>
  3938. <p>Example configuration:</p>
  3939. <pre><code class="language-yaml">filter_timeline_limit: 5000
  3940. </code></pre>
  3941. <hr />
  3942. <h3 id="block_non_admin_invites"><a class="header" href="#block_non_admin_invites"><code>block_non_admin_invites</code></a></h3>
  3943. <p>Whether room invites to users on this server should be blocked
  3944. (except those sent by local server admins). Defaults to false.</p>
  3945. <p>Example configuration:</p>
  3946. <pre><code class="language-yaml">block_non_admin_invites: true
  3947. </code></pre>
  3948. <hr />
  3949. <h3 id="enable_search"><a class="header" href="#enable_search"><code>enable_search</code></a></h3>
  3950. <p>If set to false, new messages will not be indexed for searching and users
  3951. will receive errors when searching for messages. Defaults to true.</p>
  3952. <p>Example configuration:</p>
  3953. <pre><code class="language-yaml">enable_search: false
  3954. </code></pre>
  3955. <hr />
  3956. <h3 id="ip_range_blacklist"><a class="header" href="#ip_range_blacklist"><code>ip_range_blacklist</code></a></h3>
  3957. <p>This option prevents outgoing requests from being sent to the specified blacklisted IP address
  3958. CIDR ranges. If this option is not specified then it defaults to private IP
  3959. address ranges (see the example below).</p>
  3960. <p>The blacklist applies to the outbound requests for federation, identity servers,
  3961. push servers, and for checking key validity for third-party invite events.</p>
  3962. <p>(0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
  3963. listed here, since they correspond to unroutable addresses.)</p>
  3964. <p>This option replaces <code>federation_ip_range_blacklist</code> in Synapse v1.25.0.</p>
  3965. <p>Note: The value is ignored when an HTTP proxy is in use.</p>
  3966. <p>Example configuration:</p>
  3967. <pre><code class="language-yaml">ip_range_blacklist:
  3968. - '127.0.0.0/8'
  3969. - '10.0.0.0/8'
  3970. - '172.16.0.0/12'
  3971. - '192.168.0.0/16'
  3972. - '100.64.0.0/10'
  3973. - '192.0.0.0/24'
  3974. - '169.254.0.0/16'
  3975. - '192.88.99.0/24'
  3976. - '198.18.0.0/15'
  3977. - '192.0.2.0/24'
  3978. - '198.51.100.0/24'
  3979. - '203.0.113.0/24'
  3980. - '224.0.0.0/4'
  3981. - '::1/128'
  3982. - 'fe80::/10'
  3983. - 'fc00::/7'
  3984. - '2001:db8::/32'
  3985. - 'ff00::/8'
  3986. - 'fec0::/10'
  3987. </code></pre>
  3988. <hr />
  3989. <h3 id="ip_range_whitelist"><a class="header" href="#ip_range_whitelist"><code>ip_range_whitelist</code></a></h3>
  3990. <p>List of IP address CIDR ranges that should be allowed for federation,
  3991. identity servers, push servers, and for checking key validity for
  3992. third-party invite events. This is useful for specifying exceptions to
  3993. wide-ranging blacklisted target IP ranges - e.g. for communication with
  3994. a push server only visible in your network.</p>
  3995. <p>This whitelist overrides <code>ip_range_blacklist</code> and defaults to an empty
  3996. list.</p>
  3997. <p>Example configuration:</p>
  3998. <pre><code class="language-yaml">ip_range_whitelist:
  3999. - '192.168.1.1'
  4000. </code></pre>
  4001. <hr />
  4002. <h3 id="listeners"><a class="header" href="#listeners"><code>listeners</code></a></h3>
  4003. <p>List of ports that Synapse should listen on, their purpose and their
  4004. configuration.</p>
  4005. <p>Sub-options for each listener include:</p>
  4006. <ul>
  4007. <li>
  4008. <p><code>port</code>: the TCP port to bind to.</p>
  4009. </li>
  4010. <li>
  4011. <p><code>tag</code>: An alias for the port in the logger name. If set the tag is logged instead
  4012. of the port. Default to <code>None</code>, is optional and only valid for listener with <code>type: http</code>.
  4013. See the docs <a href="usage/configuration/../administration/request_log.html">request log format</a>.</p>
  4014. </li>
  4015. <li>
  4016. <p><code>bind_addresses</code>: a list of local addresses to listen on. The default is
  4017. 'all local interfaces'.</p>
  4018. </li>
  4019. <li>
  4020. <p><code>type</code>: the type of listener. Normally <code>http</code>, but other valid options are:</p>
  4021. <ul>
  4022. <li>
  4023. <p><code>manhole</code>: (see the docs <a href="usage/configuration/../../manhole.html">here</a>),</p>
  4024. </li>
  4025. <li>
  4026. <p><code>metrics</code>: (see the docs <a href="usage/configuration/../../metrics-howto.html">here</a>),</p>
  4027. </li>
  4028. </ul>
  4029. </li>
  4030. <li>
  4031. <p><code>tls</code>: set to true to enable TLS for this listener. Will use the TLS key/cert specified in tls_private_key_path / tls_certificate_path.</p>
  4032. </li>
  4033. <li>
  4034. <p><code>x_forwarded</code>: Only valid for an 'http' listener. Set to true to use the X-Forwarded-For header as the client IP. Useful when Synapse is
  4035. behind a <a href="usage/configuration/../../reverse_proxy.html">reverse-proxy</a>.</p>
  4036. </li>
  4037. <li>
  4038. <p><code>request_id_header</code>: The header extracted from each incoming request that is
  4039. used as the basis for the request ID. The request ID is used in
  4040. <a href="usage/configuration/../administration/request_log.html#request-log-format">logs</a> and tracing to
  4041. correlate and match up requests. When unset, Synapse will automatically
  4042. generate sequential request IDs. This option is useful when Synapse is behind
  4043. a <a href="usage/configuration/../../reverse_proxy.html">reverse-proxy</a>.</p>
  4044. <p><em>Added in Synapse 1.68.0.</em></p>
  4045. </li>
  4046. <li>
  4047. <p><code>resources</code>: Only valid for an 'http' listener. A list of resources to host
  4048. on this port. Sub-options for each resource are:</p>
  4049. <ul>
  4050. <li>
  4051. <p><code>names</code>: a list of names of HTTP resources. See below for a list of valid resource names.</p>
  4052. </li>
  4053. <li>
  4054. <p><code>compress</code>: set to true to enable gzip compression on HTTP bodies for this resource. This is currently only supported with the
  4055. <code>client</code>, <code>consent</code>, <code>metrics</code> and <code>federation</code> resources.</p>
  4056. </li>
  4057. </ul>
  4058. </li>
  4059. <li>
  4060. <p><code>additional_resources</code>: Only valid for an 'http' listener. A map of
  4061. additional endpoints which should be loaded via dynamic modules.</p>
  4062. </li>
  4063. </ul>
  4064. <p>Unix socket support (<em>Added in Synapse 1.89.0</em>):</p>
  4065. <ul>
  4066. <li><code>path</code>: A path and filename for a Unix socket. Make sure it is located in a
  4067. directory with read and write permissions, and that it already exists (the directory
  4068. will not be created). Defaults to <code>None</code>.
  4069. <ul>
  4070. <li><strong>Note</strong>: The use of both <code>path</code> and <code>port</code> options for the same <code>listener</code> is not
  4071. compatible.</li>
  4072. <li>The <code>x_forwarded</code> option defaults to true when using Unix sockets and can be omitted.</li>
  4073. <li>Other options that would not make sense to use with a UNIX socket, such as
  4074. <code>bind_addresses</code> and <code>tls</code> will be ignored and can be removed.</li>
  4075. </ul>
  4076. </li>
  4077. <li><code>mode</code>: The file permissions to set on the UNIX socket. Defaults to <code>666</code></li>
  4078. <li><strong>Note:</strong> Must be set as <code>type: http</code> (does not support <code>metrics</code> and <code>manhole</code>).
  4079. Also make sure that <code>metrics</code> is not included in <code>resources</code> -&gt; <code>names</code></li>
  4080. </ul>
  4081. <p>Valid resource names are:</p>
  4082. <ul>
  4083. <li>
  4084. <p><code>client</code>: the client-server API (/_matrix/client), and the synapse admin API (/_synapse/admin). Also implies <code>media</code> and <code>static</code>.</p>
  4085. </li>
  4086. <li>
  4087. <p><code>consent</code>: user consent forms (/_matrix/consent). See <a href="usage/configuration/../../consent_tracking.html">here</a> for more.</p>
  4088. </li>
  4089. <li>
  4090. <p><code>federation</code>: the server-server API (/_matrix/federation). Also implies <code>media</code>, <code>keys</code>, <code>openid</code></p>
  4091. </li>
  4092. <li>
  4093. <p><code>keys</code>: the key discovery API (/_matrix/key).</p>
  4094. </li>
  4095. <li>
  4096. <p><code>media</code>: the media API (/_matrix/media).</p>
  4097. </li>
  4098. <li>
  4099. <p><code>metrics</code>: the metrics interface. See <a href="usage/configuration/../../metrics-howto.html">here</a>. (Not compatible with Unix sockets)</p>
  4100. </li>
  4101. <li>
  4102. <p><code>openid</code>: OpenID authentication. See <a href="usage/configuration/../../openid.html">here</a>.</p>
  4103. </li>
  4104. <li>
  4105. <p><code>replication</code>: the HTTP replication API (/_synapse/replication). See <a href="usage/configuration/../../workers.html">here</a>.</p>
  4106. </li>
  4107. <li>
  4108. <p><code>static</code>: static resources under synapse/static (/_matrix/static). (Mostly useful for 'fallback authentication'.)</p>
  4109. </li>
  4110. <li>
  4111. <p><code>health</code>: the <a href="usage/configuration/../../reverse_proxy.html#health-check-endpoint">health check endpoint</a>. This endpoint
  4112. is by default active for all other resources and does not have to be activated separately.
  4113. This is only useful if you want to use the health endpoint explicitly on a dedicated port or
  4114. for <a href="usage/configuration/../../workers.html">workers</a> and containers without listener e.g.
  4115. <a href="usage/configuration/../../workers.html#notifying-application-services">application services</a>.</p>
  4116. </li>
  4117. </ul>
  4118. <p>Example configuration #1:</p>
  4119. <pre><code class="language-yaml">listeners:
  4120. # TLS-enabled listener: for when matrix traffic is sent directly to synapse.
  4121. #
  4122. # (Note that you will also need to give Synapse a TLS key and certificate: see the TLS section
  4123. # below.)
  4124. #
  4125. - port: 8448
  4126. type: http
  4127. tls: true
  4128. resources:
  4129. - names: [client, federation]
  4130. </code></pre>
  4131. <p>Example configuration #2:</p>
  4132. <pre><code class="language-yaml">listeners:
  4133. # Insecure HTTP listener: for when matrix traffic passes through a reverse proxy
  4134. # that unwraps TLS.
  4135. #
  4136. # If you plan to use a reverse proxy, please see
  4137. # https://matrix-org.github.io/synapse/latest/reverse_proxy.html.
  4138. #
  4139. - port: 8008
  4140. tls: false
  4141. type: http
  4142. x_forwarded: true
  4143. bind_addresses: ['::1', '127.0.0.1']
  4144. resources:
  4145. - names: [client, federation]
  4146. compress: false
  4147. # example additional_resources:
  4148. additional_resources:
  4149. &quot;/_matrix/my/custom/endpoint&quot;:
  4150. module: my_module.CustomRequestHandler
  4151. config: {}
  4152. # Turn on the twisted ssh manhole service on localhost on the given
  4153. # port.
  4154. - port: 9000
  4155. bind_addresses: ['::1', '127.0.0.1']
  4156. type: manhole
  4157. </code></pre>
  4158. <p>Example configuration #3:</p>
  4159. <pre><code class="language-yaml">listeners:
  4160. # Unix socket listener: Ideal for Synapse deployments behind a reverse proxy, offering
  4161. # lightweight interprocess communication without TCP/IP overhead, avoid port
  4162. # conflicts, and providing enhanced security through system file permissions.
  4163. #
  4164. # Note that x_forwarded will default to true, when using a UNIX socket. Please see
  4165. # https://matrix-org.github.io/synapse/latest/reverse_proxy.html.
  4166. #
  4167. - path: /run/synapse/main_public.sock
  4168. type: http
  4169. resources:
  4170. - names: [client, federation]
  4171. </code></pre>
  4172. <hr />
  4173. <h3 id="manhole_settings"><a class="header" href="#manhole_settings"><code>manhole_settings</code></a></h3>
  4174. <p>Connection settings for the manhole. You can find more information
  4175. on the manhole <a href="usage/configuration/../../manhole.html">here</a>. Manhole sub-options include:</p>
  4176. <ul>
  4177. <li><code>username</code> : the username for the manhole. This defaults to 'matrix'.</li>
  4178. <li><code>password</code>: The password for the manhole. This defaults to 'rabbithole'.</li>
  4179. <li><code>ssh_priv_key_path</code> and <code>ssh_pub_key_path</code>: The private and public SSH key pair used to encrypt the manhole traffic.
  4180. If these are left unset, then hardcoded and non-secret keys are used,
  4181. which could allow traffic to be intercepted if sent over a public network.</li>
  4182. </ul>
  4183. <p>Example configuration:</p>
  4184. <pre><code class="language-yaml">manhole_settings:
  4185. username: manhole
  4186. password: mypassword
  4187. ssh_priv_key_path: CONFDIR/id_rsa
  4188. ssh_pub_key_path: CONFDIR/id_rsa.pub
  4189. </code></pre>
  4190. <hr />
  4191. <h3 id="dummy_events_threshold"><a class="header" href="#dummy_events_threshold"><code>dummy_events_threshold</code></a></h3>
  4192. <p>Forward extremities can build up in a room due to networking delays between
  4193. homeservers. Once this happens in a large room, calculation of the state of
  4194. that room can become quite expensive. To mitigate this, once the number of
  4195. forward extremities reaches a given threshold, Synapse will send an
  4196. <code>org.matrix.dummy_event</code> event, which will reduce the forward extremities
  4197. in the room.</p>
  4198. <p>This setting defines the threshold (i.e. number of forward extremities in the room) at which dummy events are sent.
  4199. The default value is 10.</p>
  4200. <p>Example configuration:</p>
  4201. <pre><code class="language-yaml">dummy_events_threshold: 5
  4202. </code></pre>
  4203. <hr />
  4204. <h3 id="delete_stale_devices_after"><a class="header" href="#delete_stale_devices_after"><code>delete_stale_devices_after</code></a></h3>
  4205. <p>An optional duration. If set, Synapse will run a daily background task to log out and
  4206. delete any device that hasn't been accessed for more than the specified amount of time.</p>
  4207. <p>Defaults to no duration, which means devices are never pruned.</p>
  4208. <p><strong>Note:</strong> This task will always run on the main process, regardless of the value of
  4209. <code>run_background_tasks_on</code>. This is due to workers currently not having the ability to
  4210. delete devices.</p>
  4211. <p>Example configuration:</p>
  4212. <pre><code class="language-yaml">delete_stale_devices_after: 1y
  4213. </code></pre>
  4214. <hr />
  4215. <h3 id="email-3"><a class="header" href="#email-3"><code>email</code></a></h3>
  4216. <p>Configuration for sending emails from Synapse.</p>
  4217. <p>Server admins can configure custom templates for email content. See
  4218. <a href="usage/configuration/../../templates.html">here</a> for more information.</p>
  4219. <p>This setting has the following sub-options:</p>
  4220. <ul>
  4221. <li>
  4222. <p><code>smtp_host</code>: The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.</p>
  4223. </li>
  4224. <li>
  4225. <p><code>smtp_port</code>: The port on the mail server for outgoing SMTP. Defaults to 465 if <code>force_tls</code> is true, else 25.</p>
  4226. <p><em>Changed in Synapse 1.64.0:</em> the default port is now aware of <code>force_tls</code>.</p>
  4227. </li>
  4228. <li>
  4229. <p><code>smtp_user</code> and <code>smtp_pass</code>: Username/password for authentication to the SMTP server. By default, no
  4230. authentication is attempted.</p>
  4231. </li>
  4232. <li>
  4233. <p><code>force_tls</code>: By default, Synapse connects over plain text and then optionally upgrades
  4234. to TLS via STARTTLS. If this option is set to true, TLS is used from the start (Implicit TLS),
  4235. and the option <code>require_transport_security</code> is ignored.
  4236. It is recommended to enable this if supported by your mail server.</p>
  4237. <p><em>New in Synapse 1.64.0.</em></p>
  4238. </li>
  4239. <li>
  4240. <p><code>require_transport_security</code>: Set to true to require TLS transport security for SMTP.
  4241. By default, Synapse will connect over plain text, and will then switch to
  4242. TLS via STARTTLS <em>if the SMTP server supports it</em>. If this option is set,
  4243. Synapse will refuse to connect unless the server supports STARTTLS.</p>
  4244. </li>
  4245. <li>
  4246. <p><code>enable_tls</code>: By default, if the server supports TLS, it will be used, and the server
  4247. must present a certificate that is valid for 'smtp_host'. If this option
  4248. is set to false, TLS will not be used.</p>
  4249. </li>
  4250. <li>
  4251. <p><code>notif_from</code>: defines the &quot;From&quot; address to use when sending emails.
  4252. It must be set if email sending is enabled. The placeholder '%(app)s' will be replaced by the application name,
  4253. which is normally set in <code>app_name</code>, but may be overridden by the
  4254. Matrix client application. Note that the placeholder must be written '%(app)s', including the
  4255. trailing 's'.</p>
  4256. </li>
  4257. <li>
  4258. <p><code>app_name</code>: <code>app_name</code> defines the default value for '%(app)s' in <code>notif_from</code> and email
  4259. subjects. It defaults to 'Matrix'.</p>
  4260. </li>
  4261. <li>
  4262. <p><code>enable_notifs</code>: Set to true to enable sending emails for messages that the user
  4263. has missed. Disabled by default.</p>
  4264. </li>
  4265. <li>
  4266. <p><code>notif_for_new_users</code>: Set to false to disable automatic subscription to email
  4267. notifications for new users. Enabled by default.</p>
  4268. </li>
  4269. <li>
  4270. <p><code>client_base_url</code>: Custom URL for client links within the email notifications. By default
  4271. links will be based on &quot;https://matrix.to&quot;. (This setting used to be called <code>riot_base_url</code>;
  4272. the old name is still supported for backwards-compatibility but is now deprecated.)</p>
  4273. </li>
  4274. <li>
  4275. <p><code>validation_token_lifetime</code>: Configures the time that a validation email will expire after sending.
  4276. Defaults to 1h.</p>
  4277. </li>
  4278. <li>
  4279. <p><code>invite_client_location</code>: The web client location to direct users to during an invite. This is passed
  4280. to the identity server as the <code>org.matrix.web_client_location</code> key. Defaults
  4281. to unset, giving no guidance to the identity server.</p>
  4282. </li>
  4283. <li>
  4284. <p><code>subjects</code>: Subjects to use when sending emails from Synapse. The placeholder '%(app)s' will
  4285. be replaced with the value of the <code>app_name</code> setting, or by a value dictated by the Matrix client application.
  4286. In addition, each subject can use the following placeholders: '%(person)s', which will be replaced by the displayname
  4287. of the user(s) that sent the message(s), e.g. &quot;Alice and Bob&quot;, and '%(room)s', which will be replaced by the name of the room the
  4288. message(s) have been sent to, e.g. &quot;My super room&quot;. In addition, emails related to account administration will
  4289. can use the '%(server_name)s' placeholder, which will be replaced by the value of the
  4290. <code>server_name</code> setting in your Synapse configuration.</p>
  4291. <p>Here is a list of subjects for notification emails that can be set:</p>
  4292. <ul>
  4293. <li><code>message_from_person_in_room</code>: Subject to use to notify about one message from one or more user(s) in a
  4294. room which has a name. Defaults to &quot;[%(app)s] You have a message on %(app)s from %(person)s in the %(room)s room...&quot;</li>
  4295. <li><code>message_from_person</code>: Subject to use to notify about one message from one or more user(s) in a
  4296. room which doesn't have a name. Defaults to &quot;[%(app)s] You have a message on %(app)s from %(person)s...&quot;</li>
  4297. <li><code>messages_from_person</code>: Subject to use to notify about multiple messages from one or more users in
  4298. a room which doesn't have a name. Defaults to &quot;[%(app)s] You have messages on %(app)s from %(person)s...&quot;</li>
  4299. <li><code>messages_in_room</code>: Subject to use to notify about multiple messages in a room which has a
  4300. name. Defaults to &quot;[%(app)s] You have messages on %(app)s in the %(room)s room...&quot;</li>
  4301. <li><code>messages_in_room_and_others</code>: Subject to use to notify about multiple messages in multiple rooms.
  4302. Defaults to &quot;[%(app)s] You have messages on %(app)s in the %(room)s room and others...&quot;</li>
  4303. <li><code>messages_from_person_and_others</code>: Subject to use to notify about multiple messages from multiple persons in
  4304. multiple rooms. This is similar to the setting above except it's used when
  4305. the room in which the notification was triggered has no name. Defaults to
  4306. &quot;[%(app)s] You have messages on %(app)s from %(person)s and others...&quot;</li>
  4307. <li><code>invite_from_person_to_room</code>: Subject to use to notify about an invite to a room which has a name.
  4308. Defaults to &quot;[%(app)s] %(person)s has invited you to join the %(room)s room on %(app)s...&quot;</li>
  4309. <li><code>invite_from_person</code>: Subject to use to notify about an invite to a room which doesn't have a
  4310. name. Defaults to &quot;[%(app)s] %(person)s has invited you to chat on %(app)s...&quot;</li>
  4311. <li><code>password_reset</code>: Subject to use when sending a password reset email. Defaults to &quot;[%(server_name)s] Password reset&quot;</li>
  4312. <li><code>email_validation</code>: Subject to use when sending a verification email to assert an address's
  4313. ownership. Defaults to &quot;[%(server_name)s] Validate your email&quot;</li>
  4314. </ul>
  4315. </li>
  4316. </ul>
  4317. <p>Example configuration:</p>
  4318. <pre><code class="language-yaml">email:
  4319. smtp_host: mail.server
  4320. smtp_port: 587
  4321. smtp_user: &quot;exampleusername&quot;
  4322. smtp_pass: &quot;examplepassword&quot;
  4323. force_tls: true
  4324. require_transport_security: true
  4325. enable_tls: false
  4326. notif_from: &quot;Your Friendly %(app)s homeserver &lt;noreply@example.com&gt;&quot;
  4327. app_name: my_branded_matrix_server
  4328. enable_notifs: true
  4329. notif_for_new_users: false
  4330. client_base_url: &quot;http://localhost/riot&quot;
  4331. validation_token_lifetime: 15m
  4332. invite_client_location: https://app.element.io
  4333. subjects:
  4334. message_from_person_in_room: &quot;[%(app)s] You have a message on %(app)s from %(person)s in the %(room)s room...&quot;
  4335. message_from_person: &quot;[%(app)s] You have a message on %(app)s from %(person)s...&quot;
  4336. messages_from_person: &quot;[%(app)s] You have messages on %(app)s from %(person)s...&quot;
  4337. messages_in_room: &quot;[%(app)s] You have messages on %(app)s in the %(room)s room...&quot;
  4338. messages_in_room_and_others: &quot;[%(app)s] You have messages on %(app)s in the %(room)s room and others...&quot;
  4339. messages_from_person_and_others: &quot;[%(app)s] You have messages on %(app)s from %(person)s and others...&quot;
  4340. invite_from_person_to_room: &quot;[%(app)s] %(person)s has invited you to join the %(room)s room on %(app)s...&quot;
  4341. invite_from_person: &quot;[%(app)s] %(person)s has invited you to chat on %(app)s...&quot;
  4342. password_reset: &quot;[%(server_name)s] Password reset&quot;
  4343. email_validation: &quot;[%(server_name)s] Validate your email&quot;
  4344. </code></pre>
  4345. <h2 id="homeserver-blocking"><a class="header" href="#homeserver-blocking">Homeserver blocking</a></h2>
  4346. <p>Useful options for Synapse admins.</p>
  4347. <hr />
  4348. <h3 id="admin_contact"><a class="header" href="#admin_contact"><code>admin_contact</code></a></h3>
  4349. <p>How to reach the server admin, used in <code>ResourceLimitError</code>. Defaults to none.</p>
  4350. <p>Example configuration:</p>
  4351. <pre><code class="language-yaml">admin_contact: 'mailto:admin@server.com'
  4352. </code></pre>
  4353. <hr />
  4354. <h3 id="hs_disabled-and-hs_disabled_message"><a class="header" href="#hs_disabled-and-hs_disabled_message"><code>hs_disabled</code> and <code>hs_disabled_message</code></a></h3>
  4355. <p>Blocks users from connecting to the homeserver and provides a human-readable reason
  4356. why the connection was blocked. Defaults to false.</p>
  4357. <p>Example configuration:</p>
  4358. <pre><code class="language-yaml">hs_disabled: true
  4359. hs_disabled_message: 'Reason for why the HS is blocked'
  4360. </code></pre>
  4361. <hr />
  4362. <h3 id="limit_usage_by_mau"><a class="header" href="#limit_usage_by_mau"><code>limit_usage_by_mau</code></a></h3>
  4363. <p>This option disables/enables monthly active user blocking. Used in cases where the admin or
  4364. server owner wants to limit to the number of monthly active users. When enabled and a limit is
  4365. reached the server returns a <code>ResourceLimitError</code> with error type <code>Codes.RESOURCE_LIMIT_EXCEEDED</code>.
  4366. Defaults to false. If this is enabled, a value for <code>max_mau_value</code> must also be set.</p>
  4367. <p>See <a href="usage/configuration/../administration/monthly_active_users.html">Monthly Active Users</a> for details on how to configure MAU.</p>
  4368. <p>Example configuration:</p>
  4369. <pre><code class="language-yaml">limit_usage_by_mau: true
  4370. </code></pre>
  4371. <hr />
  4372. <h3 id="max_mau_value"><a class="header" href="#max_mau_value"><code>max_mau_value</code></a></h3>
  4373. <p>This option sets the hard limit of monthly active users above which the server will start
  4374. blocking user actions if <code>limit_usage_by_mau</code> is enabled. Defaults to 0.</p>
  4375. <p>Example configuration:</p>
  4376. <pre><code class="language-yaml">max_mau_value: 50
  4377. </code></pre>
  4378. <hr />
  4379. <h3 id="mau_trial_days"><a class="header" href="#mau_trial_days"><code>mau_trial_days</code></a></h3>
  4380. <p>The option <code>mau_trial_days</code> is a means to add a grace period for active users. It
  4381. means that users must be active for the specified number of days before they
  4382. can be considered active and guards against the case where lots of users
  4383. sign up in a short space of time never to return after their initial
  4384. session. Defaults to 0.</p>
  4385. <p>Example configuration:</p>
  4386. <pre><code class="language-yaml">mau_trial_days: 5
  4387. </code></pre>
  4388. <hr />
  4389. <h3 id="mau_appservice_trial_days"><a class="header" href="#mau_appservice_trial_days"><code>mau_appservice_trial_days</code></a></h3>
  4390. <p>The option <code>mau_appservice_trial_days</code> is similar to <code>mau_trial_days</code>, but applies a different
  4391. trial number if the user was registered by an appservice. A value
  4392. of 0 means no trial days are applied. Appservices not listed in this dictionary
  4393. use the value of <code>mau_trial_days</code> instead.</p>
  4394. <p>Example configuration:</p>
  4395. <pre><code class="language-yaml">mau_appservice_trial_days:
  4396. my_appservice_id: 3
  4397. another_appservice_id: 6
  4398. </code></pre>
  4399. <hr />
  4400. <h3 id="mau_limit_alerting"><a class="header" href="#mau_limit_alerting"><code>mau_limit_alerting</code></a></h3>
  4401. <p>The option <code>mau_limit_alerting</code> is a means of limiting client-side alerting
  4402. should the mau limit be reached. This is useful for small instances
  4403. where the admin has 5 mau seats (say) for 5 specific people and no
  4404. interest increasing the mau limit further. Defaults to true, which
  4405. means that alerting is enabled.</p>
  4406. <p>Example configuration:</p>
  4407. <pre><code class="language-yaml">mau_limit_alerting: false
  4408. </code></pre>
  4409. <hr />
  4410. <h3 id="mau_stats_only"><a class="header" href="#mau_stats_only"><code>mau_stats_only</code></a></h3>
  4411. <p>If enabled, the metrics for the number of monthly active users will
  4412. be populated, however no one will be limited based on these numbers. If <code>limit_usage_by_mau</code>
  4413. is true, this is implied to be true. Defaults to false.</p>
  4414. <p>Example configuration:</p>
  4415. <pre><code class="language-yaml">mau_stats_only: true
  4416. </code></pre>
  4417. <hr />
  4418. <h3 id="mau_limit_reserved_threepids"><a class="header" href="#mau_limit_reserved_threepids"><code>mau_limit_reserved_threepids</code></a></h3>
  4419. <p>Sometimes the server admin will want to ensure certain accounts are
  4420. never blocked by mau checking. These accounts are specified by this option.
  4421. Defaults to none. Add accounts by specifying the <code>medium</code> and <code>address</code> of the
  4422. reserved threepid (3rd party identifier).</p>
  4423. <p>Example configuration:</p>
  4424. <pre><code class="language-yaml">mau_limit_reserved_threepids:
  4425. - medium: 'email'
  4426. address: 'reserved_user@example.com'
  4427. </code></pre>
  4428. <hr />
  4429. <h3 id="server_context"><a class="header" href="#server_context"><code>server_context</code></a></h3>
  4430. <p>This option is used by phonehome stats to group together related servers.
  4431. Defaults to none.</p>
  4432. <p>Example configuration:</p>
  4433. <pre><code class="language-yaml">server_context: context
  4434. </code></pre>
  4435. <hr />
  4436. <h3 id="limit_remote_rooms"><a class="header" href="#limit_remote_rooms"><code>limit_remote_rooms</code></a></h3>
  4437. <p>When this option is enabled, the room &quot;complexity&quot; will be checked before a user
  4438. joins a new remote room. If it is above the complexity limit, the server will
  4439. disallow joining, or will instantly leave. This is useful for homeservers that are
  4440. resource-constrained. Options for this setting include:</p>
  4441. <ul>
  4442. <li><code>enabled</code>: whether this check is enabled. Defaults to false.</li>
  4443. <li><code>complexity</code>: the limit above which rooms cannot be joined. The default is 1.0.</li>
  4444. <li><code>complexity_error</code>: override the error which is returned when the room is too complex with a
  4445. custom message.</li>
  4446. <li><code>admins_can_join</code>: allow server admins to join complex rooms. Default is false.</li>
  4447. </ul>
  4448. <p>Room complexity is an arbitrary measure based on factors such as the number of
  4449. users in the room.</p>
  4450. <p>Example configuration:</p>
  4451. <pre><code class="language-yaml">limit_remote_rooms:
  4452. enabled: true
  4453. complexity: 0.5
  4454. complexity_error: &quot;I can't let you do that, Dave.&quot;
  4455. admins_can_join: true
  4456. </code></pre>
  4457. <hr />
  4458. <h3 id="require_membership_for_aliases"><a class="header" href="#require_membership_for_aliases"><code>require_membership_for_aliases</code></a></h3>
  4459. <p>Whether to require a user to be in the room to add an alias to it.
  4460. Defaults to true.</p>
  4461. <p>Example configuration:</p>
  4462. <pre><code class="language-yaml">require_membership_for_aliases: false
  4463. </code></pre>
  4464. <hr />
  4465. <h3 id="allow_per_room_profiles"><a class="header" href="#allow_per_room_profiles"><code>allow_per_room_profiles</code></a></h3>
  4466. <p>Whether to allow per-room membership profiles through the sending of membership
  4467. events with profile information that differs from the target's global profile.
  4468. Defaults to true.</p>
  4469. <p>Example configuration:</p>
  4470. <pre><code class="language-yaml">allow_per_room_profiles: false
  4471. </code></pre>
  4472. <hr />
  4473. <h3 id="max_avatar_size"><a class="header" href="#max_avatar_size"><code>max_avatar_size</code></a></h3>
  4474. <p>The largest permissible file size in bytes for a user avatar. Defaults to no restriction.
  4475. Use M for MB and K for KB.</p>
  4476. <p>Note that user avatar changes will not work if this is set without using Synapse's media repository.</p>
  4477. <p>Example configuration:</p>
  4478. <pre><code class="language-yaml">max_avatar_size: 10M
  4479. </code></pre>
  4480. <hr />
  4481. <h3 id="allowed_avatar_mimetypes"><a class="header" href="#allowed_avatar_mimetypes"><code>allowed_avatar_mimetypes</code></a></h3>
  4482. <p>The MIME types allowed for user avatars. Defaults to no restriction.</p>
  4483. <p>Note that user avatar changes will not work if this is set without
  4484. using Synapse's media repository.</p>
  4485. <p>Example configuration:</p>
  4486. <pre><code class="language-yaml">allowed_avatar_mimetypes: [&quot;image/png&quot;, &quot;image/jpeg&quot;, &quot;image/gif&quot;]
  4487. </code></pre>
  4488. <hr />
  4489. <h3 id="redaction_retention_period"><a class="header" href="#redaction_retention_period"><code>redaction_retention_period</code></a></h3>
  4490. <p>How long to keep redacted events in unredacted form in the database. After
  4491. this period redacted events get replaced with their redacted form in the DB.</p>
  4492. <p>Synapse will check whether the rentention period has concluded for redacted
  4493. events every 5 minutes. Thus, even if this option is set to <code>0</code>, Synapse may
  4494. still take up to 5 minutes to purge redacted events from the database.</p>
  4495. <p>Defaults to <code>7d</code>. Set to <code>null</code> to disable.</p>
  4496. <p>Example configuration:</p>
  4497. <pre><code class="language-yaml">redaction_retention_period: 28d
  4498. </code></pre>
  4499. <hr />
  4500. <h3 id="forgotten_room_retention_period"><a class="header" href="#forgotten_room_retention_period"><code>forgotten_room_retention_period</code></a></h3>
  4501. <p>How long to keep locally forgotten rooms before purging them from the DB.</p>
  4502. <p>Defaults to <code>null</code>, meaning it's disabled.</p>
  4503. <p>Example configuration:</p>
  4504. <pre><code class="language-yaml">forgotten_room_retention_period: 28d
  4505. </code></pre>
  4506. <hr />
  4507. <h3 id="user_ips_max_age"><a class="header" href="#user_ips_max_age"><code>user_ips_max_age</code></a></h3>
  4508. <p>How long to track users' last seen time and IPs in the database.</p>
  4509. <p>Defaults to <code>28d</code>. Set to <code>null</code> to disable clearing out of old rows.</p>
  4510. <p>Example configuration:</p>
  4511. <pre><code class="language-yaml">user_ips_max_age: 14d
  4512. </code></pre>
  4513. <hr />
  4514. <h3 id="request_token_inhibit_3pid_errors"><a class="header" href="#request_token_inhibit_3pid_errors"><code>request_token_inhibit_3pid_errors</code></a></h3>
  4515. <p>Inhibits the <code>/requestToken</code> endpoints from returning an error that might leak
  4516. information about whether an e-mail address is in use or not on this
  4517. homeserver. Defaults to false.
  4518. Note that for some endpoints the error situation is the e-mail already being
  4519. used, and for others the error is entering the e-mail being unused.
  4520. If this option is enabled, instead of returning an error, these endpoints will
  4521. act as if no error happened and return a fake session ID ('sid') to clients.</p>
  4522. <p>Example configuration:</p>
  4523. <pre><code class="language-yaml">request_token_inhibit_3pid_errors: true
  4524. </code></pre>
  4525. <hr />
  4526. <h3 id="next_link_domain_whitelist"><a class="header" href="#next_link_domain_whitelist"><code>next_link_domain_whitelist</code></a></h3>
  4527. <p>A list of domains that the domain portion of <code>next_link</code> parameters
  4528. must match.</p>
  4529. <p>This parameter is optionally provided by clients while requesting
  4530. validation of an email or phone number, and maps to a link that
  4531. users will be automatically redirected to after validation
  4532. succeeds. Clients can make use this parameter to aid the validation
  4533. process.</p>
  4534. <p>The whitelist is applied whether the homeserver or an identity server is handling validation.</p>
  4535. <p>The default value is no whitelist functionality; all domains are
  4536. allowed. Setting this value to an empty list will instead disallow
  4537. all domains.</p>
  4538. <p>Example configuration:</p>
  4539. <pre><code class="language-yaml">next_link_domain_whitelist: [&quot;matrix.org&quot;]
  4540. </code></pre>
  4541. <hr />
  4542. <h3 id="templates-and-custom_template_directory"><a class="header" href="#templates-and-custom_template_directory"><code>templates</code> and <code>custom_template_directory</code></a></h3>
  4543. <p>These options define templates to use when generating email or HTML page contents.
  4544. The <code>custom_template_directory</code> determines which directory Synapse will try to
  4545. find template files in to use to generate email or HTML page contents.
  4546. If not set, or a file is not found within the template directory, a default
  4547. template from within the Synapse package will be used.</p>
  4548. <p>See <a href="usage/configuration/../../templates.html">here</a> for more
  4549. information about using custom templates.</p>
  4550. <p>Example configuration:</p>
  4551. <pre><code class="language-yaml">templates:
  4552. custom_template_directory: /path/to/custom/templates/
  4553. </code></pre>
  4554. <hr />
  4555. <h3 id="retention"><a class="header" href="#retention"><code>retention</code></a></h3>
  4556. <p>This option and the associated options determine message retention policy at the
  4557. server level.</p>
  4558. <p>Room admins and mods can define a retention period for their rooms using the
  4559. <code>m.room.retention</code> state event, and server admins can cap this period by setting
  4560. the <code>allowed_lifetime_min</code> and <code>allowed_lifetime_max</code> config options.</p>
  4561. <p>If this feature is enabled, Synapse will regularly look for and purge events
  4562. which are older than the room's maximum retention period. Synapse will also
  4563. filter events received over federation so that events that should have been
  4564. purged are ignored and not stored again.</p>
  4565. <p>The message retention policies feature is disabled by default. You can read more
  4566. about this feature <a href="usage/configuration/../../message_retention_policies.html">here</a>.</p>
  4567. <p>This setting has the following sub-options:</p>
  4568. <ul>
  4569. <li>
  4570. <p><code>default_policy</code>: Default retention policy. If set, Synapse will apply it to rooms that lack the
  4571. 'm.room.retention' state event. This option is further specified by the
  4572. <code>min_lifetime</code> and <code>max_lifetime</code> sub-options associated with it. Note that the
  4573. value of <code>min_lifetime</code> doesn't matter much because Synapse doesn't take it into account yet.</p>
  4574. </li>
  4575. <li>
  4576. <p><code>allowed_lifetime_min</code> and <code>allowed_lifetime_max</code>: Retention policy limits. If
  4577. set, and the state of a room contains a <code>m.room.retention</code> event in its state
  4578. which contains a <code>min_lifetime</code> or a <code>max_lifetime</code> that's out of these bounds,
  4579. Synapse will cap the room's policy to these limits when running purge jobs.</p>
  4580. </li>
  4581. <li>
  4582. <p><code>purge_jobs</code> and the associated <code>shortest_max_lifetime</code> and <code>longest_max_lifetime</code> sub-options:
  4583. Server admins can define the settings of the background jobs purging the
  4584. events whose lifetime has expired under the <code>purge_jobs</code> section.</p>
  4585. <p>If no configuration is provided for this option, a single job will be set up to delete
  4586. expired events in every room daily.</p>
  4587. <p>Each job's configuration defines which range of message lifetimes the job
  4588. takes care of. For example, if <code>shortest_max_lifetime</code> is '2d' and
  4589. <code>longest_max_lifetime</code> is '3d', the job will handle purging expired events in
  4590. rooms whose state defines a <code>max_lifetime</code> that's both higher than 2 days, and
  4591. lower than or equal to 3 days. Both the minimum and the maximum value of a
  4592. range are optional, e.g. a job with no <code>shortest_max_lifetime</code> and a
  4593. <code>longest_max_lifetime</code> of '3d' will handle every room with a retention policy
  4594. whose <code>max_lifetime</code> is lower than or equal to three days.</p>
  4595. <p>The rationale for this per-job configuration is that some rooms might have a
  4596. retention policy with a low <code>max_lifetime</code>, where history needs to be purged
  4597. of outdated messages on a more frequent basis than for the rest of the rooms
  4598. (e.g. every 12h), but not want that purge to be performed by a job that's
  4599. iterating over every room it knows, which could be heavy on the server.</p>
  4600. <p>If any purge job is configured, it is strongly recommended to have at least
  4601. a single job with neither <code>shortest_max_lifetime</code> nor <code>longest_max_lifetime</code>
  4602. set, or one job without <code>shortest_max_lifetime</code> and one job without
  4603. <code>longest_max_lifetime</code> set. Otherwise some rooms might be ignored, even if
  4604. <code>allowed_lifetime_min</code> and <code>allowed_lifetime_max</code> are set, because capping a
  4605. room's policy to these values is done after the policies are retrieved from
  4606. Synapse's database (which is done using the range specified in a purge job's
  4607. configuration).</p>
  4608. </li>
  4609. </ul>
  4610. <p>Example configuration:</p>
  4611. <pre><code class="language-yaml">retention:
  4612. enabled: true
  4613. default_policy:
  4614. min_lifetime: 1d
  4615. max_lifetime: 1y
  4616. allowed_lifetime_min: 1d
  4617. allowed_lifetime_max: 1y
  4618. purge_jobs:
  4619. - longest_max_lifetime: 3d
  4620. interval: 12h
  4621. - shortest_max_lifetime: 3d
  4622. interval: 1d
  4623. </code></pre>
  4624. <hr />
  4625. <h2 id="tls"><a class="header" href="#tls">TLS</a></h2>
  4626. <p>Options related to TLS.</p>
  4627. <hr />
  4628. <h3 id="tls_certificate_path"><a class="header" href="#tls_certificate_path"><code>tls_certificate_path</code></a></h3>
  4629. <p>This option specifies a PEM-encoded X509 certificate for TLS.
  4630. This certificate, as of Synapse 1.0, will need to be a valid and verifiable
  4631. certificate, signed by a recognised Certificate Authority. Defaults to none.</p>
  4632. <p>Be sure to use a <code>.pem</code> file that includes the full certificate chain including
  4633. any intermediate certificates (for instance, if using certbot, use
  4634. <code>fullchain.pem</code> as your certificate, not <code>cert.pem</code>).</p>
  4635. <p>Example configuration:</p>
  4636. <pre><code class="language-yaml">tls_certificate_path: &quot;CONFDIR/SERVERNAME.tls.crt&quot;
  4637. </code></pre>
  4638. <hr />
  4639. <h3 id="tls_private_key_path"><a class="header" href="#tls_private_key_path"><code>tls_private_key_path</code></a></h3>
  4640. <p>PEM-encoded private key for TLS. Defaults to none.</p>
  4641. <p>Example configuration:</p>
  4642. <pre><code class="language-yaml">tls_private_key_path: &quot;CONFDIR/SERVERNAME.tls.key&quot;
  4643. </code></pre>
  4644. <hr />
  4645. <h3 id="federation_verify_certificates"><a class="header" href="#federation_verify_certificates"><code>federation_verify_certificates</code></a></h3>
  4646. <p>Whether to verify TLS server certificates for outbound federation requests.</p>
  4647. <p>Defaults to true. To disable certificate verification, set the option to false.</p>
  4648. <p>Example configuration:</p>
  4649. <pre><code class="language-yaml">federation_verify_certificates: false
  4650. </code></pre>
  4651. <hr />
  4652. <h3 id="federation_client_minimum_tls_version"><a class="header" href="#federation_client_minimum_tls_version"><code>federation_client_minimum_tls_version</code></a></h3>
  4653. <p>The minimum TLS version that will be used for outbound federation requests.</p>
  4654. <p>Defaults to <code>&quot;1&quot;</code>. Configurable to <code>&quot;1&quot;</code>, <code>&quot;1.1&quot;</code>, <code>&quot;1.2&quot;</code>, or <code>&quot;1.3&quot;</code>. Note
  4655. that setting this value higher than <code>&quot;1.2&quot;</code> will prevent federation to most
  4656. of the public Matrix network: only configure it to <code>&quot;1.3&quot;</code> if you have an
  4657. entirely private federation setup and you can ensure TLS 1.3 support.</p>
  4658. <p>Example configuration:</p>
  4659. <pre><code class="language-yaml">federation_client_minimum_tls_version: &quot;1.2&quot;
  4660. </code></pre>
  4661. <hr />
  4662. <h3 id="federation_certificate_verification_whitelist"><a class="header" href="#federation_certificate_verification_whitelist"><code>federation_certificate_verification_whitelist</code></a></h3>
  4663. <p>Skip federation certificate verification on a given whitelist
  4664. of domains.</p>
  4665. <p>This setting should only be used in very specific cases, such as
  4666. federation over Tor hidden services and similar. For private networks
  4667. of homeservers, you likely want to use a private CA instead.</p>
  4668. <p>Only effective if <code>federation_verify_certificates</code> is <code>true</code>.</p>
  4669. <p>Example configuration:</p>
  4670. <pre><code class="language-yaml">federation_certificate_verification_whitelist:
  4671. - lon.example.com
  4672. - &quot;*.domain.com&quot;
  4673. - &quot;*.onion&quot;
  4674. </code></pre>
  4675. <hr />
  4676. <h3 id="federation_custom_ca_list"><a class="header" href="#federation_custom_ca_list"><code>federation_custom_ca_list</code></a></h3>
  4677. <p>List of custom certificate authorities for federation traffic.</p>
  4678. <p>This setting should only normally be used within a private network of
  4679. homeservers.</p>
  4680. <p>Note that this list will replace those that are provided by your
  4681. operating environment. Certificates must be in PEM format.</p>
  4682. <p>Example configuration:</p>
  4683. <pre><code class="language-yaml">federation_custom_ca_list:
  4684. - myCA1.pem
  4685. - myCA2.pem
  4686. - myCA3.pem
  4687. </code></pre>
  4688. <hr />
  4689. <h2 id="federation"><a class="header" href="#federation">Federation</a></h2>
  4690. <p>Options related to federation.</p>
  4691. <hr />
  4692. <h3 id="federation_domain_whitelist"><a class="header" href="#federation_domain_whitelist"><code>federation_domain_whitelist</code></a></h3>
  4693. <p>Restrict federation to the given whitelist of domains.
  4694. N.B. we recommend also firewalling your federation listener to limit
  4695. inbound federation traffic as early as possible, rather than relying
  4696. purely on this application-layer restriction. If not specified, the
  4697. default is to whitelist everything.</p>
  4698. <p>Note: this does not stop a server from joining rooms that servers not on the
  4699. whitelist are in. As such, this option is really only useful to establish a
  4700. &quot;private federation&quot;, where a group of servers all whitelist each other and have
  4701. the same whitelist.</p>
  4702. <p>Example configuration:</p>
  4703. <pre><code class="language-yaml">federation_domain_whitelist:
  4704. - lon.example.com
  4705. - nyc.example.com
  4706. - syd.example.com
  4707. </code></pre>
  4708. <hr />
  4709. <h3 id="federation_metrics_domains"><a class="header" href="#federation_metrics_domains"><code>federation_metrics_domains</code></a></h3>
  4710. <p>Report prometheus metrics on the age of PDUs being sent to and received from
  4711. the given domains. This can be used to give an idea of &quot;delay&quot; on inbound
  4712. and outbound federation, though be aware that any delay can be due to problems
  4713. at either end or with the intermediate network.</p>
  4714. <p>By default, no domains are monitored in this way.</p>
  4715. <p>Example configuration:</p>
  4716. <pre><code class="language-yaml">federation_metrics_domains:
  4717. - matrix.org
  4718. - example.com
  4719. </code></pre>
  4720. <hr />
  4721. <h3 id="allow_profile_lookup_over_federation"><a class="header" href="#allow_profile_lookup_over_federation"><code>allow_profile_lookup_over_federation</code></a></h3>
  4722. <p>Set to false to disable profile lookup over federation. By default, the
  4723. Federation API allows other homeservers to obtain profile data of any user
  4724. on this homeserver.</p>
  4725. <p>Example configuration:</p>
  4726. <pre><code class="language-yaml">allow_profile_lookup_over_federation: false
  4727. </code></pre>
  4728. <hr />
  4729. <h3 id="allow_device_name_lookup_over_federation"><a class="header" href="#allow_device_name_lookup_over_federation"><code>allow_device_name_lookup_over_federation</code></a></h3>
  4730. <p>Set this option to true to allow device display name lookup over federation. By default, the
  4731. Federation API prevents other homeservers from obtaining the display names of any user devices
  4732. on this homeserver.</p>
  4733. <p>Example configuration:</p>
  4734. <pre><code class="language-yaml">allow_device_name_lookup_over_federation: true
  4735. </code></pre>
  4736. <hr />
  4737. <h3 id="federation-1"><a class="header" href="#federation-1"><code>federation</code></a></h3>
  4738. <p>The federation section defines some sub-options related to federation.</p>
  4739. <p>The following options are related to configuring timeout and retry logic for one request,
  4740. independently of the others.
  4741. Short retry algorithm is used when something or someone will wait for the request to have an
  4742. answer, while long retry is used for requests that happen in the background,
  4743. like sending a federation transaction.</p>
  4744. <ul>
  4745. <li><code>client_timeout</code>: timeout for the federation requests. Default to 60s.</li>
  4746. <li><code>max_short_retry_delay</code>: maximum delay to be used for the short retry algo. Default to 2s.</li>
  4747. <li><code>max_long_retry_delay</code>: maximum delay to be used for the short retry algo. Default to 60s.</li>
  4748. <li><code>max_short_retries</code>: maximum number of retries for the short retry algo. Default to 3 attempts.</li>
  4749. <li><code>max_long_retries</code>: maximum number of retries for the long retry algo. Default to 10 attempts.</li>
  4750. </ul>
  4751. <p>The following options control the retry logic when communicating with a specific homeserver destination.
  4752. Unlike the previous configuration options, these values apply across all requests
  4753. for a given destination and the state of the backoff is stored in the database.</p>
  4754. <ul>
  4755. <li><code>destination_min_retry_interval</code>: the initial backoff, after the first request fails. Defaults to 10m.</li>
  4756. <li><code>destination_retry_multiplier</code>: how much we multiply the backoff by after each subsequent fail. Defaults to 2.</li>
  4757. <li><code>destination_max_retry_interval</code>: a cap on the backoff. Defaults to a week.</li>
  4758. </ul>
  4759. <p>Example configuration:</p>
  4760. <pre><code class="language-yaml">federation:
  4761. client_timeout: 180s
  4762. max_short_retry_delay: 7s
  4763. max_long_retry_delay: 100s
  4764. max_short_retries: 5
  4765. max_long_retries: 20
  4766. destination_min_retry_interval: 30s
  4767. destination_retry_multiplier: 5
  4768. destination_max_retry_interval: 12h
  4769. </code></pre>
  4770. <hr />
  4771. <h2 id="caching"><a class="header" href="#caching">Caching</a></h2>
  4772. <p>Options related to caching.</p>
  4773. <hr />
  4774. <h3 id="event_cache_size"><a class="header" href="#event_cache_size"><code>event_cache_size</code></a></h3>
  4775. <p>The number of events to cache in memory. Defaults to 10K. Like other caches,
  4776. this is affected by <code>caches.global_factor</code> (see below).</p>
  4777. <p>Note that this option is not part of the <code>caches</code> section.</p>
  4778. <p>Example configuration:</p>
  4779. <pre><code class="language-yaml">event_cache_size: 15K
  4780. </code></pre>
  4781. <hr />
  4782. <h3 id="caches-and-associated-values"><a class="header" href="#caches-and-associated-values"><code>caches</code> and associated values</a></h3>
  4783. <p>A cache 'factor' is a multiplier that can be applied to each of
  4784. Synapse's caches in order to increase or decrease the maximum
  4785. number of entries that can be stored.</p>
  4786. <p><code>caches</code> can be configured through the following sub-options:</p>
  4787. <ul>
  4788. <li>
  4789. <p><code>global_factor</code>: Controls the global cache factor, which is the default cache factor
  4790. for all caches if a specific factor for that cache is not otherwise
  4791. set.</p>
  4792. <p>This can also be set by the <code>SYNAPSE_CACHE_FACTOR</code> environment
  4793. variable. Setting by environment variable takes priority over
  4794. setting through the config file.</p>
  4795. <p>Defaults to 0.5, which will halve the size of all caches.</p>
  4796. </li>
  4797. <li>
  4798. <p><code>per_cache_factors</code>: A dictionary of cache name to cache factor for that individual
  4799. cache. Overrides the global cache factor for a given cache.</p>
  4800. <p>These can also be set through environment variables comprised
  4801. of <code>SYNAPSE_CACHE_FACTOR_</code> + the name of the cache in capital
  4802. letters and underscores. Setting by environment variable
  4803. takes priority over setting through the config file.
  4804. Ex. <code>SYNAPSE_CACHE_FACTOR_GET_USERS_WHO_SHARE_ROOM_WITH_USER=2.0</code></p>
  4805. <p>Some caches have '*' and other characters that are not
  4806. alphanumeric or underscores. These caches can be named with or
  4807. without the special characters stripped. For example, to specify
  4808. the cache factor for <code>*stateGroupCache*</code> via an environment
  4809. variable would be <code>SYNAPSE_CACHE_FACTOR_STATEGROUPCACHE=2.0</code>.</p>
  4810. </li>
  4811. <li>
  4812. <p><code>expire_caches</code>: Controls whether cache entries are evicted after a specified time
  4813. period. Defaults to true. Set to false to disable this feature. Note that never expiring
  4814. caches may result in excessive memory usage.</p>
  4815. </li>
  4816. <li>
  4817. <p><code>cache_entry_ttl</code>: If <code>expire_caches</code> is enabled, this flag controls how long an entry can
  4818. be in a cache without having been accessed before being evicted.
  4819. Defaults to 30m.</p>
  4820. </li>
  4821. <li>
  4822. <p><code>sync_response_cache_duration</code>: Controls how long the results of a /sync request are
  4823. cached for after a successful response is returned. A higher duration can help clients
  4824. with intermittent connections, at the cost of higher memory usage.
  4825. A value of zero means that sync responses are not cached.
  4826. Defaults to 2m.</p>
  4827. <p><em>Changed in Synapse 1.62.0</em>: The default was changed from 0 to 2m.</p>
  4828. </li>
  4829. <li>
  4830. <p><code>cache_autotuning</code> and its sub-options <code>max_cache_memory_usage</code>, <code>target_cache_memory_usage</code>, and
  4831. <code>min_cache_ttl</code> work in conjunction with each other to maintain a balance between cache memory
  4832. usage and cache entry availability. You must be using <a href="usage/configuration/../administration/admin_faq.html#help-synapse-is-slow-and-eats-all-my-ramcpu">jemalloc</a>
  4833. to utilize this option, and all three of the options must be specified for this feature to work. This option
  4834. defaults to off, enable it by providing values for the sub-options listed below. Please note that the feature will not work
  4835. and may cause unstable behavior (such as excessive emptying of caches or exceptions) if all of the values are not provided.
  4836. Please see the <a href="usage/configuration/config_documentation.html#config-conventions">Config Conventions</a> for information on how to specify memory size and cache expiry
  4837. durations.</p>
  4838. <ul>
  4839. <li><code>max_cache_memory_usage</code> sets a ceiling on how much memory the cache can use before caches begin to be continuously evicted.
  4840. They will continue to be evicted until the memory usage drops below the <code>target_memory_usage</code>, set in
  4841. the setting below, or until the <code>min_cache_ttl</code> is hit. There is no default value for this option.</li>
  4842. <li><code>target_cache_memory_usage</code> sets a rough target for the desired memory usage of the caches. There is no default value
  4843. for this option.</li>
  4844. <li><code>min_cache_ttl</code> sets a limit under which newer cache entries are not evicted and is only applied when
  4845. caches are actively being evicted/<code>max_cache_memory_usage</code> has been exceeded. This is to protect hot caches
  4846. from being emptied while Synapse is evicting due to memory. There is no default value for this option.</li>
  4847. </ul>
  4848. </li>
  4849. </ul>
  4850. <p>Example configuration:</p>
  4851. <pre><code class="language-yaml">event_cache_size: 15K
  4852. caches:
  4853. global_factor: 1.0
  4854. per_cache_factors:
  4855. get_users_who_share_room_with_user: 2.0
  4856. sync_response_cache_duration: 2m
  4857. cache_autotuning:
  4858. max_cache_memory_usage: 1024M
  4859. target_cache_memory_usage: 758M
  4860. min_cache_ttl: 5m
  4861. </code></pre>
  4862. <h3 id="reloading-cache-factors"><a class="header" href="#reloading-cache-factors">Reloading cache factors</a></h3>
  4863. <p>The cache factors (i.e. <code>caches.global_factor</code> and <code>caches.per_cache_factors</code>) may be reloaded at any time by sending a
  4864. <a href="https://en.wikipedia.org/wiki/SIGHUP"><code>SIGHUP</code></a> signal to Synapse using e.g.</p>
  4865. <pre><code class="language-commandline">kill -HUP [PID_OF_SYNAPSE_PROCESS]
  4866. </code></pre>
  4867. <p>If you are running multiple workers, you must individually update the worker
  4868. config file and send this signal to each worker process.</p>
  4869. <p>If you're using the <a href="https://github.com/matrix-org/synapse/blob/develop/contrib/systemd/matrix-synapse.service">example systemd service</a>
  4870. file in Synapse's <code>contrib</code> directory, you can send a <code>SIGHUP</code> signal by using
  4871. <code>systemctl reload matrix-synapse</code>.</p>
  4872. <hr />
  4873. <h2 id="database"><a class="header" href="#database">Database</a></h2>
  4874. <p>Config options related to database settings.</p>
  4875. <hr />
  4876. <h3 id="database-1"><a class="header" href="#database-1"><code>database</code></a></h3>
  4877. <p>The <code>database</code> setting defines the database that synapse uses to store all of
  4878. its data.</p>
  4879. <p>Associated sub-options:</p>
  4880. <ul>
  4881. <li>
  4882. <p><code>name</code>: this option specifies the database engine to use: either <code>sqlite3</code> (for SQLite)
  4883. or <code>psycopg2</code> (for PostgreSQL). If no name is specified Synapse will default to SQLite.</p>
  4884. </li>
  4885. <li>
  4886. <p><code>txn_limit</code> gives the maximum number of transactions to run per connection
  4887. before reconnecting. Defaults to 0, which means no limit.</p>
  4888. </li>
  4889. <li>
  4890. <p><code>allow_unsafe_locale</code> is an option specific to Postgres. Under the default behavior, Synapse will refuse to
  4891. start if the postgres db is set to a non-C locale. You can override this behavior (which is <em>not</em> recommended)
  4892. by setting <code>allow_unsafe_locale</code> to true. Note that doing so may corrupt your database. You can find more information
  4893. <a href="usage/configuration/../../postgres.html#fixing-incorrect-collate-or-ctype">here</a> and <a href="https://wiki.postgresql.org/wiki/Locale_data_changes">here</a>.</p>
  4894. </li>
  4895. <li>
  4896. <p><code>args</code> gives options which are passed through to the database engine,
  4897. except for options starting with <code>cp_</code>, which are used to configure the Twisted
  4898. connection pool. For a reference to valid arguments, see:</p>
  4899. <ul>
  4900. <li>for <a href="https://docs.python.org/3/library/sqlite3.html#sqlite3.connect">sqlite</a></li>
  4901. <li>for <a href="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS">postgres</a></li>
  4902. <li>for <a href="https://docs.twistedmatrix.com/en/stable/api/twisted.enterprise.adbapi.ConnectionPool.html#__init__">the connection pool</a></li>
  4903. </ul>
  4904. </li>
  4905. </ul>
  4906. <p>For more information on using Synapse with Postgres,
  4907. see <a href="usage/configuration/../../postgres.html">here</a>.</p>
  4908. <p>Example SQLite configuration:</p>
  4909. <pre><code class="language-yaml">database:
  4910. name: sqlite3
  4911. args:
  4912. database: /path/to/homeserver.db
  4913. </code></pre>
  4914. <p>Example Postgres configuration:</p>
  4915. <pre><code class="language-yaml">database:
  4916. name: psycopg2
  4917. txn_limit: 10000
  4918. args:
  4919. user: synapse_user
  4920. password: secretpassword
  4921. dbname: synapse
  4922. host: localhost
  4923. port: 5432
  4924. cp_min: 5
  4925. cp_max: 10
  4926. </code></pre>
  4927. <hr />
  4928. <h3 id="databases"><a class="header" href="#databases"><code>databases</code></a></h3>
  4929. <p>The <code>databases</code> option allows specifying a mapping between certain database tables and
  4930. database host details, spreading the load of a single Synapse instance across multiple
  4931. database backends. This is often referred to as &quot;database sharding&quot;. This option is only
  4932. supported for PostgreSQL database backends.</p>
  4933. <p><strong>Important note:</strong> This is a supported option, but is not currently used in production by the
  4934. Matrix.org Foundation. Proceed with caution and always make backups.</p>
  4935. <p><code>databases</code> is a dictionary of arbitrarily-named database entries. Each entry is equivalent
  4936. to the value of the <code>database</code> homeserver config option (see above), with the addition of
  4937. a <code>data_stores</code> key. <code>data_stores</code> is an array of strings that specifies the data store(s)
  4938. (a defined label for a set of tables) that should be stored on the associated database
  4939. backend entry.</p>
  4940. <p>The currently defined values for <code>data_stores</code> are:</p>
  4941. <ul>
  4942. <li>
  4943. <p><code>&quot;state&quot;</code>: Database that relates to state groups will be stored in this database.</p>
  4944. <p>Specifically, that means the following tables:</p>
  4945. <ul>
  4946. <li><code>state_groups</code></li>
  4947. <li><code>state_group_edges</code></li>
  4948. <li><code>state_groups_state</code></li>
  4949. </ul>
  4950. <p>And the following sequences:</p>
  4951. <ul>
  4952. <li><code>state_groups_seq_id</code></li>
  4953. </ul>
  4954. </li>
  4955. <li>
  4956. <p><code>&quot;main&quot;</code>: All other database tables and sequences.</p>
  4957. </li>
  4958. </ul>
  4959. <p>All databases will end up with additional tables used for tracking database schema migrations
  4960. and any pending background updates. Synapse will create these automatically on startup when checking for
  4961. and/or performing database schema migrations.</p>
  4962. <p>To migrate an existing database configuration (e.g. all tables on a single database) to a different
  4963. configuration (e.g. the &quot;main&quot; data store on one database, and &quot;state&quot; on another), do the following:</p>
  4964. <ol>
  4965. <li>
  4966. <p>Take a backup of your existing database. Things can and do go wrong and database corruption is no joke!</p>
  4967. </li>
  4968. <li>
  4969. <p>Ensure all pending database migrations have been applied and background updates have run. The simplest
  4970. way to do this is to use the <code>update_synapse_database</code> script supplied with your Synapse installation.</p>
  4971. <pre><code class="language-sh">update_synapse_database --database-config homeserver.yaml --run-background-updates
  4972. </code></pre>
  4973. </li>
  4974. <li>
  4975. <p>Copy over the necessary tables and sequences from one database to the other. Tables relating to database
  4976. migrations, schemas, schema versions and background updates should <strong>not</strong> be copied.</p>
  4977. <p>As an example, say that you'd like to split out the &quot;state&quot; data store from an existing database which
  4978. currently contains all data stores.</p>
  4979. <p>Simply copy the tables and sequences defined above for the &quot;state&quot; datastore from the existing database
  4980. to the secondary database. As noted above, additional tables will be created in the secondary database
  4981. when Synapse is started.</p>
  4982. </li>
  4983. <li>
  4984. <p>Modify/create the <code>databases</code> option in your <code>homeserver.yaml</code> to match the desired database configuration.</p>
  4985. </li>
  4986. <li>
  4987. <p>Start Synapse. Check that it starts up successfully and that things generally seem to be working.</p>
  4988. </li>
  4989. <li>
  4990. <p>Drop the old tables that were copied in step 3.</p>
  4991. </li>
  4992. </ol>
  4993. <p>Only one of the options <code>database</code> or <code>databases</code> may be specified in your config, but not both.</p>
  4994. <p>Example configuration:</p>
  4995. <pre><code class="language-yaml">databases:
  4996. basement_box:
  4997. name: psycopg2
  4998. txn_limit: 10000
  4999. data_stores: [&quot;main&quot;]
  5000. args:
  5001. user: synapse_user
  5002. password: secretpassword
  5003. dbname: synapse_main
  5004. host: localhost
  5005. port: 5432
  5006. cp_min: 5
  5007. cp_max: 10
  5008. my_other_database:
  5009. name: psycopg2
  5010. txn_limit: 10000
  5011. data_stores: [&quot;state&quot;]
  5012. args:
  5013. user: synapse_user
  5014. password: secretpassword
  5015. dbname: synapse_state
  5016. host: localhost
  5017. port: 5432
  5018. cp_min: 5
  5019. cp_max: 10
  5020. </code></pre>
  5021. <hr />
  5022. <h2 id="logging"><a class="header" href="#logging">Logging</a></h2>
  5023. <p>Config options related to logging.</p>
  5024. <hr />
  5025. <h3 id="log_config"><a class="header" href="#log_config"><code>log_config</code></a></h3>
  5026. <p>This option specifies a yaml python logging config file as described
  5027. <a href="https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema">here</a>.</p>
  5028. <p>Example configuration:</p>
  5029. <pre><code class="language-yaml">log_config: &quot;CONFDIR/SERVERNAME.log.config&quot;
  5030. </code></pre>
  5031. <hr />
  5032. <h2 id="ratelimiting"><a class="header" href="#ratelimiting">Ratelimiting</a></h2>
  5033. <p>Options related to ratelimiting in Synapse.</p>
  5034. <p>Each ratelimiting configuration is made of two parameters:</p>
  5035. <ul>
  5036. <li><code>per_second</code>: number of requests a client can send per second.</li>
  5037. <li><code>burst_count</code>: number of requests a client can send before being throttled.</li>
  5038. </ul>
  5039. <hr />
  5040. <h3 id="rc_message"><a class="header" href="#rc_message"><code>rc_message</code></a></h3>
  5041. <p>Ratelimiting settings for client messaging.</p>
  5042. <p>This is a ratelimiting option for messages that ratelimits sending based on the account the client
  5043. is using. It defaults to: <code>per_second: 0.2</code>, <code>burst_count: 10</code>.</p>
  5044. <p>Example configuration:</p>
  5045. <pre><code class="language-yaml">rc_message:
  5046. per_second: 0.5
  5047. burst_count: 15
  5048. </code></pre>
  5049. <hr />
  5050. <h3 id="rc_registration"><a class="header" href="#rc_registration"><code>rc_registration</code></a></h3>
  5051. <p>This option ratelimits registration requests based on the client's IP address.
  5052. It defaults to <code>per_second: 0.17</code>, <code>burst_count: 3</code>.</p>
  5053. <p>Example configuration:</p>
  5054. <pre><code class="language-yaml">rc_registration:
  5055. per_second: 0.15
  5056. burst_count: 2
  5057. </code></pre>
  5058. <hr />
  5059. <h3 id="rc_registration_token_validity"><a class="header" href="#rc_registration_token_validity"><code>rc_registration_token_validity</code></a></h3>
  5060. <p>This option checks the validity of registration tokens that ratelimits requests based on
  5061. the client's IP address.
  5062. Defaults to <code>per_second: 0.1</code>, <code>burst_count: 5</code>.</p>
  5063. <p>Example configuration:</p>
  5064. <pre><code class="language-yaml">rc_registration_token_validity:
  5065. per_second: 0.3
  5066. burst_count: 6
  5067. </code></pre>
  5068. <hr />
  5069. <h3 id="rc_login"><a class="header" href="#rc_login"><code>rc_login</code></a></h3>
  5070. <p>This option specifies several limits for login:</p>
  5071. <ul>
  5072. <li>
  5073. <p><code>address</code> ratelimits login requests based on the client's IP
  5074. address. Defaults to <code>per_second: 0.003</code>, <code>burst_count: 5</code>.</p>
  5075. </li>
  5076. <li>
  5077. <p><code>account</code> ratelimits login requests based on the account the
  5078. client is attempting to log into. Defaults to <code>per_second: 0.003</code>,
  5079. <code>burst_count: 5</code>.</p>
  5080. </li>
  5081. <li>
  5082. <p><code>failed_attempts</code> ratelimits login requests based on the account the
  5083. client is attempting to log into, based on the amount of failed login
  5084. attempts for this account. Defaults to <code>per_second: 0.17</code>, <code>burst_count: 3</code>.</p>
  5085. </li>
  5086. </ul>
  5087. <p>Example configuration:</p>
  5088. <pre><code class="language-yaml">rc_login:
  5089. address:
  5090. per_second: 0.15
  5091. burst_count: 5
  5092. account:
  5093. per_second: 0.18
  5094. burst_count: 4
  5095. failed_attempts:
  5096. per_second: 0.19
  5097. burst_count: 7
  5098. </code></pre>
  5099. <hr />
  5100. <h3 id="rc_admin_redaction"><a class="header" href="#rc_admin_redaction"><code>rc_admin_redaction</code></a></h3>
  5101. <p>This option sets ratelimiting redactions by room admins. If this is not explicitly
  5102. set then it uses the same ratelimiting as per <code>rc_message</code>. This is useful
  5103. to allow room admins to deal with abuse quickly.</p>
  5104. <p>Example configuration:</p>
  5105. <pre><code class="language-yaml">rc_admin_redaction:
  5106. per_second: 1
  5107. burst_count: 50
  5108. </code></pre>
  5109. <hr />
  5110. <h3 id="rc_joins"><a class="header" href="#rc_joins"><code>rc_joins</code></a></h3>
  5111. <p>This option allows for ratelimiting number of rooms a user can join. This setting has the following sub-options:</p>
  5112. <ul>
  5113. <li>
  5114. <p><code>local</code>: ratelimits when users are joining rooms the server is already in.
  5115. Defaults to <code>per_second: 0.1</code>, <code>burst_count: 10</code>.</p>
  5116. </li>
  5117. <li>
  5118. <p><code>remote</code>: ratelimits when users are trying to join rooms not on the server (which
  5119. can be more computationally expensive than restricting locally). Defaults to
  5120. <code>per_second: 0.01</code>, <code>burst_count: 10</code></p>
  5121. </li>
  5122. </ul>
  5123. <p>Example configuration:</p>
  5124. <pre><code class="language-yaml">rc_joins:
  5125. local:
  5126. per_second: 0.2
  5127. burst_count: 15
  5128. remote:
  5129. per_second: 0.03
  5130. burst_count: 12
  5131. </code></pre>
  5132. <hr />
  5133. <h3 id="rc_joins_per_room"><a class="header" href="#rc_joins_per_room"><code>rc_joins_per_room</code></a></h3>
  5134. <p>This option allows admins to ratelimit joins to a room based on the number of recent
  5135. joins (local or remote) to that room. It is intended to mitigate mass-join spam
  5136. waves which target multiple homeservers.</p>
  5137. <p>By default, one join is permitted to a room every second, with an accumulating
  5138. buffer of up to ten instantaneous joins.</p>
  5139. <p>Example configuration (default values):</p>
  5140. <pre><code class="language-yaml">rc_joins_per_room:
  5141. per_second: 1
  5142. burst_count: 10
  5143. </code></pre>
  5144. <p><em>Added in Synapse 1.64.0.</em></p>
  5145. <hr />
  5146. <h3 id="rc_3pid_validation"><a class="header" href="#rc_3pid_validation"><code>rc_3pid_validation</code></a></h3>
  5147. <p>This option ratelimits how often a user or IP can attempt to validate a 3PID.
  5148. Defaults to <code>per_second: 0.003</code>, <code>burst_count: 5</code>.</p>
  5149. <p>Example configuration:</p>
  5150. <pre><code class="language-yaml">rc_3pid_validation:
  5151. per_second: 0.003
  5152. burst_count: 5
  5153. </code></pre>
  5154. <hr />
  5155. <h3 id="rc_invites"><a class="header" href="#rc_invites"><code>rc_invites</code></a></h3>
  5156. <p>This option sets ratelimiting how often invites can be sent in a room or to a
  5157. specific user. <code>per_room</code> defaults to <code>per_second: 0.3</code>, <code>burst_count: 10</code> and
  5158. <code>per_user</code> defaults to <code>per_second: 0.003</code>, <code>burst_count: 5</code>.</p>
  5159. <p>Client requests that invite user(s) when <a href="https://spec.matrix.org/v1.2/client-server-api/#post_matrixclientv3createroom">creating a
  5160. room</a>
  5161. will count against the <code>rc_invites.per_room</code> limit, whereas
  5162. client requests to <a href="https://spec.matrix.org/v1.2/client-server-api/#post_matrixclientv3roomsroomidinvite">invite a single user to a
  5163. room</a>
  5164. will count against both the <code>rc_invites.per_user</code> and <code>rc_invites.per_room</code> limits.</p>
  5165. <p>Federation requests to invite a user will count against the <code>rc_invites.per_user</code>
  5166. limit only, as Synapse presumes ratelimiting by room will be done by the sending server.</p>
  5167. <p>The <code>rc_invites.per_user</code> limit applies to the <em>receiver</em> of the invite, rather than the
  5168. sender, meaning that a <code>rc_invite.per_user.burst_count</code> of 5 mandates that a single user
  5169. cannot <em>receive</em> more than a burst of 5 invites at a time.</p>
  5170. <p>In contrast, the <code>rc_invites.per_issuer</code> limit applies to the <em>issuer</em> of the invite, meaning that a <code>rc_invite.per_issuer.burst_count</code> of 5 mandates that single user cannot <em>send</em> more than a burst of 5 invites at a time.</p>
  5171. <p><em>Changed in version 1.63:</em> added the <code>per_issuer</code> limit.</p>
  5172. <p>Example configuration:</p>
  5173. <pre><code class="language-yaml">rc_invites:
  5174. per_room:
  5175. per_second: 0.5
  5176. burst_count: 5
  5177. per_user:
  5178. per_second: 0.004
  5179. burst_count: 3
  5180. per_issuer:
  5181. per_second: 0.5
  5182. burst_count: 5
  5183. </code></pre>
  5184. <hr />
  5185. <h3 id="rc_third_party_invite"><a class="header" href="#rc_third_party_invite"><code>rc_third_party_invite</code></a></h3>
  5186. <p>This option ratelimits 3PID invites (i.e. invites sent to a third-party ID
  5187. such as an email address or a phone number) based on the account that's
  5188. sending the invite. Defaults to <code>per_second: 0.2</code>, <code>burst_count: 10</code>.</p>
  5189. <p>Example configuration:</p>
  5190. <pre><code class="language-yaml">rc_third_party_invite:
  5191. per_second: 0.2
  5192. burst_count: 10
  5193. </code></pre>
  5194. <hr />
  5195. <h3 id="rc_media_create"><a class="header" href="#rc_media_create"><code>rc_media_create</code></a></h3>
  5196. <p>This option ratelimits creation of MXC URIs via the <code>/_matrix/media/v1/create</code>
  5197. endpoint based on the account that's creating the media. Defaults to
  5198. <code>per_second: 10</code>, <code>burst_count: 50</code>.</p>
  5199. <p>Example configuration:</p>
  5200. <pre><code class="language-yaml">rc_media_create:
  5201. per_second: 10
  5202. burst_count: 50
  5203. </code></pre>
  5204. <hr />
  5205. <h3 id="rc_federation"><a class="header" href="#rc_federation"><code>rc_federation</code></a></h3>
  5206. <p>Defines limits on federation requests.</p>
  5207. <p>The <code>rc_federation</code> configuration has the following sub-options:</p>
  5208. <ul>
  5209. <li><code>window_size</code>: window size in milliseconds. Defaults to 1000.</li>
  5210. <li><code>sleep_limit</code>: number of federation requests from a single server in
  5211. a window before the server will delay processing the request. Defaults to 10.</li>
  5212. <li><code>sleep_delay</code>: duration in milliseconds to delay processing events
  5213. from remote servers by if they go over the sleep limit. Defaults to 500.</li>
  5214. <li><code>reject_limit</code>: maximum number of concurrent federation requests
  5215. allowed from a single server. Defaults to 50.</li>
  5216. <li><code>concurrent</code>: number of federation requests to concurrently process
  5217. from a single server. Defaults to 3.</li>
  5218. </ul>
  5219. <p>Example configuration:</p>
  5220. <pre><code class="language-yaml">rc_federation:
  5221. window_size: 750
  5222. sleep_limit: 15
  5223. sleep_delay: 400
  5224. reject_limit: 40
  5225. concurrent: 5
  5226. </code></pre>
  5227. <hr />
  5228. <h3 id="federation_rr_transactions_per_room_per_second"><a class="header" href="#federation_rr_transactions_per_room_per_second"><code>federation_rr_transactions_per_room_per_second</code></a></h3>
  5229. <p>Sets outgoing federation transaction frequency for sending read-receipts,
  5230. per-room.</p>
  5231. <p>If we end up trying to send out more read-receipts, they will get buffered up
  5232. into fewer transactions. Defaults to 50.</p>
  5233. <p>Example configuration:</p>
  5234. <pre><code class="language-yaml">federation_rr_transactions_per_room_per_second: 40
  5235. </code></pre>
  5236. <hr />
  5237. <h2 id="media-store"><a class="header" href="#media-store">Media Store</a></h2>
  5238. <p>Config options related to Synapse's media store.</p>
  5239. <hr />
  5240. <h3 id="enable_media_repo"><a class="header" href="#enable_media_repo"><code>enable_media_repo</code></a></h3>
  5241. <p>Enable the media store service in the Synapse master. Defaults to true.
  5242. Set to false if you are using a separate media store worker.</p>
  5243. <p>Example configuration:</p>
  5244. <pre><code class="language-yaml">enable_media_repo: false
  5245. </code></pre>
  5246. <hr />
  5247. <h3 id="media_store_path"><a class="header" href="#media_store_path"><code>media_store_path</code></a></h3>
  5248. <p>Directory where uploaded images and attachments are stored.</p>
  5249. <p>Example configuration:</p>
  5250. <pre><code class="language-yaml">media_store_path: &quot;DATADIR/media_store&quot;
  5251. </code></pre>
  5252. <hr />
  5253. <h3 id="max_pending_media_uploads"><a class="header" href="#max_pending_media_uploads"><code>max_pending_media_uploads</code></a></h3>
  5254. <p>How many <em>pending media uploads</em> can a given user have? A pending media upload
  5255. is a created MXC URI that (a) is not expired (the <code>unused_expires_at</code> timestamp
  5256. has not passed) and (b) the media has not yet been uploaded for. Defaults to 5.</p>
  5257. <p>Example configuration:</p>
  5258. <pre><code class="language-yaml">max_pending_media_uploads: 5
  5259. </code></pre>
  5260. <hr />
  5261. <h3 id="unused_expiration_time"><a class="header" href="#unused_expiration_time"><code>unused_expiration_time</code></a></h3>
  5262. <p>How long to wait in milliseconds before expiring created media IDs. Defaults to
  5263. &quot;24h&quot;</p>
  5264. <p>Example configuration:</p>
  5265. <pre><code class="language-yaml">unused_expiration_time: &quot;1h&quot;
  5266. </code></pre>
  5267. <hr />
  5268. <h3 id="media_storage_providers"><a class="header" href="#media_storage_providers"><code>media_storage_providers</code></a></h3>
  5269. <p>Media storage providers allow media to be stored in different
  5270. locations. Defaults to none. Associated sub-options are:</p>
  5271. <ul>
  5272. <li><code>module</code>: type of resource, e.g. <code>file_system</code>.</li>
  5273. <li><code>store_local</code>: whether to store newly uploaded local files</li>
  5274. <li><code>store_remote</code>: whether to store newly downloaded local files</li>
  5275. <li><code>store_synchronous</code>: whether to wait for successful storage for local uploads</li>
  5276. <li><code>config</code>: sets a path to the resource through the <code>directory</code> option</li>
  5277. </ul>
  5278. <p>Example configuration:</p>
  5279. <pre><code class="language-yaml">media_storage_providers:
  5280. - module: file_system
  5281. store_local: false
  5282. store_remote: false
  5283. store_synchronous: false
  5284. config:
  5285. directory: /mnt/some/other/directory
  5286. </code></pre>
  5287. <hr />
  5288. <h3 id="max_upload_size"><a class="header" href="#max_upload_size"><code>max_upload_size</code></a></h3>
  5289. <p>The largest allowed upload size in bytes.</p>
  5290. <p>If you are using a reverse proxy you may also need to set this value in
  5291. your reverse proxy's config. Defaults to 50M. Notably Nginx has a small max body size by default.
  5292. See <a href="usage/configuration/../../reverse_proxy.html">here</a> for more on using a reverse proxy with Synapse.</p>
  5293. <p>Example configuration:</p>
  5294. <pre><code class="language-yaml">max_upload_size: 60M
  5295. </code></pre>
  5296. <hr />
  5297. <h3 id="max_image_pixels"><a class="header" href="#max_image_pixels"><code>max_image_pixels</code></a></h3>
  5298. <p>Maximum number of pixels that will be thumbnailed. Defaults to 32M.</p>
  5299. <p>Example configuration:</p>
  5300. <pre><code class="language-yaml">max_image_pixels: 35M
  5301. </code></pre>
  5302. <hr />
  5303. <h3 id="prevent_media_downloads_from"><a class="header" href="#prevent_media_downloads_from"><code>prevent_media_downloads_from</code></a></h3>
  5304. <p>A list of domains to never download media from. Media from these
  5305. domains that is already downloaded will not be deleted, but will be
  5306. inaccessible to users. This option does not affect admin APIs trying
  5307. to download/operate on media.</p>
  5308. <p>This will not prevent the listed domains from accessing media themselves.
  5309. It simply prevents users on this server from downloading media originating
  5310. from the listed servers.</p>
  5311. <p>This will have no effect on media originating from the local server.
  5312. This only affects media downloaded from other Matrix servers, to
  5313. block domains from URL previews see <a href="usage/configuration/config_documentation.html#url_preview_url_blacklist"><code>url_preview_url_blacklist</code></a>.</p>
  5314. <p>Defaults to an empty list (nothing blocked).</p>
  5315. <p>Example configuration:</p>
  5316. <pre><code class="language-yaml">prevent_media_downloads_from:
  5317. - evil.example.org
  5318. - evil2.example.org
  5319. </code></pre>
  5320. <hr />
  5321. <h3 id="dynamic_thumbnails"><a class="header" href="#dynamic_thumbnails"><code>dynamic_thumbnails</code></a></h3>
  5322. <p>Whether to generate new thumbnails on the fly to precisely match
  5323. the resolution requested by the client. If true then whenever
  5324. a new resolution is requested by the client the server will
  5325. generate a new thumbnail. If false the server will pick a thumbnail
  5326. from a precalculated list. Defaults to false.</p>
  5327. <p>Example configuration:</p>
  5328. <pre><code class="language-yaml">dynamic_thumbnails: true
  5329. </code></pre>
  5330. <hr />
  5331. <h3 id="thumbnail_sizes"><a class="header" href="#thumbnail_sizes"><code>thumbnail_sizes</code></a></h3>
  5332. <p>List of thumbnails to precalculate when an image is uploaded. Associated sub-options are:</p>
  5333. <ul>
  5334. <li><code>width</code></li>
  5335. <li><code>height</code></li>
  5336. <li><code>method</code>: i.e. <code>crop</code>, <code>scale</code>, etc.</li>
  5337. </ul>
  5338. <p>Example configuration:</p>
  5339. <pre><code class="language-yaml">thumbnail_sizes:
  5340. - width: 32
  5341. height: 32
  5342. method: crop
  5343. - width: 96
  5344. height: 96
  5345. method: crop
  5346. - width: 320
  5347. height: 240
  5348. method: scale
  5349. - width: 640
  5350. height: 480
  5351. method: scale
  5352. - width: 800
  5353. height: 600
  5354. method: scale
  5355. </code></pre>
  5356. <hr />
  5357. <h3 id="media_retention"><a class="header" href="#media_retention"><code>media_retention</code></a></h3>
  5358. <p>Controls whether local media and entries in the remote media cache
  5359. (media that is downloaded from other homeservers) should be removed
  5360. under certain conditions, typically for the purpose of saving space.</p>
  5361. <p>Purging media files will be the carried out by the media worker
  5362. (that is, the worker that has the <code>enable_media_repo</code> homeserver config
  5363. option set to 'true'). This may be the main process.</p>
  5364. <p>The <code>media_retention.local_media_lifetime</code> and
  5365. <code>media_retention.remote_media_lifetime</code> config options control whether
  5366. media will be purged if it has not been accessed in a given amount of
  5367. time. Note that media is 'accessed' when loaded in a room in a client, or
  5368. otherwise downloaded by a local or remote user. If the media has never
  5369. been accessed, the media's creation time is used instead. Both thumbnails
  5370. and the original media will be removed. If either of these options are unset,
  5371. then media of that type will not be purged.</p>
  5372. <p>Local or cached remote media that has been
  5373. <a href="usage/configuration/../../admin_api/media_admin_api.html#quarantining-media-in-a-room">quarantined</a>
  5374. will not be deleted. Similarly, local media that has been marked as
  5375. <a href="usage/configuration/../../admin_api/media_admin_api.html#protecting-media-from-being-quarantined">protected from quarantine</a>
  5376. will not be deleted.</p>
  5377. <p>Example configuration:</p>
  5378. <pre><code class="language-yaml">media_retention:
  5379. local_media_lifetime: 90d
  5380. remote_media_lifetime: 14d
  5381. </code></pre>
  5382. <hr />
  5383. <h3 id="url_preview_enabled"><a class="header" href="#url_preview_enabled"><code>url_preview_enabled</code></a></h3>
  5384. <p>This setting determines whether the preview URL API is enabled.
  5385. It is disabled by default. Set to true to enable. If enabled you must specify a
  5386. <code>url_preview_ip_range_blacklist</code> blacklist.</p>
  5387. <p>Example configuration:</p>
  5388. <pre><code class="language-yaml">url_preview_enabled: true
  5389. </code></pre>
  5390. <hr />
  5391. <h3 id="url_preview_ip_range_blacklist"><a class="header" href="#url_preview_ip_range_blacklist"><code>url_preview_ip_range_blacklist</code></a></h3>
  5392. <p>List of IP address CIDR ranges that the URL preview spider is denied
  5393. from accessing. There are no defaults: you must explicitly
  5394. specify a list for URL previewing to work. You should specify any
  5395. internal services in your network that you do not want synapse to try
  5396. to connect to, otherwise anyone in any Matrix room could cause your
  5397. synapse to issue arbitrary GET requests to your internal services,
  5398. causing serious security issues.</p>
  5399. <p>(0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
  5400. listed here, since they correspond to unroutable addresses.)</p>
  5401. <p>This must be specified if <code>url_preview_enabled</code> is set. It is recommended that
  5402. you use the following example list as a starting point.</p>
  5403. <p>Note: The value is ignored when an HTTP proxy is in use.</p>
  5404. <p>Example configuration:</p>
  5405. <pre><code class="language-yaml">url_preview_ip_range_blacklist:
  5406. - '127.0.0.0/8'
  5407. - '10.0.0.0/8'
  5408. - '172.16.0.0/12'
  5409. - '192.168.0.0/16'
  5410. - '100.64.0.0/10'
  5411. - '192.0.0.0/24'
  5412. - '169.254.0.0/16'
  5413. - '192.88.99.0/24'
  5414. - '198.18.0.0/15'
  5415. - '192.0.2.0/24'
  5416. - '198.51.100.0/24'
  5417. - '203.0.113.0/24'
  5418. - '224.0.0.0/4'
  5419. - '::1/128'
  5420. - 'fe80::/10'
  5421. - 'fc00::/7'
  5422. - '2001:db8::/32'
  5423. - 'ff00::/8'
  5424. - 'fec0::/10'
  5425. </code></pre>
  5426. <hr />
  5427. <h3 id="url_preview_ip_range_whitelist"><a class="header" href="#url_preview_ip_range_whitelist"><code>url_preview_ip_range_whitelist</code></a></h3>
  5428. <p>This option sets a list of IP address CIDR ranges that the URL preview spider is allowed
  5429. to access even if they are specified in <code>url_preview_ip_range_blacklist</code>.
  5430. This is useful for specifying exceptions to wide-ranging blacklisted
  5431. target IP ranges - e.g. for enabling URL previews for a specific private
  5432. website only visible in your network. Defaults to none.</p>
  5433. <p>Example configuration:</p>
  5434. <pre><code class="language-yaml">url_preview_ip_range_whitelist:
  5435. - '192.168.1.1'
  5436. </code></pre>
  5437. <hr />
  5438. <h3 id="url_preview_url_blacklist"><a class="header" href="#url_preview_url_blacklist"><code>url_preview_url_blacklist</code></a></h3>
  5439. <p>Optional list of URL matches that the URL preview spider is
  5440. denied from accessing. You should use <code>url_preview_ip_range_blacklist</code>
  5441. in preference to this, otherwise someone could define a public DNS
  5442. entry that points to a private IP address and circumvent the blacklist.
  5443. This is more useful if you know there is an entire shape of URL that
  5444. you know that will never want synapse to try to spider.</p>
  5445. <p>Each list entry is a dictionary of url component attributes as returned
  5446. by urlparse.urlsplit as applied to the absolute form of the URL. See
  5447. <a href="https://docs.python.org/2/library/urlparse.html#urlparse.urlsplit">here</a> for more
  5448. information. Some examples are:</p>
  5449. <ul>
  5450. <li><code>username</code></li>
  5451. <li><code>netloc</code></li>
  5452. <li><code>scheme</code></li>
  5453. <li><code>path</code></li>
  5454. </ul>
  5455. <p>The values of the dictionary are treated as a filename match pattern
  5456. applied to that component of URLs, unless they start with a ^ in which
  5457. case they are treated as a regular expression match. If all the
  5458. specified component matches for a given list item succeed, the URL is
  5459. blacklisted.</p>
  5460. <p>Example configuration:</p>
  5461. <pre><code class="language-yaml">url_preview_url_blacklist:
  5462. # blacklist any URL with a username in its URI
  5463. - username: '*'
  5464. # blacklist all *.google.com URLs
  5465. - netloc: 'google.com'
  5466. - netloc: '*.google.com'
  5467. # blacklist all plain HTTP URLs
  5468. - scheme: 'http'
  5469. # blacklist http(s)://www.acme.com/foo
  5470. - netloc: 'www.acme.com'
  5471. path: '/foo'
  5472. # blacklist any URL with a literal IPv4 address
  5473. - netloc: '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'
  5474. </code></pre>
  5475. <hr />
  5476. <h3 id="max_spider_size"><a class="header" href="#max_spider_size"><code>max_spider_size</code></a></h3>
  5477. <p>The largest allowed URL preview spidering size in bytes. Defaults to 10M.</p>
  5478. <p>Example configuration:</p>
  5479. <pre><code class="language-yaml">max_spider_size: 8M
  5480. </code></pre>
  5481. <hr />
  5482. <h3 id="url_preview_accept_language"><a class="header" href="#url_preview_accept_language"><code>url_preview_accept_language</code></a></h3>
  5483. <p>A list of values for the Accept-Language HTTP header used when
  5484. downloading webpages during URL preview generation. This allows
  5485. Synapse to specify the preferred languages that URL previews should
  5486. be in when communicating with remote servers.</p>
  5487. <p>Each value is a IETF language tag; a 2-3 letter identifier for a
  5488. language, optionally followed by subtags separated by '-', specifying
  5489. a country or region variant.</p>
  5490. <p>Multiple values can be provided, and a weight can be added to each by
  5491. using quality value syntax (;q=). '*' translates to any language.</p>
  5492. <p>Defaults to &quot;en&quot;.</p>
  5493. <p>Example configuration:</p>
  5494. <pre><code class="language-yaml"> url_preview_accept_language:
  5495. - 'en-UK'
  5496. - 'en-US;q=0.9'
  5497. - 'fr;q=0.8'
  5498. - '*;q=0.7'
  5499. </code></pre>
  5500. <hr />
  5501. <h3 id="oembed"><a class="header" href="#oembed"><code>oembed</code></a></h3>
  5502. <p>oEmbed allows for easier embedding content from a website. It can be
  5503. used for generating URLs previews of services which support it. A default list of oEmbed providers
  5504. is included with Synapse. Set <code>disable_default_providers</code> to true to disable using
  5505. these default oEmbed URLs. Use <code>additional_providers</code> to specify additional files with oEmbed configuration (each
  5506. should be in the form of providers.json). By default this list is empty.</p>
  5507. <p>Example configuration:</p>
  5508. <pre><code class="language-yaml">oembed:
  5509. disable_default_providers: true
  5510. additional_providers:
  5511. - oembed/my_providers.json
  5512. </code></pre>
  5513. <hr />
  5514. <h2 id="captcha"><a class="header" href="#captcha">Captcha</a></h2>
  5515. <p>See <a href="usage/configuration/../../CAPTCHA_SETUP.html">here</a> for full details on setting up captcha.</p>
  5516. <hr />
  5517. <h3 id="recaptcha_public_key"><a class="header" href="#recaptcha_public_key"><code>recaptcha_public_key</code></a></h3>
  5518. <p>This homeserver's ReCAPTCHA public key. Must be specified if
  5519. <a href="usage/configuration/config_documentation.html#enable_registration_captcha"><code>enable_registration_captcha</code></a> is enabled.</p>
  5520. <p>Example configuration:</p>
  5521. <pre><code class="language-yaml">recaptcha_public_key: &quot;YOUR_PUBLIC_KEY&quot;
  5522. </code></pre>
  5523. <hr />
  5524. <h3 id="recaptcha_private_key"><a class="header" href="#recaptcha_private_key"><code>recaptcha_private_key</code></a></h3>
  5525. <p>This homeserver's ReCAPTCHA private key. Must be specified if
  5526. <a href="usage/configuration/config_documentation.html#enable_registration_captcha"><code>enable_registration_captcha</code></a> is
  5527. enabled.</p>
  5528. <p>Example configuration:</p>
  5529. <pre><code class="language-yaml">recaptcha_private_key: &quot;YOUR_PRIVATE_KEY&quot;
  5530. </code></pre>
  5531. <hr />
  5532. <h3 id="enable_registration_captcha"><a class="header" href="#enable_registration_captcha"><code>enable_registration_captcha</code></a></h3>
  5533. <p>Set to <code>true</code> to require users to complete a CAPTCHA test when registering an account.
  5534. Requires a valid ReCaptcha public/private key.
  5535. Defaults to <code>false</code>.</p>
  5536. <p>Note that <a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a> must also be set to allow account registration.</p>
  5537. <p>Example configuration:</p>
  5538. <pre><code class="language-yaml">enable_registration_captcha: true
  5539. </code></pre>
  5540. <hr />
  5541. <h3 id="recaptcha_siteverify_api"><a class="header" href="#recaptcha_siteverify_api"><code>recaptcha_siteverify_api</code></a></h3>
  5542. <p>The API endpoint to use for verifying <code>m.login.recaptcha</code> responses.
  5543. Defaults to <code>https://www.recaptcha.net/recaptcha/api/siteverify</code>.</p>
  5544. <p>Example configuration:</p>
  5545. <pre><code class="language-yaml">recaptcha_siteverify_api: &quot;https://my.recaptcha.site&quot;
  5546. </code></pre>
  5547. <hr />
  5548. <h2 id="turn"><a class="header" href="#turn">TURN</a></h2>
  5549. <p>Options related to adding a TURN server to Synapse.</p>
  5550. <hr />
  5551. <h3 id="turn_uris"><a class="header" href="#turn_uris"><code>turn_uris</code></a></h3>
  5552. <p>The public URIs of the TURN server to give to clients.</p>
  5553. <p>Example configuration:</p>
  5554. <pre><code class="language-yaml">turn_uris: [turn:example.org]
  5555. </code></pre>
  5556. <hr />
  5557. <h3 id="turn_shared_secret"><a class="header" href="#turn_shared_secret"><code>turn_shared_secret</code></a></h3>
  5558. <p>The shared secret used to compute passwords for the TURN server.</p>
  5559. <p>Example configuration:</p>
  5560. <pre><code class="language-yaml">turn_shared_secret: &quot;YOUR_SHARED_SECRET&quot;
  5561. </code></pre>
  5562. <hr />
  5563. <h3 id="turn_username-and-turn_password"><a class="header" href="#turn_username-and-turn_password"><code>turn_username</code> and <code>turn_password</code></a></h3>
  5564. <p>The Username and password if the TURN server needs them and does not use a token.</p>
  5565. <p>Example configuration:</p>
  5566. <pre><code class="language-yaml">turn_username: &quot;TURNSERVER_USERNAME&quot;
  5567. turn_password: &quot;TURNSERVER_PASSWORD&quot;
  5568. </code></pre>
  5569. <hr />
  5570. <h3 id="turn_user_lifetime"><a class="header" href="#turn_user_lifetime"><code>turn_user_lifetime</code></a></h3>
  5571. <p>How long generated TURN credentials last. Defaults to 1h.</p>
  5572. <p>Example configuration:</p>
  5573. <pre><code class="language-yaml">turn_user_lifetime: 2h
  5574. </code></pre>
  5575. <hr />
  5576. <h3 id="turn_allow_guests"><a class="header" href="#turn_allow_guests"><code>turn_allow_guests</code></a></h3>
  5577. <p>Whether guests should be allowed to use the TURN server. This defaults to true, otherwise
  5578. VoIP will be unreliable for guests. However, it does introduce a slight security risk as
  5579. it allows users to connect to arbitrary endpoints without having first signed up for a valid account (e.g. by passing a CAPTCHA).</p>
  5580. <p>Example configuration:</p>
  5581. <pre><code class="language-yaml">turn_allow_guests: false
  5582. </code></pre>
  5583. <hr />
  5584. <h2 id="registration"><a class="header" href="#registration">Registration</a></h2>
  5585. <p>Registration can be rate-limited using the parameters in the <a href="usage/configuration/config_documentation.html#ratelimiting">Ratelimiting</a> section of this manual.</p>
  5586. <hr />
  5587. <h3 id="enable_registration"><a class="header" href="#enable_registration"><code>enable_registration</code></a></h3>
  5588. <p>Enable registration for new users. Defaults to <code>false</code>.</p>
  5589. <p>It is highly recommended that if you enable registration, you set one or more
  5590. or the following options, to avoid abuse of your server by &quot;bots&quot;:</p>
  5591. <ul>
  5592. <li><a href="usage/configuration/config_documentation.html#enable_registration_captcha"><code>enable_registration_captcha</code></a></li>
  5593. <li><a href="usage/configuration/config_documentation.html#registrations_require_3pid"><code>registrations_require_3pid</code></a></li>
  5594. <li><a href="usage/configuration/config_documentation.html#registration_requires_token"><code>registration_requires_token</code></a></li>
  5595. </ul>
  5596. <p>(In order to enable registration without any verification, you must also set
  5597. <a href="usage/configuration/config_documentation.html#enable_registration_without_verification"><code>enable_registration_without_verification</code></a>.)</p>
  5598. <p>Note that even if this setting is disabled, new accounts can still be created
  5599. via the admin API if
  5600. <a href="usage/configuration/config_documentation.html#registration_shared_secret"><code>registration_shared_secret</code></a> is set.</p>
  5601. <p>Example configuration:</p>
  5602. <pre><code class="language-yaml">enable_registration: true
  5603. </code></pre>
  5604. <hr />
  5605. <h3 id="enable_registration_without_verification"><a class="header" href="#enable_registration_without_verification"><code>enable_registration_without_verification</code></a></h3>
  5606. <p>Enable registration without email or captcha verification. Note: this option is <em>not</em> recommended,
  5607. as registration without verification is a known vector for spam and abuse. Defaults to <code>false</code>. Has no effect
  5608. unless <a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a> is also enabled.</p>
  5609. <p>Example configuration:</p>
  5610. <pre><code class="language-yaml">enable_registration_without_verification: true
  5611. </code></pre>
  5612. <hr />
  5613. <h3 id="registrations_require_3pid"><a class="header" href="#registrations_require_3pid"><code>registrations_require_3pid</code></a></h3>
  5614. <p>If this is set, users must provide all of the specified types of 3PID when registering an account.</p>
  5615. <p>Note that <a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a> must also be set to allow account registration.</p>
  5616. <p>Example configuration:</p>
  5617. <pre><code class="language-yaml">registrations_require_3pid:
  5618. - email
  5619. - msisdn
  5620. </code></pre>
  5621. <hr />
  5622. <h3 id="disable_msisdn_registration"><a class="header" href="#disable_msisdn_registration"><code>disable_msisdn_registration</code></a></h3>
  5623. <p>Explicitly disable asking for MSISDNs from the registration
  5624. flow (overrides <code>registrations_require_3pid</code> if MSISDNs are set as required).</p>
  5625. <p>Example configuration:</p>
  5626. <pre><code class="language-yaml">disable_msisdn_registration: true
  5627. </code></pre>
  5628. <hr />
  5629. <h3 id="allowed_local_3pids"><a class="header" href="#allowed_local_3pids"><code>allowed_local_3pids</code></a></h3>
  5630. <p>Mandate that users are only allowed to associate certain formats of
  5631. 3PIDs with accounts on this server, as specified by the <code>medium</code> and <code>pattern</code> sub-options.</p>
  5632. <p>Example configuration:</p>
  5633. <pre><code class="language-yaml">allowed_local_3pids:
  5634. - medium: email
  5635. pattern: '^[^@]+@matrix\.org$'
  5636. - medium: email
  5637. pattern: '^[^@]+@vector\.im$'
  5638. - medium: msisdn
  5639. pattern: '\+44'
  5640. </code></pre>
  5641. <hr />
  5642. <h3 id="enable_3pid_lookup"><a class="header" href="#enable_3pid_lookup"><code>enable_3pid_lookup</code></a></h3>
  5643. <p>Enable 3PIDs lookup requests to identity servers from this server. Defaults to true.</p>
  5644. <p>Example configuration:</p>
  5645. <pre><code class="language-yaml">enable_3pid_lookup: false
  5646. </code></pre>
  5647. <hr />
  5648. <h3 id="registration_requires_token"><a class="header" href="#registration_requires_token"><code>registration_requires_token</code></a></h3>
  5649. <p>Require users to submit a token during registration.
  5650. Tokens can be managed using the admin <a href="usage/configuration/../administration/admin_api/registration_tokens.html">API</a>.
  5651. Disabling this option will not delete any tokens previously generated.
  5652. Defaults to <code>false</code>. Set to <code>true</code> to enable.</p>
  5653. <p>Note that <a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a> must also be set to allow account registration.</p>
  5654. <p>Example configuration:</p>
  5655. <pre><code class="language-yaml">registration_requires_token: true
  5656. </code></pre>
  5657. <hr />
  5658. <h3 id="registration_shared_secret"><a class="header" href="#registration_shared_secret"><code>registration_shared_secret</code></a></h3>
  5659. <p>If set, allows registration of standard or admin accounts by anyone who has the
  5660. shared secret, even if <a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a> is not
  5661. set.</p>
  5662. <p>This is primarily intended for use with the <code>register_new_matrix_user</code> script
  5663. (see <a href="usage/configuration/../../setup/installation.html#registering-a-user">Registering a user</a>);
  5664. however, the interface is <a href="usage/configuration/../../admin_api/register_api.html">documented</a>.</p>
  5665. <p>See also <a href="usage/configuration/config_documentation.html#registration_shared_secret_path"><code>registration_shared_secret_path</code></a>.</p>
  5666. <p>Example configuration:</p>
  5667. <pre><code class="language-yaml">registration_shared_secret: &lt;PRIVATE STRING&gt;
  5668. </code></pre>
  5669. <hr />
  5670. <h3 id="registration_shared_secret_path"><a class="header" href="#registration_shared_secret_path"><code>registration_shared_secret_path</code></a></h3>
  5671. <p>An alternative to <a href="usage/configuration/config_documentation.html#registration_shared_secret"><code>registration_shared_secret</code></a>:
  5672. allows the shared secret to be specified in an external file.</p>
  5673. <p>The file should be a plain text file, containing only the shared secret.</p>
  5674. <p>If this file does not exist, Synapse will create a new shared
  5675. secret on startup and store it in this file.</p>
  5676. <p>Example configuration:</p>
  5677. <pre><code class="language-yaml">registration_shared_secret_path: /path/to/secrets/file
  5678. </code></pre>
  5679. <p><em>Added in Synapse 1.67.0.</em></p>
  5680. <hr />
  5681. <h3 id="bcrypt_rounds"><a class="header" href="#bcrypt_rounds"><code>bcrypt_rounds</code></a></h3>
  5682. <p>Set the number of bcrypt rounds used to generate password hash.
  5683. Larger numbers increase the work factor needed to generate the hash.
  5684. The default number is 12 (which equates to 2^12 rounds).
  5685. N.B. that increasing this will exponentially increase the time required
  5686. to register or login - e.g. 24 =&gt; 2^24 rounds which will take &gt;20 mins.
  5687. Example configuration:</p>
  5688. <pre><code class="language-yaml">bcrypt_rounds: 14
  5689. </code></pre>
  5690. <hr />
  5691. <h3 id="allow_guest_access"><a class="header" href="#allow_guest_access"><code>allow_guest_access</code></a></h3>
  5692. <p>Allows users to register as guests without a password/email/etc, and
  5693. participate in rooms hosted on this server which have been made
  5694. accessible to anonymous users. Defaults to false.</p>
  5695. <p>Example configuration:</p>
  5696. <pre><code class="language-yaml">allow_guest_access: true
  5697. </code></pre>
  5698. <hr />
  5699. <h3 id="default_identity_server"><a class="header" href="#default_identity_server"><code>default_identity_server</code></a></h3>
  5700. <p>The identity server which we suggest that clients should use when users log
  5701. in on this server.</p>
  5702. <p>(By default, no suggestion is made, so it is left up to the client.
  5703. This setting is ignored unless <code>public_baseurl</code> is also explicitly set.)</p>
  5704. <p>Example configuration:</p>
  5705. <pre><code class="language-yaml">default_identity_server: https://matrix.org
  5706. </code></pre>
  5707. <hr />
  5708. <h3 id="account_threepid_delegates"><a class="header" href="#account_threepid_delegates"><code>account_threepid_delegates</code></a></h3>
  5709. <p>Delegate verification of phone numbers to an identity server.</p>
  5710. <p>When a user wishes to add a phone number to their account, we need to verify that they
  5711. actually own that phone number, which requires sending them a text message (SMS).
  5712. Currently Synapse does not support sending those texts itself and instead delegates the
  5713. task to an identity server. The base URI for the identity server to be used is
  5714. specified by the <code>account_threepid_delegates.msisdn</code> option.</p>
  5715. <p>If this is left unspecified, Synapse will not allow users to add phone numbers to
  5716. their account.</p>
  5717. <p>(Servers handling the these requests must answer the <code>/requestToken</code> endpoints defined
  5718. by the Matrix Identity Service API
  5719. <a href="https://matrix.org/docs/spec/identity_service/latest">specification</a>.)</p>
  5720. <p><em>Deprecated in Synapse 1.64.0</em>: The <code>email</code> option is deprecated.</p>
  5721. <p><em>Removed in Synapse 1.66.0</em>: The <code>email</code> option has been removed.
  5722. If present, Synapse will report a configuration error on startup.</p>
  5723. <p>Example configuration:</p>
  5724. <pre><code class="language-yaml">account_threepid_delegates:
  5725. msisdn: http://localhost:8090 # Delegate SMS sending to this local process
  5726. </code></pre>
  5727. <hr />
  5728. <h3 id="enable_set_displayname"><a class="header" href="#enable_set_displayname"><code>enable_set_displayname</code></a></h3>
  5729. <p>Whether users are allowed to change their displayname after it has
  5730. been initially set. Useful when provisioning users based on the
  5731. contents of a third-party directory.</p>
  5732. <p>Does not apply to server administrators. Defaults to true.</p>
  5733. <p>Example configuration:</p>
  5734. <pre><code class="language-yaml">enable_set_displayname: false
  5735. </code></pre>
  5736. <hr />
  5737. <h3 id="enable_set_avatar_url"><a class="header" href="#enable_set_avatar_url"><code>enable_set_avatar_url</code></a></h3>
  5738. <p>Whether users are allowed to change their avatar after it has been
  5739. initially set. Useful when provisioning users based on the contents
  5740. of a third-party directory.</p>
  5741. <p>Does not apply to server administrators. Defaults to true.</p>
  5742. <p>Example configuration:</p>
  5743. <pre><code class="language-yaml">enable_set_avatar_url: false
  5744. </code></pre>
  5745. <hr />
  5746. <h3 id="enable_3pid_changes"><a class="header" href="#enable_3pid_changes"><code>enable_3pid_changes</code></a></h3>
  5747. <p>Whether users can change the third-party IDs associated with their accounts
  5748. (email address and msisdn).</p>
  5749. <p>Defaults to true.</p>
  5750. <p>Example configuration:</p>
  5751. <pre><code class="language-yaml">enable_3pid_changes: false
  5752. </code></pre>
  5753. <hr />
  5754. <h3 id="auto_join_rooms"><a class="header" href="#auto_join_rooms"><code>auto_join_rooms</code></a></h3>
  5755. <p>Users who register on this homeserver will automatically be joined
  5756. to the rooms listed under this option.</p>
  5757. <p>By default, any room aliases included in this list will be created
  5758. as a publicly joinable room when the first user registers for the
  5759. homeserver. If the room already exists, make certain it is a publicly joinable
  5760. room, i.e. the join rule of the room must be set to 'public'. You can find more options
  5761. relating to auto-joining rooms below.</p>
  5762. <p>As Spaces are just rooms under the hood, Space aliases may also be
  5763. used.</p>
  5764. <p>Example configuration:</p>
  5765. <pre><code class="language-yaml">auto_join_rooms:
  5766. - &quot;#exampleroom:example.com&quot;
  5767. - &quot;#anotherexampleroom:example.com&quot;
  5768. </code></pre>
  5769. <hr />
  5770. <h3 id="autocreate_auto_join_rooms"><a class="header" href="#autocreate_auto_join_rooms"><code>autocreate_auto_join_rooms</code></a></h3>
  5771. <p>Where <code>auto_join_rooms</code> are specified, setting this flag ensures that
  5772. the rooms exist by creating them when the first user on the
  5773. homeserver registers. This option will not create Spaces.</p>
  5774. <p>By default the auto-created rooms are publicly joinable from any federated
  5775. server. Use the <code>autocreate_auto_join_rooms_federated</code> and
  5776. <code>autocreate_auto_join_room_preset</code> settings to customise this behaviour.</p>
  5777. <p>Setting to false means that if the rooms are not manually created,
  5778. users cannot be auto-joined since they do not exist.</p>
  5779. <p>Defaults to true.</p>
  5780. <p>Example configuration:</p>
  5781. <pre><code class="language-yaml">autocreate_auto_join_rooms: false
  5782. </code></pre>
  5783. <hr />
  5784. <h3 id="autocreate_auto_join_rooms_federated"><a class="header" href="#autocreate_auto_join_rooms_federated"><code>autocreate_auto_join_rooms_federated</code></a></h3>
  5785. <p>Whether the rooms listed in <code>auto_join_rooms</code> that are auto-created are available
  5786. via federation. Only has an effect if <code>autocreate_auto_join_rooms</code> is true.</p>
  5787. <p>Note that whether a room is federated cannot be modified after
  5788. creation.</p>
  5789. <p>Defaults to true: the room will be joinable from other servers.
  5790. Set to false to prevent users from other homeservers from
  5791. joining these rooms.</p>
  5792. <p>Example configuration:</p>
  5793. <pre><code class="language-yaml">autocreate_auto_join_rooms_federated: false
  5794. </code></pre>
  5795. <hr />
  5796. <h3 id="autocreate_auto_join_room_preset"><a class="header" href="#autocreate_auto_join_room_preset"><code>autocreate_auto_join_room_preset</code></a></h3>
  5797. <p>The room preset to use when auto-creating one of <code>auto_join_rooms</code>. Only has an
  5798. effect if <code>autocreate_auto_join_rooms</code> is true.</p>
  5799. <p>Possible values for this option are:</p>
  5800. <ul>
  5801. <li>&quot;public_chat&quot;: the room is joinable by anyone, including
  5802. federated servers if <code>autocreate_auto_join_rooms_federated</code> is true (the default).</li>
  5803. <li>&quot;private_chat&quot;: an invitation is required to join these rooms.</li>
  5804. <li>&quot;trusted_private_chat&quot;: an invitation is required to join this room and the invitee is
  5805. assigned a power level of 100 upon joining the room.</li>
  5806. </ul>
  5807. <p>If a value of &quot;private_chat&quot; or &quot;trusted_private_chat&quot; is used then
  5808. <code>auto_join_mxid_localpart</code> must also be configured.</p>
  5809. <p>Defaults to &quot;public_chat&quot;.</p>
  5810. <p>Example configuration:</p>
  5811. <pre><code class="language-yaml">autocreate_auto_join_room_preset: private_chat
  5812. </code></pre>
  5813. <hr />
  5814. <h3 id="auto_join_mxid_localpart"><a class="header" href="#auto_join_mxid_localpart"><code>auto_join_mxid_localpart</code></a></h3>
  5815. <p>The local part of the user id which is used to create <code>auto_join_rooms</code> if
  5816. <code>autocreate_auto_join_rooms</code> is true. If this is not provided then the
  5817. initial user account that registers will be used to create the rooms.</p>
  5818. <p>The user id is also used to invite new users to any auto-join rooms which
  5819. are set to invite-only.</p>
  5820. <p>It <em>must</em> be configured if <code>autocreate_auto_join_room_preset</code> is set to
  5821. &quot;private_chat&quot; or &quot;trusted_private_chat&quot;.</p>
  5822. <p>Note that this must be specified in order for new users to be correctly
  5823. invited to any auto-join rooms which have been set to invite-only (either
  5824. at the time of creation or subsequently).</p>
  5825. <p>Note that, if the room already exists, this user must be joined and
  5826. have the appropriate permissions to invite new members.</p>
  5827. <p>Example configuration:</p>
  5828. <pre><code class="language-yaml">auto_join_mxid_localpart: system
  5829. </code></pre>
  5830. <hr />
  5831. <h3 id="auto_join_rooms_for_guests"><a class="header" href="#auto_join_rooms_for_guests"><code>auto_join_rooms_for_guests</code></a></h3>
  5832. <p>When <code>auto_join_rooms</code> is specified, setting this flag to false prevents
  5833. guest accounts from being automatically joined to the rooms.</p>
  5834. <p>Defaults to true.</p>
  5835. <p>Example configuration:</p>
  5836. <pre><code class="language-yaml">auto_join_rooms_for_guests: false
  5837. </code></pre>
  5838. <hr />
  5839. <h3 id="inhibit_user_in_use_error"><a class="header" href="#inhibit_user_in_use_error"><code>inhibit_user_in_use_error</code></a></h3>
  5840. <p>Whether to inhibit errors raised when registering a new account if the user ID
  5841. already exists. If turned on, requests to <code>/register/available</code> will always
  5842. show a user ID as available, and Synapse won't raise an error when starting
  5843. a registration with a user ID that already exists. However, Synapse will still
  5844. raise an error if the registration completes and the username conflicts.</p>
  5845. <p>Defaults to false.</p>
  5846. <p>Example configuration:</p>
  5847. <pre><code class="language-yaml">inhibit_user_in_use_error: true
  5848. </code></pre>
  5849. <hr />
  5850. <h2 id="user-session-management"><a class="header" href="#user-session-management">User session management</a></h2>
  5851. <hr />
  5852. <h3 id="session_lifetime"><a class="header" href="#session_lifetime"><code>session_lifetime</code></a></h3>
  5853. <p>Time that a user's session remains valid for, after they log in.</p>
  5854. <p>Note that this is not currently compatible with guest logins.</p>
  5855. <p>Note also that this is calculated at login time: changes are not applied retrospectively to users who have already
  5856. logged in.</p>
  5857. <p>By default, this is infinite.</p>
  5858. <p>Example configuration:</p>
  5859. <pre><code class="language-yaml">session_lifetime: 24h
  5860. </code></pre>
  5861. <hr />
  5862. <h3 id="refresh_access_token_lifetime"><a class="header" href="#refresh_access_token_lifetime"><code>refresh_access_token_lifetime</code></a></h3>
  5863. <p>Time that an access token remains valid for, if the session is using refresh tokens.</p>
  5864. <p>For more information about refresh tokens, please see the <a href="usage/configuration/user_authentication/refresh_tokens.html">manual</a>.</p>
  5865. <p>Note that this only applies to clients which advertise support for refresh tokens.</p>
  5866. <p>Note also that this is calculated at login time and refresh time: changes are not applied to
  5867. existing sessions until they are refreshed.</p>
  5868. <p>By default, this is 5 minutes.</p>
  5869. <p>Example configuration:</p>
  5870. <pre><code class="language-yaml">refreshable_access_token_lifetime: 10m
  5871. </code></pre>
  5872. <hr />
  5873. <h3 id="refresh_token_lifetime-24h"><a class="header" href="#refresh_token_lifetime-24h"><code>refresh_token_lifetime: 24h</code></a></h3>
  5874. <p>Time that a refresh token remains valid for (provided that it is not
  5875. exchanged for another one first).
  5876. This option can be used to automatically log-out inactive sessions.
  5877. Please see the manual for more information.</p>
  5878. <p>Note also that this is calculated at login time and refresh time:
  5879. changes are not applied to existing sessions until they are refreshed.</p>
  5880. <p>By default, this is infinite.</p>
  5881. <p>Example configuration:</p>
  5882. <pre><code class="language-yaml">refresh_token_lifetime: 24h
  5883. </code></pre>
  5884. <hr />
  5885. <h3 id="nonrefreshable_access_token_lifetime"><a class="header" href="#nonrefreshable_access_token_lifetime"><code>nonrefreshable_access_token_lifetime</code></a></h3>
  5886. <p>Time that an access token remains valid for, if the session is NOT
  5887. using refresh tokens.</p>
  5888. <p>Please note that not all clients support refresh tokens, so setting
  5889. this to a short value may be inconvenient for some users who will
  5890. then be logged out frequently.</p>
  5891. <p>Note also that this is calculated at login time: changes are not applied
  5892. retrospectively to existing sessions for users that have already logged in.</p>
  5893. <p>By default, this is infinite.</p>
  5894. <p>Example configuration:</p>
  5895. <pre><code class="language-yaml">nonrefreshable_access_token_lifetime: 24h
  5896. </code></pre>
  5897. <hr />
  5898. <h3 id="ui_auth"><a class="header" href="#ui_auth"><code>ui_auth</code></a></h3>
  5899. <p>The amount of time to allow a user-interactive authentication session to be active.</p>
  5900. <p>This defaults to 0, meaning the user is queried for their credentials
  5901. before every action, but this can be overridden to allow a single
  5902. validation to be re-used. This weakens the protections afforded by
  5903. the user-interactive authentication process, by allowing for multiple
  5904. (and potentially different) operations to use the same validation session.</p>
  5905. <p>This is ignored for potentially &quot;dangerous&quot; operations (including
  5906. deactivating an account, modifying an account password, adding a 3PID,
  5907. and minting additional login tokens).</p>
  5908. <p>Use the <code>session_timeout</code> sub-option here to change the time allowed for credential validation.</p>
  5909. <p>Example configuration:</p>
  5910. <pre><code class="language-yaml">ui_auth:
  5911. session_timeout: &quot;15s&quot;
  5912. </code></pre>
  5913. <hr />
  5914. <h3 id="login_via_existing_session"><a class="header" href="#login_via_existing_session"><code>login_via_existing_session</code></a></h3>
  5915. <p>Matrix supports the ability of an existing session to mint a login token for
  5916. another client.</p>
  5917. <p>Synapse disables this by default as it has security ramifications -- a malicious
  5918. client could use the mechanism to spawn more than one session.</p>
  5919. <p>The duration of time the generated token is valid for can be configured with the
  5920. <code>token_timeout</code> sub-option.</p>
  5921. <p>User-interactive authentication is required when this is enabled unless the
  5922. <code>require_ui_auth</code> sub-option is set to <code>False</code>.</p>
  5923. <p>Example configuration:</p>
  5924. <pre><code class="language-yaml">login_via_existing_session:
  5925. enabled: true
  5926. require_ui_auth: false
  5927. token_timeout: &quot;5m&quot;
  5928. </code></pre>
  5929. <hr />
  5930. <h2 id="metrics"><a class="header" href="#metrics">Metrics</a></h2>
  5931. <p>Config options related to metrics.</p>
  5932. <hr />
  5933. <h3 id="enable_metrics"><a class="header" href="#enable_metrics"><code>enable_metrics</code></a></h3>
  5934. <p>Set to true to enable collection and rendering of performance metrics.
  5935. Defaults to false.</p>
  5936. <p>Example configuration:</p>
  5937. <pre><code class="language-yaml">enable_metrics: true
  5938. </code></pre>
  5939. <hr />
  5940. <h3 id="sentry"><a class="header" href="#sentry"><code>sentry</code></a></h3>
  5941. <p>Use this option to enable sentry integration. Provide the DSN assigned to you by sentry
  5942. with the <code>dsn</code> setting.</p>
  5943. <p>NOTE: While attempts are made to ensure that the logs don't contain
  5944. any sensitive information, this cannot be guaranteed. By enabling
  5945. this option the sentry server may therefore receive sensitive
  5946. information, and it in turn may then disseminate sensitive information
  5947. through insecure notification channels if so configured.</p>
  5948. <p>Example configuration:</p>
  5949. <pre><code class="language-yaml">sentry:
  5950. dsn: &quot;...&quot;
  5951. </code></pre>
  5952. <hr />
  5953. <h3 id="metrics_flags"><a class="header" href="#metrics_flags"><code>metrics_flags</code></a></h3>
  5954. <p>Flags to enable Prometheus metrics which are not suitable to be
  5955. enabled by default, either for performance reasons or limited use.
  5956. Currently the only option is <code>known_servers</code>, which publishes
  5957. <code>synapse_federation_known_servers</code>, a gauge of the number of
  5958. servers this homeserver knows about, including itself. May cause
  5959. performance problems on large homeservers.</p>
  5960. <p>Example configuration:</p>
  5961. <pre><code class="language-yaml">metrics_flags:
  5962. known_servers: true
  5963. </code></pre>
  5964. <hr />
  5965. <h3 id="report_stats"><a class="header" href="#report_stats"><code>report_stats</code></a></h3>
  5966. <p>Whether or not to report homeserver usage statistics. This is originally
  5967. set when generating the config. Set this option to true or false to change the current
  5968. behavior. See
  5969. <a href="usage/configuration/../administration/monitoring/reporting_homeserver_usage_statistics.html">Reporting Homeserver Usage Statistics</a>
  5970. for information on what data is reported.</p>
  5971. <p>Statistics will be reported 5 minutes after Synapse starts, and then every 3 hours
  5972. after that.</p>
  5973. <p>Example configuration:</p>
  5974. <pre><code class="language-yaml">report_stats: true
  5975. </code></pre>
  5976. <hr />
  5977. <h3 id="report_stats_endpoint"><a class="header" href="#report_stats_endpoint"><code>report_stats_endpoint</code></a></h3>
  5978. <p>The endpoint to report homeserver usage statistics to.
  5979. Defaults to https://matrix.org/report-usage-stats/push</p>
  5980. <p>Example configuration:</p>
  5981. <pre><code class="language-yaml">report_stats_endpoint: https://example.com/report-usage-stats/push
  5982. </code></pre>
  5983. <hr />
  5984. <h2 id="api-configuration"><a class="header" href="#api-configuration">API Configuration</a></h2>
  5985. <p>Config settings related to the client/server API</p>
  5986. <hr />
  5987. <h3 id="room_prejoin_state"><a class="header" href="#room_prejoin_state"><code>room_prejoin_state</code></a></h3>
  5988. <p>This setting controls the state that is shared with users upon receiving an
  5989. invite to a room, or in reply to a knock on a room. By default, the following
  5990. state events are shared with users:</p>
  5991. <ul>
  5992. <li><code>m.room.join_rules</code></li>
  5993. <li><code>m.room.canonical_alias</code></li>
  5994. <li><code>m.room.avatar</code></li>
  5995. <li><code>m.room.encryption</code></li>
  5996. <li><code>m.room.name</code></li>
  5997. <li><code>m.room.create</code></li>
  5998. <li><code>m.room.topic</code></li>
  5999. </ul>
  6000. <p>To change the default behavior, use the following sub-options:</p>
  6001. <ul>
  6002. <li>
  6003. <p><code>disable_default_event_types</code>: boolean. Set to <code>true</code> to disable the above
  6004. defaults. If this is enabled, only the event types listed in
  6005. <code>additional_event_types</code> are shared. Defaults to <code>false</code>.</p>
  6006. </li>
  6007. <li>
  6008. <p><code>additional_event_types</code>: A list of additional state events to include in the
  6009. events to be shared. By default, this list is empty (so only the default event
  6010. types are shared).</p>
  6011. <p>Each entry in this list should be either a single string or a list of two
  6012. strings.</p>
  6013. <ul>
  6014. <li>A standalone string <code>t</code> represents all events with type <code>t</code> (i.e.
  6015. with no restrictions on state keys).</li>
  6016. <li>A pair of strings <code>[t, s]</code> represents a single event with type <code>t</code> and
  6017. state key <code>s</code>. The same type can appear in two entries with different state
  6018. keys: in this situation, both state keys are included in prejoin state.</li>
  6019. </ul>
  6020. </li>
  6021. </ul>
  6022. <p>Example configuration:</p>
  6023. <pre><code class="language-yaml">room_prejoin_state:
  6024. disable_default_event_types: false
  6025. additional_event_types:
  6026. # Share all events of type `org.example.custom.event.typeA`
  6027. - org.example.custom.event.typeA
  6028. # Share only events of type `org.example.custom.event.typeB` whose
  6029. # state_key is &quot;foo&quot;
  6030. - [&quot;org.example.custom.event.typeB&quot;, &quot;foo&quot;]
  6031. # Share only events of type `org.example.custom.event.typeC` whose
  6032. # state_key is &quot;bar&quot; or &quot;baz&quot;
  6033. - [&quot;org.example.custom.event.typeC&quot;, &quot;bar&quot;]
  6034. - [&quot;org.example.custom.event.typeC&quot;, &quot;baz&quot;]
  6035. </code></pre>
  6036. <p><em>Changed in Synapse 1.74:</em> admins can filter the events in prejoin state based
  6037. on their state key.</p>
  6038. <hr />
  6039. <h3 id="track_puppeted_user_ips"><a class="header" href="#track_puppeted_user_ips"><code>track_puppeted_user_ips</code></a></h3>
  6040. <p>We record the IP address of clients used to access the API for various
  6041. reasons, including displaying it to the user in the &quot;Where you're signed in&quot;
  6042. dialog.</p>
  6043. <p>By default, when puppeting another user via the admin API, the client IP
  6044. address is recorded against the user who created the access token (ie, the
  6045. admin user), and <em>not</em> the puppeted user.</p>
  6046. <p>Set this option to true to also record the IP address against the puppeted
  6047. user. (This also means that the puppeted user will count as an &quot;active&quot; user
  6048. for the purpose of monthly active user tracking - see <code>limit_usage_by_mau</code> etc
  6049. above.)</p>
  6050. <p>Example configuration:</p>
  6051. <pre><code class="language-yaml">track_puppeted_user_ips: true
  6052. </code></pre>
  6053. <hr />
  6054. <h3 id="app_service_config_files"><a class="header" href="#app_service_config_files"><code>app_service_config_files</code></a></h3>
  6055. <p>A list of application service config files to use.</p>
  6056. <p>Example configuration:</p>
  6057. <pre><code class="language-yaml">app_service_config_files:
  6058. - app_service_1.yaml
  6059. - app_service_2.yaml
  6060. </code></pre>
  6061. <hr />
  6062. <h3 id="track_appservice_user_ips"><a class="header" href="#track_appservice_user_ips"><code>track_appservice_user_ips</code></a></h3>
  6063. <p>Defaults to false. Set to true to enable tracking of application service IP addresses.
  6064. Implicitly enables MAU tracking for application service users.</p>
  6065. <p>Example configuration:</p>
  6066. <pre><code class="language-yaml">track_appservice_user_ips: true
  6067. </code></pre>
  6068. <hr />
  6069. <h3 id="use_appservice_legacy_authorization"><a class="header" href="#use_appservice_legacy_authorization"><code>use_appservice_legacy_authorization</code></a></h3>
  6070. <p>Whether to send the application service access tokens via the <code>access_token</code> query parameter
  6071. per older versions of the Matrix specification. Defaults to false. Set to true to enable sending
  6072. access tokens via a query parameter.</p>
  6073. <p>**Enabling this option is considered insecure and is not recommended. **</p>
  6074. <p>Example configuration:</p>
  6075. <pre><code class="language-yaml">use_appservice_legacy_authorization: true
  6076. </code></pre>
  6077. <hr />
  6078. <h3 id="macaroon_secret_key"><a class="header" href="#macaroon_secret_key"><code>macaroon_secret_key</code></a></h3>
  6079. <p>A secret which is used to sign</p>
  6080. <ul>
  6081. <li>access token for guest users,</li>
  6082. <li>short-term login token used during SSO logins (OIDC or SAML2) and</li>
  6083. <li>token used for unsubscribing from email notifications.</li>
  6084. </ul>
  6085. <p>If none is specified, the <code>registration_shared_secret</code> is used, if one is given;
  6086. otherwise, a secret key is derived from the signing key.</p>
  6087. <p>Example configuration:</p>
  6088. <pre><code class="language-yaml">macaroon_secret_key: &lt;PRIVATE STRING&gt;
  6089. </code></pre>
  6090. <hr />
  6091. <h3 id="form_secret"><a class="header" href="#form_secret"><code>form_secret</code></a></h3>
  6092. <p>A secret which is used to calculate HMACs for form values, to stop
  6093. falsification of values. Must be specified for the User Consent
  6094. forms to work.</p>
  6095. <p>Example configuration:</p>
  6096. <pre><code class="language-yaml">form_secret: &lt;PRIVATE STRING&gt;
  6097. </code></pre>
  6098. <hr />
  6099. <h2 id="signing-keys"><a class="header" href="#signing-keys">Signing Keys</a></h2>
  6100. <p>Config options relating to signing keys</p>
  6101. <hr />
  6102. <h3 id="signing_key_path"><a class="header" href="#signing_key_path"><code>signing_key_path</code></a></h3>
  6103. <p>Path to the signing key to sign events and federation requests with.</p>
  6104. <p><em>New in Synapse 1.67</em>: If this file does not exist, Synapse will create a new signing
  6105. key on startup and store it in this file.</p>
  6106. <p>Example configuration:</p>
  6107. <pre><code class="language-yaml">signing_key_path: &quot;CONFDIR/SERVERNAME.signing.key&quot;
  6108. </code></pre>
  6109. <hr />
  6110. <h3 id="old_signing_keys"><a class="header" href="#old_signing_keys"><code>old_signing_keys</code></a></h3>
  6111. <p>The keys that the server used to sign messages with but won't use
  6112. to sign new messages. For each key, <code>key</code> should be the base64-encoded public key, and
  6113. <code>expired_ts</code>should be the time (in milliseconds since the unix epoch) that
  6114. it was last used.</p>
  6115. <p>It is possible to build an entry from an old <code>signing.key</code> file using the
  6116. <code>export_signing_key</code> script which is provided with synapse.</p>
  6117. <p>Example configuration:</p>
  6118. <pre><code class="language-yaml">old_signing_keys:
  6119. &quot;ed25519:id&quot;: { key: &quot;base64string&quot;, expired_ts: 123456789123 }
  6120. </code></pre>
  6121. <hr />
  6122. <h3 id="key_refresh_interval"><a class="header" href="#key_refresh_interval"><code>key_refresh_interval</code></a></h3>
  6123. <p>How long key response published by this server is valid for.
  6124. Used to set the <code>valid_until_ts</code> in <code>/key/v2</code> APIs.
  6125. Determines how quickly servers will query to check which keys
  6126. are still valid. Defaults to 1d.</p>
  6127. <p>Example configuration:</p>
  6128. <pre><code class="language-yaml">key_refresh_interval: 2d
  6129. </code></pre>
  6130. <hr />
  6131. <h3 id="trusted_key_servers"><a class="header" href="#trusted_key_servers"><code>trusted_key_servers</code></a></h3>
  6132. <p>The trusted servers to download signing keys from.</p>
  6133. <p>When we need to fetch a signing key, each server is tried in parallel.</p>
  6134. <p>Normally, the connection to the key server is validated via TLS certificates.
  6135. Additional security can be provided by configuring a <code>verify key</code>, which
  6136. will make synapse check that the response is signed by that key.</p>
  6137. <p>This setting supersedes an older setting named <code>perspectives</code>. The old format
  6138. is still supported for backwards-compatibility, but it is deprecated.</p>
  6139. <p><code>trusted_key_servers</code> defaults to matrix.org, but using it will generate a
  6140. warning on start-up. To suppress this warning, set
  6141. <code>suppress_key_server_warning</code> to true.</p>
  6142. <p>If the use of a trusted key server has to be deactivated, e.g. in a private
  6143. federation or for privacy reasons, this can be realised by setting
  6144. an empty array (<code>trusted_key_servers: []</code>). Then Synapse will request the keys
  6145. directly from the server that owns the keys. If Synapse does not get keys directly
  6146. from the server, the events of this server will be rejected.</p>
  6147. <p>Options for each entry in the list include:</p>
  6148. <ul>
  6149. <li><code>server_name</code>: the name of the server. Required.</li>
  6150. <li><code>verify_keys</code>: an optional map from key id to base64-encoded public key.
  6151. If specified, we will check that the response is signed by at least
  6152. one of the given keys.</li>
  6153. <li><code>accept_keys_insecurely</code>: a boolean. Normally, if <code>verify_keys</code> is unset,
  6154. and <code>federation_verify_certificates</code> is not <code>true</code>, synapse will refuse
  6155. to start, because this would allow anyone who can spoof DNS responses
  6156. to masquerade as the trusted key server. If you know what you are doing
  6157. and are sure that your network environment provides a secure connection
  6158. to the key server, you can set this to <code>true</code> to override this behaviour.</li>
  6159. </ul>
  6160. <p>Example configuration #1:</p>
  6161. <pre><code class="language-yaml">trusted_key_servers:
  6162. - server_name: &quot;my_trusted_server.example.com&quot;
  6163. verify_keys:
  6164. &quot;ed25519:auto&quot;: &quot;abcdefghijklmnopqrstuvwxyzabcdefghijklmopqr&quot;
  6165. - server_name: &quot;my_other_trusted_server.example.com&quot;
  6166. </code></pre>
  6167. <p>Example configuration #2:</p>
  6168. <pre><code class="language-yaml">trusted_key_servers:
  6169. - server_name: &quot;matrix.org&quot;
  6170. </code></pre>
  6171. <hr />
  6172. <h3 id="suppress_key_server_warning"><a class="header" href="#suppress_key_server_warning"><code>suppress_key_server_warning</code></a></h3>
  6173. <p>Set the following to true to disable the warning that is emitted when the
  6174. <code>trusted_key_servers</code> include 'matrix.org'. See above.</p>
  6175. <p>Example configuration:</p>
  6176. <pre><code class="language-yaml">suppress_key_server_warning: true
  6177. </code></pre>
  6178. <hr />
  6179. <h3 id="key_server_signing_keys_path"><a class="header" href="#key_server_signing_keys_path"><code>key_server_signing_keys_path</code></a></h3>
  6180. <p>The signing keys to use when acting as a trusted key server. If not specified
  6181. defaults to the server signing key.</p>
  6182. <p>Can contain multiple keys, one per line.</p>
  6183. <p>Example configuration:</p>
  6184. <pre><code class="language-yaml">key_server_signing_keys_path: &quot;key_server_signing_keys.key&quot;
  6185. </code></pre>
  6186. <hr />
  6187. <h2 id="single-sign-on-integration"><a class="header" href="#single-sign-on-integration">Single sign-on integration</a></h2>
  6188. <p>The following settings can be used to make Synapse use a single sign-on
  6189. provider for authentication, instead of its internal password database.</p>
  6190. <p>You will probably also want to set the following options to <code>false</code> to
  6191. disable the regular login/registration flows:</p>
  6192. <ul>
  6193. <li><a href="usage/configuration/config_documentation.html#enable_registration"><code>enable_registration</code></a></li>
  6194. <li><a href="usage/configuration/config_documentation.html#password_config"><code>password_config.enabled</code></a></li>
  6195. </ul>
  6196. <hr />
  6197. <h3 id="saml2_config"><a class="header" href="#saml2_config"><code>saml2_config</code></a></h3>
  6198. <p>Enable SAML2 for registration and login. Uses pysaml2. To learn more about pysaml and
  6199. to find a full list options for configuring pysaml, read the docs <a href="https://pysaml2.readthedocs.io/en/latest/">here</a>.</p>
  6200. <p>At least one of <code>sp_config</code> or <code>config_path</code> must be set in this section to
  6201. enable SAML login. You can either put your entire pysaml config inline using the <code>sp_config</code>
  6202. option, or you can specify a path to a psyaml config file with the sub-option <code>config_path</code>.
  6203. This setting has the following sub-options:</p>
  6204. <ul>
  6205. <li><code>idp_name</code>: A user-facing name for this identity provider, which is used to
  6206. offer the user a choice of login mechanisms.</li>
  6207. <li><code>idp_icon</code>: An optional icon for this identity provider, which is presented
  6208. by clients and Synapse's own IdP picker page. If given, must be an
  6209. MXC URI of the format <code>mxc://&lt;server-name&gt;/&lt;media-id&gt;</code>. (An easy way to
  6210. obtain such an MXC URI is to upload an image to an (unencrypted) room
  6211. and then copy the &quot;url&quot; from the source of the event.)</li>
  6212. <li><code>idp_brand</code>: An optional brand for this identity provider, allowing clients
  6213. to style the login flow according to the identity provider in question.
  6214. See the <a href="https://spec.matrix.org/latest/">spec</a> for possible options here.</li>
  6215. <li><code>sp_config</code>: the configuration for the pysaml2 Service Provider. See pysaml2 docs for format of config.
  6216. Default values will be used for the <code>entityid</code> and <code>service</code> settings,
  6217. so it is not normally necessary to specify them unless you need to
  6218. override them. Here are a few useful sub-options for configuring pysaml:
  6219. <ul>
  6220. <li><code>metadata</code>: Point this to the IdP's metadata. You must provide either a local
  6221. file via the <code>local</code> attribute or (preferably) a URL via the
  6222. <code>remote</code> attribute.</li>
  6223. <li><code>accepted_time_diff: 3</code>: Allowed clock difference in seconds between the homeserver and IdP.
  6224. Defaults to 0.</li>
  6225. <li><code>service</code>: By default, the user has to go to our login page first. If you'd like
  6226. to allow IdP-initiated login, set <code>allow_unsolicited</code> to true under <code>sp</code> in the <code>service</code>
  6227. section.</li>
  6228. </ul>
  6229. </li>
  6230. <li><code>config_path</code>: specify a separate pysaml2 configuration file thusly:
  6231. <code>config_path: &quot;CONFDIR/sp_conf.py&quot;</code></li>
  6232. <li><code>saml_session_lifetime</code>: The lifetime of a SAML session. This defines how long a user has to
  6233. complete the authentication process, if <code>allow_unsolicited</code> is unset. The default is 15 minutes.</li>
  6234. <li><code>user_mapping_provider</code>: Using this option, an external module can be provided as a
  6235. custom solution to mapping attributes returned from a saml provider onto a matrix user. The
  6236. <code>user_mapping_provider</code> has the following attributes:
  6237. <ul>
  6238. <li><code>module</code>: The custom module's class.</li>
  6239. <li><code>config</code>: Custom configuration values for the module. Use the values provided in the
  6240. example if you are using the built-in user_mapping_provider, or provide your own
  6241. config values for a custom class if you are using one. This section will be passed as a Python
  6242. dictionary to the module's <code>parse_config</code> method. The built-in provider takes the following two
  6243. options:
  6244. <ul>
  6245. <li><code>mxid_source_attribute</code>: The SAML attribute (after mapping via the attribute maps) to use
  6246. to derive the Matrix ID from. It is 'uid' by default. Note: This used to be configured by the
  6247. <code>saml2_config.mxid_source_attribute option</code>. If that is still defined, its value will be used instead.</li>
  6248. <li><code>mxid_mapping</code>: The mapping system to use for mapping the saml attribute onto a
  6249. matrix ID. Options include: <code>hexencode</code> (which maps unpermitted characters to '=xx')
  6250. and <code>dotreplace</code> (which replaces unpermitted characters with '.').
  6251. The default is <code>hexencode</code>. Note: This used to be configured by the
  6252. <code>saml2_config.mxid_mapping option</code>. If that is still defined, its value will be used instead.</li>
  6253. </ul>
  6254. </li>
  6255. </ul>
  6256. </li>
  6257. <li><code>grandfathered_mxid_source_attribute</code>: In previous versions of synapse, the mapping from SAML attribute to
  6258. MXID was always calculated dynamically rather than stored in a table. For backwards- compatibility, we will look for <code>user_ids</code>
  6259. matching such a pattern before creating a new account. This setting controls the SAML attribute which will be used for this
  6260. backwards-compatibility lookup. Typically it should be 'uid', but if the attribute maps are changed, it may be necessary to change it.
  6261. The default is 'uid'.</li>
  6262. <li><code>attribute_requirements</code>: It is possible to configure Synapse to only allow logins if SAML attributes
  6263. match particular values. The requirements can be listed under
  6264. <code>attribute_requirements</code> as shown in the example. All of the listed attributes must
  6265. match for the login to be permitted.</li>
  6266. <li><code>idp_entityid</code>: If the metadata XML contains multiple IdP entities then the <code>idp_entityid</code>
  6267. option must be set to the entity to redirect users to.
  6268. Most deployments only have a single IdP entity and so should omit this option.</li>
  6269. </ul>
  6270. <p>Once SAML support is enabled, a metadata file will be exposed at
  6271. <code>https://&lt;server&gt;:&lt;port&gt;/_synapse/client/saml2/metadata.xml</code>, which you may be able to
  6272. use to configure your SAML IdP with. Alternatively, you can manually configure
  6273. the IdP to use an ACS location of
  6274. <code>https://&lt;server&gt;:&lt;port&gt;/_synapse/client/saml2/authn_response</code>.</p>
  6275. <p>Example configuration:</p>
  6276. <pre><code class="language-yaml">saml2_config:
  6277. sp_config:
  6278. metadata:
  6279. local: [&quot;saml2/idp.xml&quot;]
  6280. remote:
  6281. - url: https://our_idp/metadata.xml
  6282. accepted_time_diff: 3
  6283. service:
  6284. sp:
  6285. allow_unsolicited: true
  6286. # The examples below are just used to generate our metadata xml, and you
  6287. # may well not need them, depending on your setup. Alternatively you
  6288. # may need a whole lot more detail - see the pysaml2 docs!
  6289. description: [&quot;My awesome SP&quot;, &quot;en&quot;]
  6290. name: [&quot;Test SP&quot;, &quot;en&quot;]
  6291. ui_info:
  6292. display_name:
  6293. - lang: en
  6294. text: &quot;Display Name is the descriptive name of your service.&quot;
  6295. description:
  6296. - lang: en
  6297. text: &quot;Description should be a short paragraph explaining the purpose of the service.&quot;
  6298. information_url:
  6299. - lang: en
  6300. text: &quot;https://example.com/terms-of-service&quot;
  6301. privacy_statement_url:
  6302. - lang: en
  6303. text: &quot;https://example.com/privacy-policy&quot;
  6304. keywords:
  6305. - lang: en
  6306. text: [&quot;Matrix&quot;, &quot;Element&quot;]
  6307. logo:
  6308. - lang: en
  6309. text: &quot;https://example.com/logo.svg&quot;
  6310. width: &quot;200&quot;
  6311. height: &quot;80&quot;
  6312. organization:
  6313. name: Example com
  6314. display_name:
  6315. - [&quot;Example co&quot;, &quot;en&quot;]
  6316. url: &quot;http://example.com&quot;
  6317. contact_person:
  6318. - given_name: Bob
  6319. sur_name: &quot;the Sysadmin&quot;
  6320. email_address&quot;: [&quot;admin@example.com&quot;]
  6321. contact_type&quot;: technical
  6322. saml_session_lifetime: 5m
  6323. user_mapping_provider:
  6324. # Below options are intended for the built-in provider, they should be
  6325. # changed if using a custom module.
  6326. config:
  6327. mxid_source_attribute: displayName
  6328. mxid_mapping: dotreplace
  6329. grandfathered_mxid_source_attribute: upn
  6330. attribute_requirements:
  6331. - attribute: userGroup
  6332. value: &quot;staff&quot;
  6333. - attribute: department
  6334. value: &quot;sales&quot;
  6335. idp_entityid: 'https://our_idp/entityid'
  6336. </code></pre>
  6337. <hr />
  6338. <h3 id="oidc_providers"><a class="header" href="#oidc_providers"><code>oidc_providers</code></a></h3>
  6339. <p>List of OpenID Connect (OIDC) / OAuth 2.0 identity providers, for registration
  6340. and login. See <a href="usage/configuration/../../openid.html">here</a>
  6341. for information on how to configure these options.</p>
  6342. <p>For backwards compatibility, it is also possible to configure a single OIDC
  6343. provider via an <code>oidc_config</code> setting. This is now deprecated and admins are
  6344. advised to migrate to the <code>oidc_providers</code> format. (When doing that migration,
  6345. use <code>oidc</code> for the <code>idp_id</code> to ensure that existing users continue to be
  6346. recognised.)</p>
  6347. <p>Options for each entry include:</p>
  6348. <ul>
  6349. <li>
  6350. <p><code>idp_id</code>: a unique identifier for this identity provider. Used internally
  6351. by Synapse; should be a single word such as 'github'.
  6352. Note that, if this is changed, users authenticating via that provider
  6353. will no longer be recognised as the same user!
  6354. (Use &quot;oidc&quot; here if you are migrating from an old <code>oidc_config</code> configuration.)</p>
  6355. </li>
  6356. <li>
  6357. <p><code>idp_name</code>: A user-facing name for this identity provider, which is used to
  6358. offer the user a choice of login mechanisms.</p>
  6359. </li>
  6360. <li>
  6361. <p><code>idp_icon</code>: An optional icon for this identity provider, which is presented
  6362. by clients and Synapse's own IdP picker page. If given, must be an
  6363. MXC URI of the format <code>mxc://&lt;server-name&gt;/&lt;media-id&gt;</code>. (An easy way to
  6364. obtain such an MXC URI is to upload an image to an (unencrypted) room
  6365. and then copy the &quot;url&quot; from the source of the event.)</p>
  6366. </li>
  6367. <li>
  6368. <p><code>idp_brand</code>: An optional brand for this identity provider, allowing clients
  6369. to style the login flow according to the identity provider in question.
  6370. See the <a href="https://spec.matrix.org/latest/">spec</a> for possible options here.</p>
  6371. </li>
  6372. <li>
  6373. <p><code>discover</code>: set to false to disable the use of the OIDC discovery mechanism
  6374. to discover endpoints. Defaults to true.</p>
  6375. </li>
  6376. <li>
  6377. <p><code>issuer</code>: Required. The OIDC issuer. Used to validate tokens and (if discovery
  6378. is enabled) to discover the provider's endpoints.</p>
  6379. </li>
  6380. <li>
  6381. <p><code>client_id</code>: Required. oauth2 client id to use.</p>
  6382. </li>
  6383. <li>
  6384. <p><code>client_secret</code>: oauth2 client secret to use. May be omitted if
  6385. <code>client_secret_jwt_key</code> is given, or if <code>client_auth_method</code> is 'none'.
  6386. Must be omitted if <code>client_secret_path</code> is specified.</p>
  6387. </li>
  6388. <li>
  6389. <p><code>client_secret_path</code>: path to the oauth2 client secret to use. With that
  6390. it's not necessary to leak secrets into the config file itself.
  6391. Mutually exclusive with <code>client_secret</code>. Can be omitted if
  6392. <code>client_secret_jwt_key</code> is specified.</p>
  6393. <p><em>Added in Synapse 1.91.0.</em></p>
  6394. </li>
  6395. <li>
  6396. <p><code>client_secret_jwt_key</code>: Alternative to client_secret: details of a key used
  6397. to create a JSON Web Token to be used as an OAuth2 client secret. If
  6398. given, must be a dictionary with the following properties:</p>
  6399. <ul>
  6400. <li>
  6401. <p><code>key</code>: a pem-encoded signing key. Must be a suitable key for the
  6402. algorithm specified. Required unless <code>key_file</code> is given.</p>
  6403. </li>
  6404. <li>
  6405. <p><code>key_file</code>: the path to file containing a pem-encoded signing key file.
  6406. Required unless <code>key</code> is given.</p>
  6407. </li>
  6408. <li>
  6409. <p><code>jwt_header</code>: a dictionary giving properties to include in the JWT
  6410. header. Must include the key <code>alg</code>, giving the algorithm used to
  6411. sign the JWT, such as &quot;ES256&quot;, using the JWA identifiers in
  6412. RFC7518.</p>
  6413. </li>
  6414. <li>
  6415. <p><code>jwt_payload</code>: an optional dictionary giving properties to include in
  6416. the JWT payload. Normally this should include an <code>iss</code> key.</p>
  6417. </li>
  6418. </ul>
  6419. </li>
  6420. <li>
  6421. <p><code>client_auth_method</code>: auth method to use when exchanging the token. Valid
  6422. values are <code>client_secret_basic</code> (default), <code>client_secret_post</code> and
  6423. <code>none</code>.</p>
  6424. </li>
  6425. <li>
  6426. <p><code>pkce_method</code>: Whether to use proof key for code exchange when requesting
  6427. and exchanging the token. Valid values are: <code>auto</code>, <code>always</code>, or <code>never</code>. Defaults
  6428. to <code>auto</code>, which uses PKCE if supported during metadata discovery. Set to <code>always</code>
  6429. to force enable PKCE or <code>never</code> to force disable PKCE.</p>
  6430. </li>
  6431. <li>
  6432. <p><code>scopes</code>: list of scopes to request. This should normally include the &quot;openid&quot;
  6433. scope. Defaults to <code>[&quot;openid&quot;]</code>.</p>
  6434. </li>
  6435. <li>
  6436. <p><code>authorization_endpoint</code>: the oauth2 authorization endpoint. Required if
  6437. provider discovery is disabled.</p>
  6438. </li>
  6439. <li>
  6440. <p><code>token_endpoint</code>: the oauth2 token endpoint. Required if provider discovery is
  6441. disabled.</p>
  6442. </li>
  6443. <li>
  6444. <p><code>userinfo_endpoint</code>: the OIDC userinfo endpoint. Required if discovery is
  6445. disabled and the 'openid' scope is not requested.</p>
  6446. </li>
  6447. <li>
  6448. <p><code>jwks_uri</code>: URI where to fetch the JWKS. Required if discovery is disabled and
  6449. the 'openid' scope is used.</p>
  6450. </li>
  6451. <li>
  6452. <p><code>skip_verification</code>: set to 'true' to skip metadata verification. Use this if
  6453. you are connecting to a provider that is not OpenID Connect compliant.
  6454. Defaults to false. Avoid this in production.</p>
  6455. </li>
  6456. <li>
  6457. <p><code>user_profile_method</code>: Whether to fetch the user profile from the userinfo
  6458. endpoint, or to rely on the data returned in the id_token from the <code>token_endpoint</code>.
  6459. Valid values are: <code>auto</code> or <code>userinfo_endpoint</code>.
  6460. Defaults to <code>auto</code>, which uses the userinfo endpoint if <code>openid</code> is
  6461. not included in <code>scopes</code>. Set to <code>userinfo_endpoint</code> to always use the
  6462. userinfo endpoint.</p>
  6463. </li>
  6464. <li>
  6465. <p><code>allow_existing_users</code>: set to true to allow a user logging in via OIDC to
  6466. match a pre-existing account instead of failing. This could be used if
  6467. switching from password logins to OIDC. Defaults to false.</p>
  6468. </li>
  6469. <li>
  6470. <p><code>enable_registration</code>: set to 'false' to disable automatic registration of new
  6471. users. This allows the OIDC SSO flow to be limited to sign in only, rather than
  6472. automatically registering users that have a valid SSO login but do not have
  6473. a pre-registered account. Defaults to true.</p>
  6474. </li>
  6475. <li>
  6476. <p><code>user_mapping_provider</code>: Configuration for how attributes returned from a OIDC
  6477. provider are mapped onto a matrix user. This setting has the following
  6478. sub-properties:</p>
  6479. <ul>
  6480. <li>
  6481. <p><code>module</code>: The class name of a custom mapping module. Default is
  6482. <code>synapse.handlers.oidc.JinjaOidcMappingProvider</code>.
  6483. See <a href="usage/configuration/../../sso_mapping_providers.html#openid-mapping-providers">OpenID Mapping Providers</a>
  6484. for information on implementing a custom mapping provider.</p>
  6485. </li>
  6486. <li>
  6487. <p><code>config</code>: Configuration for the mapping provider module. This section will
  6488. be passed as a Python dictionary to the user mapping provider
  6489. module's <code>parse_config</code> method.</p>
  6490. <p>For the default provider, the following settings are available:</p>
  6491. <ul>
  6492. <li>
  6493. <p><code>subject_template</code>: Jinja2 template for a unique identifier for the user.
  6494. Defaults to <code>{{ user.sub }}</code>, which OpenID Connect compliant providers should provide.</p>
  6495. <p>This replaces and overrides <code>subject_claim</code>.</p>
  6496. </li>
  6497. <li>
  6498. <p><code>subject_claim</code>: name of the claim containing a unique identifier
  6499. for the user. Defaults to 'sub', which OpenID Connect
  6500. compliant providers should provide.</p>
  6501. <p><em>Deprecated in Synapse v1.75.0.</em></p>
  6502. </li>
  6503. <li>
  6504. <p><code>picture_template</code>: Jinja2 template for an url for the user's profile picture.
  6505. Defaults to <code>{{ user.picture }}</code>, which OpenID Connect compliant providers should
  6506. provide and has to refer to a direct image file such as PNG, JPEG, or GIF image file.</p>
  6507. <p>This replaces and overrides <code>picture_claim</code>.</p>
  6508. <p>Currently only supported in monolithic (single-process) server configurations
  6509. where the media repository runs within the Synapse process.</p>
  6510. </li>
  6511. <li>
  6512. <p><code>picture_claim</code>: name of the claim containing an url for the user's profile picture.
  6513. Defaults to 'picture', which OpenID Connect compliant providers should provide
  6514. and has to refer to a direct image file such as PNG, JPEG, or GIF image file.</p>
  6515. <p>Currently only supported in monolithic (single-process) server configurations
  6516. where the media repository runs within the Synapse process.</p>
  6517. <p><em>Deprecated in Synapse v1.75.0.</em></p>
  6518. </li>
  6519. <li>
  6520. <p><code>localpart_template</code>: Jinja2 template for the localpart of the MXID.
  6521. If this is not set, the user will be prompted to choose their
  6522. own username (see the documentation for the <code>sso_auth_account_details.html</code>
  6523. template). This template can use the <code>localpart_from_email</code> filter.</p>
  6524. </li>
  6525. <li>
  6526. <p><code>confirm_localpart</code>: Whether to prompt the user to validate (or
  6527. change) the generated localpart (see the documentation for the
  6528. 'sso_auth_account_details.html' template), instead of
  6529. registering the account right away.</p>
  6530. </li>
  6531. <li>
  6532. <p><code>display_name_template</code>: Jinja2 template for the display name to set
  6533. on first login. If unset, no displayname will be set.</p>
  6534. </li>
  6535. <li>
  6536. <p><code>email_template</code>: Jinja2 template for the email address of the user.
  6537. If unset, no email address will be added to the account.</p>
  6538. </li>
  6539. <li>
  6540. <p><code>extra_attributes</code>: a map of Jinja2 templates for extra attributes
  6541. to send back to the client during login. Note that these are non-standard and clients will ignore them
  6542. without modifications.</p>
  6543. </li>
  6544. </ul>
  6545. </li>
  6546. </ul>
  6547. <p>When rendering, the Jinja2 templates are given a 'user' variable,
  6548. which is set to the claims returned by the UserInfo Endpoint and/or
  6549. in the ID Token.</p>
  6550. </li>
  6551. <li>
  6552. <p><code>backchannel_logout_enabled</code>: set to <code>true</code> to process OIDC Back-Channel Logout notifications.
  6553. Those notifications are expected to be received on <code>/_synapse/client/oidc/backchannel_logout</code>.
  6554. Defaults to <code>false</code>.</p>
  6555. </li>
  6556. <li>
  6557. <p><code>backchannel_logout_ignore_sub</code>: by default, the OIDC Back-Channel Logout feature checks that the
  6558. <code>sub</code> claim matches the subject claim received during login. This check can be disabled by setting
  6559. this to <code>true</code>. Defaults to <code>false</code>.</p>
  6560. <p>You might want to disable this if the <code>subject_claim</code> returned by the mapping provider is not <code>sub</code>.</p>
  6561. </li>
  6562. </ul>
  6563. <p>It is possible to configure Synapse to only allow logins if certain attributes
  6564. match particular values in the OIDC userinfo. The requirements can be listed under
  6565. <code>attribute_requirements</code> as shown here:</p>
  6566. <pre><code class="language-yaml">attribute_requirements:
  6567. - attribute: family_name
  6568. value: &quot;Stephensson&quot;
  6569. - attribute: groups
  6570. value: &quot;admin&quot;
  6571. </code></pre>
  6572. <p>All of the listed attributes must match for the login to be permitted. Additional attributes can be added to
  6573. userinfo by expanding the <code>scopes</code> section of the OIDC config to retrieve
  6574. additional information from the OIDC provider.</p>
  6575. <p>If the OIDC claim is a list, then the attribute must match any value in the list.
  6576. Otherwise, it must exactly match the value of the claim. Using the example
  6577. above, the <code>family_name</code> claim MUST be &quot;Stephensson&quot;, but the <code>groups</code>
  6578. claim MUST contain &quot;admin&quot;.</p>
  6579. <p>Example configuration:</p>
  6580. <pre><code class="language-yaml">oidc_providers:
  6581. # Generic example
  6582. #
  6583. - idp_id: my_idp
  6584. idp_name: &quot;My OpenID provider&quot;
  6585. idp_icon: &quot;mxc://example.com/mediaid&quot;
  6586. discover: false
  6587. issuer: &quot;https://accounts.example.com/&quot;
  6588. client_id: &quot;provided-by-your-issuer&quot;
  6589. client_secret: &quot;provided-by-your-issuer&quot;
  6590. client_auth_method: client_secret_post
  6591. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  6592. authorization_endpoint: &quot;https://accounts.example.com/oauth2/auth&quot;
  6593. token_endpoint: &quot;https://accounts.example.com/oauth2/token&quot;
  6594. userinfo_endpoint: &quot;https://accounts.example.com/userinfo&quot;
  6595. jwks_uri: &quot;https://accounts.example.com/.well-known/jwks.json&quot;
  6596. skip_verification: true
  6597. enable_registration: true
  6598. user_mapping_provider:
  6599. config:
  6600. subject_claim: &quot;id&quot;
  6601. localpart_template: &quot;{{ user.login }}&quot;
  6602. display_name_template: &quot;{{ user.name }}&quot;
  6603. email_template: &quot;{{ user.email }}&quot;
  6604. attribute_requirements:
  6605. - attribute: userGroup
  6606. value: &quot;synapseUsers&quot;
  6607. </code></pre>
  6608. <hr />
  6609. <h3 id="cas_config"><a class="header" href="#cas_config"><code>cas_config</code></a></h3>
  6610. <p>Enable Central Authentication Service (CAS) for registration and login.
  6611. Has the following sub-options:</p>
  6612. <ul>
  6613. <li>
  6614. <p><code>enabled</code>: Set this to true to enable authorization against a CAS server.
  6615. Defaults to false.</p>
  6616. </li>
  6617. <li>
  6618. <p><code>idp_name</code>: A user-facing name for this identity provider, which is used to
  6619. offer the user a choice of login mechanisms.</p>
  6620. </li>
  6621. <li>
  6622. <p><code>idp_icon</code>: An optional icon for this identity provider, which is presented
  6623. by clients and Synapse's own IdP picker page. If given, must be an
  6624. MXC URI of the format <code>mxc://&lt;server-name&gt;/&lt;media-id&gt;</code>. (An easy way to
  6625. obtain such an MXC URI is to upload an image to an (unencrypted) room
  6626. and then copy the &quot;url&quot; from the source of the event.)</p>
  6627. </li>
  6628. <li>
  6629. <p><code>idp_brand</code>: An optional brand for this identity provider, allowing clients
  6630. to style the login flow according to the identity provider in question.
  6631. See the <a href="https://spec.matrix.org/latest/">spec</a> for possible options here.</p>
  6632. </li>
  6633. <li>
  6634. <p><code>server_url</code>: The URL of the CAS authorization endpoint.</p>
  6635. </li>
  6636. <li>
  6637. <p><code>protocol_version</code>: The CAS protocol version, defaults to none (version 3 is required if you want to use &quot;required_attributes&quot;).</p>
  6638. </li>
  6639. <li>
  6640. <p><code>displayname_attribute</code>: The attribute of the CAS response to use as the display name.
  6641. If no name is given here, no displayname will be set.</p>
  6642. </li>
  6643. <li>
  6644. <p><code>required_attributes</code>: It is possible to configure Synapse to only allow logins if CAS attributes
  6645. match particular values. All of the keys given below must exist
  6646. and the values must match the given value. Alternately if the given value
  6647. is <code>None</code> then any value is allowed (the attribute just must exist).
  6648. All of the listed attributes must match for the login to be permitted.</p>
  6649. </li>
  6650. <li>
  6651. <p><code>enable_registration</code>: set to 'false' to disable automatic registration of new
  6652. users. This allows the CAS SSO flow to be limited to sign in only, rather than
  6653. automatically registering users that have a valid SSO login but do not have
  6654. a pre-registered account. Defaults to true.</p>
  6655. <p><em>Added in Synapse 1.93.0.</em></p>
  6656. </li>
  6657. </ul>
  6658. <p>Example configuration:</p>
  6659. <pre><code class="language-yaml">cas_config:
  6660. enabled: true
  6661. server_url: &quot;https://cas-server.com&quot;
  6662. protocol_version: 3
  6663. displayname_attribute: name
  6664. required_attributes:
  6665. userGroup: &quot;staff&quot;
  6666. department: None
  6667. enable_registration: true
  6668. </code></pre>
  6669. <hr />
  6670. <h3 id="sso"><a class="header" href="#sso"><code>sso</code></a></h3>
  6671. <p>Additional settings to use with single-sign on systems such as OpenID Connect,
  6672. SAML2 and CAS.</p>
  6673. <p>Server admins can configure custom templates for pages related to SSO. See
  6674. <a href="usage/configuration/../../templates.html">here</a> for more information.</p>
  6675. <p>Options include:</p>
  6676. <ul>
  6677. <li><code>client_whitelist</code>: A list of client URLs which are whitelisted so that the user does not
  6678. have to confirm giving access to their account to the URL. Any client
  6679. whose URL starts with an entry in the following list will not be subject
  6680. to an additional confirmation step after the SSO login is completed.
  6681. WARNING: An entry such as &quot;https://my.client&quot; is insecure, because it
  6682. will also match &quot;https://my.client.evil.site&quot;, exposing your users to
  6683. phishing attacks from evil.site. To avoid this, include a slash after the
  6684. hostname: &quot;https://my.client/&quot;.
  6685. The login fallback page (used by clients that don't natively support the
  6686. required login flows) is whitelisted in addition to any URLs in this list.
  6687. By default, this list contains only the login fallback page.</li>
  6688. <li><code>update_profile_information</code>: Use this setting to keep a user's profile fields in sync with information from
  6689. the identity provider. Currently only syncing the displayname is supported. Fields
  6690. are checked on every SSO login, and are updated if necessary.
  6691. Note that enabling this option will override user profile information,
  6692. regardless of whether users have opted-out of syncing that
  6693. information when first signing in. Defaults to false.</li>
  6694. </ul>
  6695. <p>Example configuration:</p>
  6696. <pre><code class="language-yaml">sso:
  6697. client_whitelist:
  6698. - https://riot.im/develop
  6699. - https://my.custom.client/
  6700. update_profile_information: true
  6701. </code></pre>
  6702. <hr />
  6703. <h3 id="jwt_config"><a class="header" href="#jwt_config"><code>jwt_config</code></a></h3>
  6704. <p>JSON web token integration. The following settings can be used to make
  6705. Synapse JSON web tokens for authentication, instead of its internal
  6706. password database.</p>
  6707. <p>Each JSON Web Token needs to contain a &quot;sub&quot; (subject) claim, which is
  6708. used as the localpart of the mxid.</p>
  6709. <p>Additionally, the expiration time (&quot;exp&quot;), not before time (&quot;nbf&quot;),
  6710. and issued at (&quot;iat&quot;) claims are validated if present.</p>
  6711. <p>Note that this is a non-standard login type and client support is
  6712. expected to be non-existent.</p>
  6713. <p>See <a href="usage/configuration/../../jwt.html">here</a> for more.</p>
  6714. <p>Additional sub-options for this setting include:</p>
  6715. <ul>
  6716. <li><code>enabled</code>: Set to true to enable authorization using JSON web
  6717. tokens. Defaults to false.</li>
  6718. <li><code>secret</code>: This is either the private shared secret or the public key used to
  6719. decode the contents of the JSON web token. Required if <code>enabled</code> is set to true.</li>
  6720. <li><code>algorithm</code>: The algorithm used to sign (or HMAC) the JSON web token.
  6721. Supported algorithms are listed
  6722. <a href="https://docs.authlib.org/en/latest/specs/rfc7518.html">here (section JWS)</a>.
  6723. Required if <code>enabled</code> is set to true.</li>
  6724. <li><code>subject_claim</code>: Name of the claim containing a unique identifier for the user.
  6725. Optional, defaults to <code>sub</code>.</li>
  6726. <li><code>issuer</code>: The issuer to validate the &quot;iss&quot; claim against. Optional. If provided the
  6727. &quot;iss&quot; claim will be required and validated for all JSON web tokens.</li>
  6728. <li><code>audiences</code>: A list of audiences to validate the &quot;aud&quot; claim against. Optional.
  6729. If provided the &quot;aud&quot; claim will be required and validated for all JSON web tokens.
  6730. Note that if the &quot;aud&quot; claim is included in a JSON web token then
  6731. validation will fail without configuring audiences.</li>
  6732. </ul>
  6733. <p>Example configuration:</p>
  6734. <pre><code class="language-yaml">jwt_config:
  6735. enabled: true
  6736. secret: &quot;provided-by-your-issuer&quot;
  6737. algorithm: &quot;provided-by-your-issuer&quot;
  6738. subject_claim: &quot;name_of_claim&quot;
  6739. issuer: &quot;provided-by-your-issuer&quot;
  6740. audiences:
  6741. - &quot;provided-by-your-issuer&quot;
  6742. </code></pre>
  6743. <hr />
  6744. <h3 id="password_config"><a class="header" href="#password_config"><code>password_config</code></a></h3>
  6745. <p>Use this setting to enable password-based logins.</p>
  6746. <p>This setting has the following sub-options:</p>
  6747. <ul>
  6748. <li><code>enabled</code>: Defaults to true.
  6749. Set to false to disable password authentication.
  6750. Set to <code>only_for_reauth</code> to allow users with existing passwords to use them
  6751. to log in and reauthenticate, whilst preventing new users from setting passwords.</li>
  6752. <li><code>localdb_enabled</code>: Set to false to disable authentication against the local password
  6753. database. This is ignored if <code>enabled</code> is false, and is only useful
  6754. if you have other <code>password_providers</code>. Defaults to true.</li>
  6755. <li><code>pepper</code>: Set the value here to a secret random string for extra security.
  6756. DO NOT CHANGE THIS AFTER INITIAL SETUP!</li>
  6757. <li><code>policy</code>: Define and enforce a password policy, such as minimum lengths for passwords, etc.
  6758. Each parameter is optional. This is an implementation of MSC2000. Parameters are as follows:
  6759. <ul>
  6760. <li><code>enabled</code>: Defaults to false. Set to true to enable.</li>
  6761. <li><code>minimum_length</code>: Minimum accepted length for a password. Defaults to 0.</li>
  6762. <li><code>require_digit</code>: Whether a password must contain at least one digit.
  6763. Defaults to false.</li>
  6764. <li><code>require_symbol</code>: Whether a password must contain at least one symbol.
  6765. A symbol is any character that's not a number or a letter. Defaults to false.</li>
  6766. <li><code>require_lowercase</code>: Whether a password must contain at least one lowercase letter.
  6767. Defaults to false.</li>
  6768. <li><code>require_uppercase</code>: Whether a password must contain at least one uppercase letter.
  6769. Defaults to false.</li>
  6770. </ul>
  6771. </li>
  6772. </ul>
  6773. <p>Example configuration:</p>
  6774. <pre><code class="language-yaml">password_config:
  6775. enabled: false
  6776. localdb_enabled: false
  6777. pepper: &quot;EVEN_MORE_SECRET&quot;
  6778. policy:
  6779. enabled: true
  6780. minimum_length: 15
  6781. require_digit: true
  6782. require_symbol: true
  6783. require_lowercase: true
  6784. require_uppercase: true
  6785. </code></pre>
  6786. <hr />
  6787. <h2 id="push"><a class="header" href="#push">Push</a></h2>
  6788. <p>Configuration settings related to push notifications</p>
  6789. <hr />
  6790. <h3 id="push-1"><a class="header" href="#push-1"><code>push</code></a></h3>
  6791. <p>This setting defines options for push notifications.</p>
  6792. <p>This option has a number of sub-options. They are as follows:</p>
  6793. <ul>
  6794. <li><code>enabled</code>: Enables or disables push notification calculation. Note, disabling this will also
  6795. stop unread counts being calculated for rooms. This mode of operation is intended
  6796. for homeservers which may only have bots or appservice users connected, or are otherwise
  6797. not interested in push/unread counters. This is enabled by default.</li>
  6798. <li><code>include_content</code>: Clients requesting push notifications can either have the body of
  6799. the message sent in the notification poke along with other details
  6800. like the sender, or just the event ID and room ID (<code>event_id_only</code>).
  6801. If clients choose the to have the body sent, this option controls whether the
  6802. notification request includes the content of the event (other details
  6803. like the sender are still included). If <code>event_id_only</code> is enabled, it
  6804. has no effect.
  6805. For modern android devices the notification content will still appear
  6806. because it is loaded by the app. iPhone, however will send a
  6807. notification saying only that a message arrived and who it came from.
  6808. Defaults to true. Set to false to only include the event ID and room ID in push notification payloads.</li>
  6809. <li><code>group_unread_count_by_room: false</code>: When a push notification is received, an unread count is also sent.
  6810. This number can either be calculated as the number of unread messages for the user, or the number of <em>rooms</em> the
  6811. user has unread messages in. Defaults to true, meaning push clients will see the number of
  6812. rooms with unread messages in them. Set to false to instead send the number
  6813. of unread messages.</li>
  6814. <li><code>jitter_delay</code>: Delays push notifications by a random amount up to the given
  6815. duration. Useful for mitigating timing attacks. Optional, defaults to no
  6816. delay. <em>Added in Synapse 1.84.0.</em></li>
  6817. </ul>
  6818. <p>Example configuration:</p>
  6819. <pre><code class="language-yaml">push:
  6820. enabled: true
  6821. include_content: false
  6822. group_unread_count_by_room: false
  6823. jitter_delay: &quot;10s&quot;
  6824. </code></pre>
  6825. <hr />
  6826. <h2 id="rooms"><a class="header" href="#rooms">Rooms</a></h2>
  6827. <p>Config options relating to rooms.</p>
  6828. <hr />
  6829. <h3 id="encryption_enabled_by_default_for_room_type"><a class="header" href="#encryption_enabled_by_default_for_room_type"><code>encryption_enabled_by_default_for_room_type</code></a></h3>
  6830. <p>Controls whether locally-created rooms should be end-to-end encrypted by
  6831. default.</p>
  6832. <p>Possible options are &quot;all&quot;, &quot;invite&quot;, and &quot;off&quot;. They are defined as:</p>
  6833. <ul>
  6834. <li>&quot;all&quot;: any locally-created room</li>
  6835. <li>&quot;invite&quot;: any room created with the <code>private_chat</code> or <code>trusted_private_chat</code>
  6836. room creation presets</li>
  6837. <li>&quot;off&quot;: this option will take no effect</li>
  6838. </ul>
  6839. <p>The default value is &quot;off&quot;.</p>
  6840. <p>Note that this option will only affect rooms created after it is set. It
  6841. will also not affect rooms created by other servers.</p>
  6842. <p>Example configuration:</p>
  6843. <pre><code class="language-yaml">encryption_enabled_by_default_for_room_type: invite
  6844. </code></pre>
  6845. <hr />
  6846. <h3 id="user_directory"><a class="header" href="#user_directory"><code>user_directory</code></a></h3>
  6847. <p>This setting defines options related to the user directory.</p>
  6848. <p>This option has the following sub-options:</p>
  6849. <ul>
  6850. <li>
  6851. <p><code>enabled</code>: Defines whether users can search the user directory. If false then
  6852. empty responses are returned to all queries. Defaults to true.</p>
  6853. </li>
  6854. <li>
  6855. <p><code>search_all_users</code>: Defines whether to search all users visible to your HS at the time the search is performed. If set to true, will return all users who share a room with the user from the homeserver.
  6856. If false, search results will only contain users
  6857. visible in public rooms and users sharing a room with the requester.
  6858. Defaults to false.</p>
  6859. <p>NB. If you set this to true, and the last time the user_directory search
  6860. indexes were (re)built was before Synapse 1.44, you'll have to
  6861. rebuild the indexes in order to search through all known users.</p>
  6862. <p>These indexes are built the first time Synapse starts; admins can
  6863. manually trigger a rebuild via the API following the instructions
  6864. <a href="usage/configuration/../administration/admin_api/background_updates.html#run">for running background updates</a>,
  6865. set to true to return search results containing all known users, even if that
  6866. user does not share a room with the requester.</p>
  6867. </li>
  6868. <li>
  6869. <p><code>prefer_local_users</code>: Defines whether to prefer local users in search query results.
  6870. If set to true, local users are more likely to appear above remote users when searching the
  6871. user directory. Defaults to false.</p>
  6872. </li>
  6873. <li>
  6874. <p><code>show_locked_users</code>: Defines whether to show locked users in search query results. Defaults to false.</p>
  6875. </li>
  6876. </ul>
  6877. <p>Example configuration:</p>
  6878. <pre><code class="language-yaml">user_directory:
  6879. enabled: false
  6880. search_all_users: true
  6881. prefer_local_users: true
  6882. show_locked_users: true
  6883. </code></pre>
  6884. <hr />
  6885. <h3 id="user_consent"><a class="header" href="#user_consent"><code>user_consent</code></a></h3>
  6886. <p>For detailed instructions on user consent configuration, see <a href="usage/configuration/../../consent_tracking.html">here</a>.</p>
  6887. <p>Parts of this section are required if enabling the <code>consent</code> resource under
  6888. <a href="usage/configuration/config_documentation.html#listeners"><code>listeners</code></a>, in particular <code>template_dir</code> and <code>version</code>.</p>
  6889. <ul>
  6890. <li>
  6891. <p><code>template_dir</code>: gives the location of the templates for the HTML forms.
  6892. This directory should contain one subdirectory per language (eg, <code>en</code>, <code>fr</code>),
  6893. and each language directory should contain the policy document (named as
  6894. <version>.html) and a success page (success.html).</p>
  6895. </li>
  6896. <li>
  6897. <p><code>version</code>: specifies the 'current' version of the policy document. It defines
  6898. the version to be served by the consent resource if there is no 'v'
  6899. parameter.</p>
  6900. </li>
  6901. <li>
  6902. <p><code>server_notice_content</code>: if enabled, will send a user a &quot;Server Notice&quot;
  6903. asking them to consent to the privacy policy. The <a href="usage/configuration/config_documentation.html#server_notices"><code>server_notices</code> section</a>
  6904. must also be configured for this to work. Notices will <em>not</em> be sent to
  6905. guest users unless <code>send_server_notice_to_guests</code> is set to true.</p>
  6906. </li>
  6907. <li>
  6908. <p><code>block_events_error</code>, if set, will block any attempts to send events
  6909. until the user consents to the privacy policy. The value of the setting is
  6910. used as the text of the error.</p>
  6911. </li>
  6912. <li>
  6913. <p><code>require_at_registration</code>, if enabled, will add a step to the registration
  6914. process, similar to how captcha works. Users will be required to accept the
  6915. policy before their account is created.</p>
  6916. </li>
  6917. <li>
  6918. <p><code>policy_name</code> is the display name of the policy users will see when registering
  6919. for an account. Has no effect unless <code>require_at_registration</code> is enabled.
  6920. Defaults to &quot;Privacy Policy&quot;.</p>
  6921. </li>
  6922. </ul>
  6923. <p>Example configuration:</p>
  6924. <pre><code class="language-yaml">user_consent:
  6925. template_dir: res/templates/privacy
  6926. version: 1.0
  6927. server_notice_content:
  6928. msgtype: m.text
  6929. body: &gt;-
  6930. To continue using this homeserver you must review and agree to the
  6931. terms and conditions at %(consent_uri)s
  6932. send_server_notice_to_guests: true
  6933. block_events_error: &gt;-
  6934. To continue using this homeserver you must review and agree to the
  6935. terms and conditions at %(consent_uri)s
  6936. require_at_registration: false
  6937. policy_name: Privacy Policy
  6938. </code></pre>
  6939. <hr />
  6940. <h3 id="stats"><a class="header" href="#stats"><code>stats</code></a></h3>
  6941. <p>Settings for local room and user statistics collection. See <a href="usage/configuration/../../room_and_user_statistics.html">here</a>
  6942. for more.</p>
  6943. <ul>
  6944. <li><code>enabled</code>: Set to false to disable room and user statistics. Note that doing
  6945. so may cause certain features (such as the room directory) not to work
  6946. correctly. Defaults to true.</li>
  6947. </ul>
  6948. <p>Example configuration:</p>
  6949. <pre><code class="language-yaml">stats:
  6950. enabled: false
  6951. </code></pre>
  6952. <hr />
  6953. <h3 id="server_notices"><a class="header" href="#server_notices"><code>server_notices</code></a></h3>
  6954. <p>Use this setting to enable a room which can be used to send notices
  6955. from the server to users. It is a special room which users cannot leave; notices
  6956. in the room come from a special &quot;notices&quot; user id.</p>
  6957. <p>If you use this setting, you <em>must</em> define the <code>system_mxid_localpart</code>
  6958. sub-setting, which defines the id of the user which will be used to send the
  6959. notices.</p>
  6960. <p>Sub-options for this setting include:</p>
  6961. <ul>
  6962. <li><code>system_mxid_display_name</code>: set the display name of the &quot;notices&quot; user</li>
  6963. <li><code>system_mxid_avatar_url</code>: set the avatar for the &quot;notices&quot; user</li>
  6964. <li><code>room_name</code>: set the room name of the server notices room</li>
  6965. <li><code>auto_join</code>: boolean. If true, the user will be automatically joined to the room instead of being invited.
  6966. Defaults to false. <em>Added in Synapse 1.98.0.</em></li>
  6967. </ul>
  6968. <p>Example configuration:</p>
  6969. <pre><code class="language-yaml">server_notices:
  6970. system_mxid_localpart: notices
  6971. system_mxid_display_name: &quot;Server Notices&quot;
  6972. system_mxid_avatar_url: &quot;mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ&quot;
  6973. room_name: &quot;Server Notices&quot;
  6974. auto_join: true
  6975. </code></pre>
  6976. <hr />
  6977. <h3 id="enable_room_list_search"><a class="header" href="#enable_room_list_search"><code>enable_room_list_search</code></a></h3>
  6978. <p>Set to false to disable searching the public room list. When disabled
  6979. blocks searching local and remote room lists for local and remote
  6980. users by always returning an empty list for all queries. Defaults to true.</p>
  6981. <p>Example configuration:</p>
  6982. <pre><code class="language-yaml">enable_room_list_search: false
  6983. </code></pre>
  6984. <hr />
  6985. <h3 id="alias_creation_rules"><a class="header" href="#alias_creation_rules"><code>alias_creation_rules</code></a></h3>
  6986. <p>The <code>alias_creation_rules</code> option allows server admins to prevent unwanted
  6987. alias creation on this server.</p>
  6988. <p>This setting is an optional list of 0 or more rules. By default, no list is
  6989. provided, meaning that all alias creations are permitted.</p>
  6990. <p>Otherwise, requests to create aliases are matched against each rule in order.
  6991. The first rule that matches decides if the request is allowed or denied. If no
  6992. rule matches, the request is denied. In particular, this means that configuring
  6993. an empty list of rules will deny every alias creation request.</p>
  6994. <p>Each rule is a YAML object containing four fields, each of which is an optional string:</p>
  6995. <ul>
  6996. <li><code>user_id</code>: a glob pattern that matches against the creator of the alias.</li>
  6997. <li><code>alias</code>: a glob pattern that matches against the alias being created.</li>
  6998. <li><code>room_id</code>: a glob pattern that matches against the room ID the alias is being pointed at.</li>
  6999. <li><code>action</code>: either <code>allow</code> or <code>deny</code>. What to do with the request if the rule matches. Defaults to <code>allow</code>.</li>
  7000. </ul>
  7001. <p>Each of the glob patterns is optional, defaulting to <code>*</code> (&quot;match anything&quot;).
  7002. Note that the patterns match against fully qualified IDs, e.g. against
  7003. <code>@alice:example.com</code>, <code>#room:example.com</code> and <code>!abcdefghijk:example.com</code> instead
  7004. of <code>alice</code>, <code>room</code> and <code>abcedgghijk</code>.</p>
  7005. <p>Example configuration:</p>
  7006. <pre><code class="language-yaml"># No rule list specified. All alias creations are allowed.
  7007. # This is the default behaviour.
  7008. alias_creation_rules:
  7009. </code></pre>
  7010. <pre><code class="language-yaml"># A list of one rule which allows everything.
  7011. # This has the same effect as the previous example.
  7012. alias_creation_rules:
  7013. - &quot;action&quot;: &quot;allow&quot;
  7014. </code></pre>
  7015. <pre><code class="language-yaml"># An empty list of rules. All alias creations are denied.
  7016. alias_creation_rules: []
  7017. </code></pre>
  7018. <pre><code class="language-yaml"># A list of one rule which denies everything.
  7019. # This has the same effect as the previous example.
  7020. alias_creation_rules:
  7021. - &quot;action&quot;: &quot;deny&quot;
  7022. </code></pre>
  7023. <pre><code class="language-yaml"># Prevent a specific user from creating aliases.
  7024. # Allow other users to create any alias
  7025. alias_creation_rules:
  7026. - user_id: &quot;@bad_user:example.com&quot;
  7027. action: deny
  7028. - action: allow
  7029. </code></pre>
  7030. <pre><code class="language-yaml"># Prevent aliases being created which point to a specific room.
  7031. alias_creation_rules:
  7032. - room_id: &quot;!forbiddenRoom:example.com&quot;
  7033. action: deny
  7034. - action: allow
  7035. </code></pre>
  7036. <hr />
  7037. <h3 id="room_list_publication_rules"><a class="header" href="#room_list_publication_rules"><code>room_list_publication_rules</code></a></h3>
  7038. <p>The <code>room_list_publication_rules</code> option allows server admins to prevent
  7039. unwanted entries from being published in the public room list.</p>
  7040. <p>The format of this option is the same as that for
  7041. <a href="usage/configuration/config_documentation.html#alias_creation_rules"><code>alias_creation_rules</code></a>: an optional list of 0 or more
  7042. rules. By default, no list is provided, meaning that all rooms may be
  7043. published to the room list.</p>
  7044. <p>Otherwise, requests to publish a room are matched against each rule in order.
  7045. The first rule that matches decides if the request is allowed or denied. If no
  7046. rule matches, the request is denied. In particular, this means that configuring
  7047. an empty list of rules will deny every alias creation request.</p>
  7048. <p>Each rule is a YAML object containing four fields, each of which is an optional string:</p>
  7049. <ul>
  7050. <li><code>user_id</code>: a glob pattern that matches against the user publishing the room.</li>
  7051. <li><code>alias</code>: a glob pattern that matches against one of published room's aliases.
  7052. <ul>
  7053. <li>If the room has no aliases, the alias match fails unless <code>alias</code> is unspecified or <code>*</code>.</li>
  7054. <li>If the room has exactly one alias, the alias match succeeds if the <code>alias</code> pattern matches that alias.</li>
  7055. <li>If the room has two or more aliases, the alias match succeeds if the pattern matches at least one of the aliases.</li>
  7056. </ul>
  7057. </li>
  7058. <li><code>room_id</code>: a glob pattern that matches against the room ID of the room being published.</li>
  7059. <li><code>action</code>: either <code>allow</code> or <code>deny</code>. What to do with the request if the rule matches. Defaults to <code>allow</code>.</li>
  7060. </ul>
  7061. <p>Each of the glob patterns is optional, defaulting to <code>*</code> (&quot;match anything&quot;).
  7062. Note that the patterns match against fully qualified IDs, e.g. against
  7063. <code>@alice:example.com</code>, <code>#room:example.com</code> and <code>!abcdefghijk:example.com</code> instead
  7064. of <code>alice</code>, <code>room</code> and <code>abcedgghijk</code>.</p>
  7065. <p>Example configuration:</p>
  7066. <pre><code class="language-yaml"># No rule list specified. Anyone may publish any room to the public list.
  7067. # This is the default behaviour.
  7068. room_list_publication_rules:
  7069. </code></pre>
  7070. <pre><code class="language-yaml"># A list of one rule which allows everything.
  7071. # This has the same effect as the previous example.
  7072. room_list_publication_rules:
  7073. - &quot;action&quot;: &quot;allow&quot;
  7074. </code></pre>
  7075. <pre><code class="language-yaml"># An empty list of rules. No-one may publish to the room list.
  7076. room_list_publication_rules: []
  7077. </code></pre>
  7078. <pre><code class="language-yaml"># A list of one rule which denies everything.
  7079. # This has the same effect as the previous example.
  7080. room_list_publication_rules:
  7081. - &quot;action&quot;: &quot;deny&quot;
  7082. </code></pre>
  7083. <pre><code class="language-yaml"># Prevent a specific user from publishing rooms.
  7084. # Allow other users to publish anything.
  7085. room_list_publication_rules:
  7086. - user_id: &quot;@bad_user:example.com&quot;
  7087. action: deny
  7088. - action: allow
  7089. </code></pre>
  7090. <pre><code class="language-yaml"># Prevent publication of a specific room.
  7091. room_list_publication_rules:
  7092. - room_id: &quot;!forbiddenRoom:example.com&quot;
  7093. action: deny
  7094. - action: allow
  7095. </code></pre>
  7096. <pre><code class="language-yaml"># Prevent publication of rooms with at least one alias containing the word &quot;potato&quot;.
  7097. room_list_publication_rules:
  7098. - alias: &quot;#*potato*:example.com&quot;
  7099. action: deny
  7100. - action: allow
  7101. </code></pre>
  7102. <hr />
  7103. <h3 id="default_power_level_content_override"><a class="header" href="#default_power_level_content_override"><code>default_power_level_content_override</code></a></h3>
  7104. <p>The <code>default_power_level_content_override</code> option controls the default power
  7105. levels for rooms.</p>
  7106. <p>Useful if you know that your users need special permissions in rooms
  7107. that they create (e.g. to send particular types of state events without
  7108. needing an elevated power level). This takes the same shape as the
  7109. <code>power_level_content_override</code> parameter in the /createRoom API, but
  7110. is applied before that parameter.</p>
  7111. <p>Note that each key provided inside a preset (for example <code>events</code> in the example
  7112. below) will overwrite all existing defaults inside that key. So in the example
  7113. below, newly-created private_chat rooms will have no rules for any event types
  7114. except <code>com.example.foo</code>.</p>
  7115. <p>Example configuration:</p>
  7116. <pre><code class="language-yaml">default_power_level_content_override:
  7117. private_chat: { &quot;events&quot;: { &quot;com.example.foo&quot; : 0 } }
  7118. trusted_private_chat: null
  7119. public_chat: null
  7120. </code></pre>
  7121. <hr />
  7122. <h3 id="forget_rooms_on_leave"><a class="header" href="#forget_rooms_on_leave"><code>forget_rooms_on_leave</code></a></h3>
  7123. <p>Set to true to automatically forget rooms for users when they leave them, either
  7124. normally or via a kick or ban. Defaults to false.</p>
  7125. <p>Example configuration:</p>
  7126. <pre><code class="language-yaml">forget_rooms_on_leave: false
  7127. </code></pre>
  7128. <hr />
  7129. <h3 id="exclude_rooms_from_sync"><a class="header" href="#exclude_rooms_from_sync"><code>exclude_rooms_from_sync</code></a></h3>
  7130. <p>A list of rooms to exclude from sync responses. This is useful for server
  7131. administrators wishing to group users into a room without these users being able
  7132. to see it from their client.</p>
  7133. <p>By default, no room is excluded.</p>
  7134. <p>Example configuration:</p>
  7135. <pre><code class="language-yaml">exclude_rooms_from_sync:
  7136. - !foo:example.com
  7137. </code></pre>
  7138. <hr />
  7139. <h2 id="opentracing"><a class="header" href="#opentracing">Opentracing</a></h2>
  7140. <p>Configuration options related to Opentracing support.</p>
  7141. <hr />
  7142. <h3 id="opentracing-1"><a class="header" href="#opentracing-1"><code>opentracing</code></a></h3>
  7143. <p>These settings enable and configure opentracing, which implements distributed tracing.
  7144. This allows you to observe the causal chains of events across servers
  7145. including requests, key lookups etc., across any server running
  7146. synapse or any other services which support opentracing
  7147. (specifically those implemented with Jaeger).</p>
  7148. <p>Sub-options include:</p>
  7149. <ul>
  7150. <li><code>enabled</code>: whether tracing is enabled. Set to true to enable. Disabled by default.</li>
  7151. <li><code>homeserver_whitelist</code>: The list of homeservers we wish to send and receive span contexts and span baggage.
  7152. See <a href="usage/configuration/../../opentracing.html">here</a> for more.
  7153. This is a list of regexes which are matched against the <code>server_name</code> of the homeserver.
  7154. By default, it is empty, so no servers are matched.</li>
  7155. <li><code>force_tracing_for_users</code>: # A list of the matrix IDs of users whose requests will always be traced,
  7156. even if the tracing system would otherwise drop the traces due to probabilistic sampling.
  7157. By default, the list is empty.</li>
  7158. <li><code>jaeger_config</code>: Jaeger can be configured to sample traces at different rates.
  7159. All configuration options provided by Jaeger can be set here. Jaeger's configuration is
  7160. mostly related to trace sampling which is documented <a href="https://www.jaegertracing.io/docs/latest/sampling/">here</a>.</li>
  7161. </ul>
  7162. <p>Example configuration:</p>
  7163. <pre><code class="language-yaml">opentracing:
  7164. enabled: true
  7165. homeserver_whitelist:
  7166. - &quot;.*&quot;
  7167. force_tracing_for_users:
  7168. - &quot;@user1:server_name&quot;
  7169. - &quot;@user2:server_name&quot;
  7170. jaeger_config:
  7171. sampler:
  7172. type: const
  7173. param: 1
  7174. logging:
  7175. false
  7176. </code></pre>
  7177. <hr />
  7178. <h2 id="coordinating-workers"><a class="header" href="#coordinating-workers">Coordinating workers</a></h2>
  7179. <p>Configuration options related to workers which belong in the main config file
  7180. (usually called <code>homeserver.yaml</code>).
  7181. A Synapse deployment can scale horizontally by running multiple Synapse processes
  7182. called <em>workers</em>. Incoming requests are distributed between workers to handle higher
  7183. loads. Some workers are privileged and can accept requests from other workers.</p>
  7184. <p>As a result, the worker configuration is divided into two parts.</p>
  7185. <ol>
  7186. <li>The first part (in this section of the manual) defines which shardable tasks
  7187. are delegated to privileged workers. This allows unprivileged workers to make
  7188. requests to a privileged worker to act on their behalf.</li>
  7189. <li><a href="usage/configuration/config_documentation.html#individual-worker-configuration">The second part</a>
  7190. controls the behaviour of individual workers in isolation.</li>
  7191. </ol>
  7192. <p>For guidance on setting up workers, see the <a href="usage/configuration/../../workers.html">worker documentation</a>.</p>
  7193. <hr />
  7194. <h3 id="worker_replication_secret"><a class="header" href="#worker_replication_secret"><code>worker_replication_secret</code></a></h3>
  7195. <p>A shared secret used by the replication APIs on the main process to authenticate
  7196. HTTP requests from workers.</p>
  7197. <p>The default, this value is omitted (equivalently <code>null</code>), which means that
  7198. traffic between the workers and the main process is not authenticated.</p>
  7199. <p>Example configuration:</p>
  7200. <pre><code class="language-yaml">worker_replication_secret: &quot;secret_secret&quot;
  7201. </code></pre>
  7202. <hr />
  7203. <h3 id="start_pushers"><a class="header" href="#start_pushers"><code>start_pushers</code></a></h3>
  7204. <p>Unnecessary to set if using <a href="usage/configuration/config_documentation.html#pusher_instances"><code>pusher_instances</code></a> with <a href="usage/configuration/../../workers.html#synapseappgeneric_worker"><code>generic_workers</code></a>.</p>
  7205. <p>Controls sending of push notifications on the main process. Set to <code>false</code>
  7206. if using a <a href="usage/configuration/../../workers.html#synapseapppusher">pusher worker</a>. Defaults to <code>true</code>.</p>
  7207. <p>Example configuration:</p>
  7208. <pre><code class="language-yaml">start_pushers: false
  7209. </code></pre>
  7210. <hr />
  7211. <h3 id="pusher_instances"><a class="header" href="#pusher_instances"><code>pusher_instances</code></a></h3>
  7212. <p>It is possible to scale the processes that handle sending push notifications to <a href="https://github.com/matrix-org/sygnal">sygnal</a>
  7213. and email by running a <a href="usage/configuration/../../workers.html#synapseappgeneric_worker"><code>generic_worker</code></a> and adding it's <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a> to
  7214. a <code>pusher_instances</code> map. Doing so will remove handling of this function from the main
  7215. process. Multiple workers can be added to this map, in which case the work is balanced
  7216. across them. Ensure the main process and all pusher workers are restarted after changing
  7217. this option.</p>
  7218. <p>Example configuration for a single worker:</p>
  7219. <pre><code class="language-yaml">pusher_instances:
  7220. - pusher_worker1
  7221. </code></pre>
  7222. <p>And for multiple workers:</p>
  7223. <pre><code class="language-yaml">pusher_instances:
  7224. - pusher_worker1
  7225. - pusher_worker2
  7226. </code></pre>
  7227. <hr />
  7228. <h3 id="send_federation"><a class="header" href="#send_federation"><code>send_federation</code></a></h3>
  7229. <p>Unnecessary to set if using <a href="usage/configuration/config_documentation.html#federation_sender_instances"><code>federation_sender_instances</code></a> with <a href="usage/configuration/../../workers.html#synapseappgeneric_worker"><code>generic_workers</code></a>.</p>
  7230. <p>Controls sending of outbound federation transactions on the main process.
  7231. Set to <code>false</code> if using a <a href="usage/configuration/../../workers.html#synapseappfederation_sender">federation sender worker</a>.
  7232. Defaults to <code>true</code>.</p>
  7233. <p>Example configuration:</p>
  7234. <pre><code class="language-yaml">send_federation: false
  7235. </code></pre>
  7236. <hr />
  7237. <h3 id="federation_sender_instances"><a class="header" href="#federation_sender_instances"><code>federation_sender_instances</code></a></h3>
  7238. <p>It is possible to scale the processes that handle sending outbound federation requests
  7239. by running a <a href="usage/configuration/../../workers.html#synapseappgeneric_worker"><code>generic_worker</code></a> and adding it's <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a> to
  7240. a <code>federation_sender_instances</code> map. Doing so will remove handling of this function from
  7241. the main process. Multiple workers can be added to this map, in which case the work is
  7242. balanced across them.</p>
  7243. <p>This configuration setting must be shared between all workers handling federation
  7244. sending, and if changed all federation sender workers must be stopped at the same time
  7245. and then started, to ensure that all instances are running with the same config (otherwise
  7246. events may be dropped).</p>
  7247. <p>Example configuration for a single worker:</p>
  7248. <pre><code class="language-yaml">federation_sender_instances:
  7249. - federation_sender1
  7250. </code></pre>
  7251. <p>And for multiple workers:</p>
  7252. <pre><code class="language-yaml">federation_sender_instances:
  7253. - federation_sender1
  7254. - federation_sender2
  7255. </code></pre>
  7256. <hr />
  7257. <h3 id="instance_map"><a class="header" href="#instance_map"><code>instance_map</code></a></h3>
  7258. <p>When using workers this should be a map from <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a> to the HTTP
  7259. replication listener of the worker, if configured, and to the main process. Each worker
  7260. declared under <a href="usage/configuration/../../workers.html#stream-writers"><code>stream_writers</code></a> and
  7261. <a href="usage/configuration/config_documentation.html#outbound_federation_restricted_to"><code>outbound_federation_restricted_to</code></a> needs a HTTP
  7262. replication listener, and that listener should be included in the <code>instance_map</code>. The
  7263. main process also needs an entry on the <code>instance_map</code>, and it should be listed under
  7264. <code>main</code> <strong>if even one other worker exists</strong>. Ensure the port matches with what is
  7265. declared inside the <code>listener</code> block for a <code>replication</code> listener.</p>
  7266. <p>Example configuration:</p>
  7267. <pre><code class="language-yaml">instance_map:
  7268. main:
  7269. host: localhost
  7270. port: 8030
  7271. worker1:
  7272. host: localhost
  7273. port: 8034
  7274. </code></pre>
  7275. <p>Example configuration(#2, for UNIX sockets):</p>
  7276. <pre><code class="language-yaml">instance_map:
  7277. main:
  7278. path: /run/synapse/main_replication.sock
  7279. worker1:
  7280. path: /run/synapse/worker1_replication.sock
  7281. </code></pre>
  7282. <hr />
  7283. <h3 id="stream_writers"><a class="header" href="#stream_writers"><code>stream_writers</code></a></h3>
  7284. <p>Experimental: When using workers you can define which workers should
  7285. handle writing to streams such as event persistence and typing notifications.
  7286. Any worker specified here must also be in the <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a>.</p>
  7287. <p>See the list of available streams in the
  7288. <a href="usage/configuration/../../workers.html#stream-writers">worker documentation</a>.</p>
  7289. <p>Example configuration:</p>
  7290. <pre><code class="language-yaml">stream_writers:
  7291. events: worker1
  7292. typing: worker1
  7293. </code></pre>
  7294. <hr />
  7295. <h3 id="outbound_federation_restricted_to"><a class="header" href="#outbound_federation_restricted_to"><code>outbound_federation_restricted_to</code></a></h3>
  7296. <p>When using workers, you can restrict outbound federation traffic to only go through a
  7297. specific subset of workers. Any worker specified here must also be in the
  7298. <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a>.
  7299. <a href="usage/configuration/config_documentation.html#worker_replication_secret"><code>worker_replication_secret</code></a> must also be configured to
  7300. authorize inter-worker communication.</p>
  7301. <pre><code class="language-yaml">outbound_federation_restricted_to:
  7302. - federation_sender1
  7303. - federation_sender2
  7304. </code></pre>
  7305. <p>Also see the <a href="usage/configuration/../../workers.html#restrict-outbound-federation-traffic-to-a-specific-set-of-workers">worker
  7306. documentation</a>
  7307. for more info.</p>
  7308. <p><em>Added in Synapse 1.89.0.</em></p>
  7309. <hr />
  7310. <h3 id="run_background_tasks_on"><a class="header" href="#run_background_tasks_on"><code>run_background_tasks_on</code></a></h3>
  7311. <p>The <a href="usage/configuration/../../workers.html#background-tasks">worker</a> that is used to run
  7312. background tasks (e.g. cleaning up expired data). If not provided this
  7313. defaults to the main process.</p>
  7314. <p>Example configuration:</p>
  7315. <pre><code class="language-yaml">run_background_tasks_on: worker1
  7316. </code></pre>
  7317. <hr />
  7318. <h3 id="update_user_directory_from_worker"><a class="header" href="#update_user_directory_from_worker"><code>update_user_directory_from_worker</code></a></h3>
  7319. <p>The <a href="usage/configuration/../../workers.html#updating-the-user-directory">worker</a> that is used to
  7320. update the user directory. If not provided this defaults to the main process.</p>
  7321. <p>Example configuration:</p>
  7322. <pre><code class="language-yaml">update_user_directory_from_worker: worker1
  7323. </code></pre>
  7324. <p><em>Added in Synapse 1.59.0.</em></p>
  7325. <hr />
  7326. <h3 id="notify_appservices_from_worker"><a class="header" href="#notify_appservices_from_worker"><code>notify_appservices_from_worker</code></a></h3>
  7327. <p>The <a href="usage/configuration/../../workers.html#notifying-application-services">worker</a> that is used to
  7328. send output traffic to Application Services. If not provided this defaults
  7329. to the main process.</p>
  7330. <p>Example configuration:</p>
  7331. <pre><code class="language-yaml">notify_appservices_from_worker: worker1
  7332. </code></pre>
  7333. <p><em>Added in Synapse 1.59.0.</em></p>
  7334. <hr />
  7335. <h3 id="media_instance_running_background_jobs"><a class="header" href="#media_instance_running_background_jobs"><code>media_instance_running_background_jobs</code></a></h3>
  7336. <p>The <a href="usage/configuration/../../workers.html#synapseappmedia_repository">worker</a> that is used to run
  7337. background tasks for media repository. If running multiple media repositories
  7338. you must configure a single instance to run the background tasks. If not provided
  7339. this defaults to the main process or your single <code>media_repository</code> worker.</p>
  7340. <p>Example configuration:</p>
  7341. <pre><code class="language-yaml">media_instance_running_background_jobs: worker1
  7342. </code></pre>
  7343. <p><em>Added in Synapse 1.16.0.</em></p>
  7344. <hr />
  7345. <h3 id="redis"><a class="header" href="#redis"><code>redis</code></a></h3>
  7346. <p>Configuration for Redis when using workers. This <em>must</em> be enabled when using workers.
  7347. This setting has the following sub-options:</p>
  7348. <ul>
  7349. <li>
  7350. <p><code>enabled</code>: whether to use Redis support. Defaults to false.</p>
  7351. </li>
  7352. <li>
  7353. <p><code>host</code> and <code>port</code>: Optional host and port to use to connect to redis. Defaults to
  7354. localhost and 6379</p>
  7355. </li>
  7356. <li>
  7357. <p><code>path</code>: The full path to a local Unix socket file. <strong>If this is used, <code>host</code> and
  7358. <code>port</code> are ignored.</strong> Defaults to `/tmp/redis.sock'</p>
  7359. </li>
  7360. <li>
  7361. <p><code>password</code>: Optional password if configured on the Redis instance.</p>
  7362. </li>
  7363. <li>
  7364. <p><code>dbid</code>: Optional redis dbid if needs to connect to specific redis logical db.</p>
  7365. </li>
  7366. <li>
  7367. <p><code>use_tls</code>: Whether to use tls connection. Defaults to false.</p>
  7368. </li>
  7369. <li>
  7370. <p><code>certificate_file</code>: Optional path to the certificate file</p>
  7371. </li>
  7372. <li>
  7373. <p><code>private_key_file</code>: Optional path to the private key file</p>
  7374. </li>
  7375. <li>
  7376. <p><code>ca_file</code>: Optional path to the CA certificate file. Use this one or:</p>
  7377. </li>
  7378. <li>
  7379. <p><code>ca_path</code>: Optional path to the folder containing the CA certificate file</p>
  7380. <p><em>Added in Synapse 1.78.0.</em></p>
  7381. <p><em>Changed in Synapse 1.84.0: Added use_tls, certificate_file, private_key_file, ca_file and ca_path attributes</em></p>
  7382. <p><em>Changed in Synapse 1.85.0: Added path option to use a local Unix socket</em></p>
  7383. </li>
  7384. </ul>
  7385. <p>Example configuration:</p>
  7386. <pre><code class="language-yaml">redis:
  7387. enabled: true
  7388. host: localhost
  7389. port: 6379
  7390. password: &lt;secret_password&gt;
  7391. dbid: &lt;dbid&gt;
  7392. #use_tls: True
  7393. #certificate_file: &lt;path_to_the_certificate_file&gt;
  7394. #private_key_file: &lt;path_to_the_private_key_file&gt;
  7395. #ca_file: &lt;path_to_the_ca_certificate_file&gt;
  7396. </code></pre>
  7397. <hr />
  7398. <h2 id="individual-worker-configuration"><a class="header" href="#individual-worker-configuration">Individual worker configuration</a></h2>
  7399. <p>These options configure an individual worker, in its worker configuration file.
  7400. They should be not be provided when configuring the main process.</p>
  7401. <p>Note also the configuration above for
  7402. <a href="usage/configuration/config_documentation.html#coordinating-workers">coordinating a cluster of workers</a>.</p>
  7403. <p>For guidance on setting up workers, see the <a href="usage/configuration/../../workers.html">worker documentation</a>.</p>
  7404. <hr />
  7405. <h3 id="worker_app"><a class="header" href="#worker_app"><code>worker_app</code></a></h3>
  7406. <p>The type of worker. The currently available worker applications are listed
  7407. in <a href="usage/configuration/../../workers.html#available-worker-applications">worker documentation</a>.</p>
  7408. <p>The most common worker is the
  7409. <a href="usage/configuration/../../workers.html#synapseappgeneric_worker"><code>synapse.app.generic_worker</code></a>.</p>
  7410. <p>Example configuration:</p>
  7411. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  7412. </code></pre>
  7413. <hr />
  7414. <h3 id="worker_name"><a class="header" href="#worker_name"><code>worker_name</code></a></h3>
  7415. <p>A unique name for the worker. The worker needs a name to be addressed in
  7416. further parameters and identification in log files. We strongly recommend
  7417. giving each worker a unique <code>worker_name</code>.</p>
  7418. <p>Example configuration:</p>
  7419. <pre><code class="language-yaml">worker_name: generic_worker1
  7420. </code></pre>
  7421. <hr />
  7422. <h3 id="worker_listeners"><a class="header" href="#worker_listeners"><code>worker_listeners</code></a></h3>
  7423. <p>A worker can handle HTTP requests. To do so, a <code>worker_listeners</code> option
  7424. must be declared, in the same way as the <a href="usage/configuration/config_documentation.html#listeners"><code>listeners</code> option</a>
  7425. in the shared config.</p>
  7426. <p>Workers declared in <a href="usage/configuration/config_documentation.html#stream_writers"><code>stream_writers</code></a> and <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a>
  7427. will need to include a <code>replication</code> listener here, in order to accept internal HTTP
  7428. requests from other workers.</p>
  7429. <p>Example configuration:</p>
  7430. <pre><code class="language-yaml">worker_listeners:
  7431. - type: http
  7432. port: 8083
  7433. resources:
  7434. - names: [client, federation]
  7435. </code></pre>
  7436. <p>Example configuration(#2, using UNIX sockets with a <code>replication</code> listener):</p>
  7437. <pre><code class="language-yaml">worker_listeners:
  7438. - type: http
  7439. path: /run/synapse/worker_replication.sock
  7440. resources:
  7441. - names: [replication]
  7442. - type: http
  7443. path: /run/synapse/worker_public.sock
  7444. resources:
  7445. - names: [client, federation]
  7446. </code></pre>
  7447. <hr />
  7448. <h3 id="worker_manhole"><a class="header" href="#worker_manhole"><code>worker_manhole</code></a></h3>
  7449. <p>A worker may have a listener for <a href="usage/configuration/../../manhole.html"><code>manhole</code></a>.
  7450. It allows server administrators to access a Python shell on the worker.</p>
  7451. <p>Example configuration:</p>
  7452. <pre><code class="language-yaml">worker_manhole: 9000
  7453. </code></pre>
  7454. <p>This is a short form for:</p>
  7455. <pre><code class="language-yaml">worker_listeners:
  7456. - port: 9000
  7457. bind_addresses: ['127.0.0.1']
  7458. type: manhole
  7459. </code></pre>
  7460. <p>It needs also an additional <a href="usage/configuration/config_documentation.html#manhole_settings"><code>manhole_settings</code></a> configuration.</p>
  7461. <hr />
  7462. <h3 id="worker_daemonize"><a class="header" href="#worker_daemonize"><code>worker_daemonize</code></a></h3>
  7463. <p>Specifies whether the worker should be started as a daemon process.
  7464. If Synapse is being managed by <a href="usage/configuration/../../systemd-with-workers/">systemd</a>, this option
  7465. must be omitted or set to <code>false</code>.</p>
  7466. <p>Defaults to <code>false</code>.</p>
  7467. <p>Example configuration:</p>
  7468. <pre><code class="language-yaml">worker_daemonize: true
  7469. </code></pre>
  7470. <hr />
  7471. <h3 id="worker_pid_file"><a class="header" href="#worker_pid_file"><code>worker_pid_file</code></a></h3>
  7472. <p>When running a worker as a daemon, we need a place to store the
  7473. <a href="https://en.wikipedia.org/wiki/Process_identifier">PID</a> of the worker.
  7474. This option defines the location of that &quot;pid file&quot;.</p>
  7475. <p>This option is required if <code>worker_daemonize</code> is <code>true</code> and ignored
  7476. otherwise. It has no default.</p>
  7477. <p>See also the <a href="usage/configuration/config_documentation.html#pid_file"><code>pid_file</code> option</a> option for the main Synapse process.</p>
  7478. <p>Example configuration:</p>
  7479. <pre><code class="language-yaml">worker_pid_file: DATADIR/generic_worker1.pid
  7480. </code></pre>
  7481. <hr />
  7482. <h3 id="worker_log_config"><a class="header" href="#worker_log_config"><code>worker_log_config</code></a></h3>
  7483. <p>This option specifies a yaml python logging config file as described
  7484. <a href="https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema">here</a>.
  7485. See also the <a href="usage/configuration/config_documentation.html#log_config"><code>log_config</code> option</a> option for the main Synapse process.</p>
  7486. <p>Example configuration:</p>
  7487. <pre><code class="language-yaml">worker_log_config: /etc/matrix-synapse/generic-worker-log.yaml
  7488. </code></pre>
  7489. <hr />
  7490. <h2 id="background-updates"><a class="header" href="#background-updates">Background Updates</a></h2>
  7491. <p>Configuration settings related to background updates.</p>
  7492. <hr />
  7493. <h3 id="background_updates"><a class="header" href="#background_updates"><code>background_updates</code></a></h3>
  7494. <p>Background updates are database updates that are run in the background in batches.
  7495. The duration, minimum batch size, default batch size, whether to sleep between batches and if so, how long to
  7496. sleep can all be configured. This is helpful to speed up or slow down the updates.
  7497. This setting has the following sub-options:</p>
  7498. <ul>
  7499. <li><code>background_update_duration_ms</code>: How long in milliseconds to run a batch of background updates for. Defaults to 100.
  7500. Set a different time to change the default.</li>
  7501. <li><code>sleep_enabled</code>: Whether to sleep between updates. Defaults to true. Set to false to change the default.</li>
  7502. <li><code>sleep_duration_ms</code>: If sleeping between updates, how long in milliseconds to sleep for. Defaults to 1000.
  7503. Set a duration to change the default.</li>
  7504. <li><code>min_batch_size</code>: Minimum size a batch of background updates can be. Must be greater than 0. Defaults to 1.
  7505. Set a size to change the default.</li>
  7506. <li><code>default_batch_size</code>: The batch size to use for the first iteration of a new background update. The default is 100.
  7507. Set a size to change the default.</li>
  7508. </ul>
  7509. <p>Example configuration:</p>
  7510. <pre><code class="language-yaml">background_updates:
  7511. background_update_duration_ms: 500
  7512. sleep_enabled: false
  7513. sleep_duration_ms: 300
  7514. min_batch_size: 10
  7515. default_batch_size: 50
  7516. </code></pre>
  7517. <div style="break-before: page; page-break-before: always;"></div><h1 id="homeserver-sample-configuration-file"><a class="header" href="#homeserver-sample-configuration-file">Homeserver Sample Configuration File</a></h1>
  7518. <p>Below is a sample homeserver configuration file. The homeserver configuration file
  7519. can be tweaked to change the behaviour of your homeserver. A restart of the server is
  7520. generally required to apply any changes made to this file.</p>
  7521. <p>Note that the contents below are <em>not</em> intended to be copied and used as the basis for
  7522. a real homeserver.yaml. Instead, if you are starting from scratch, please generate
  7523. a fresh config using Synapse by following the instructions in
  7524. <a href="usage/configuration/../../setup/installation.html">Installation</a>.</p>
  7525. <p>Documentation for all configuration options can be found in the
  7526. <a href="usage/configuration/./config_documentation.html">Configuration Manual</a>.</p>
  7527. <pre><code class="language-yaml"># This file is maintained as an up-to-date snapshot of the default
  7528. # homeserver.yaml configuration generated by Synapse. You can find a
  7529. # complete accounting of possible configuration options at
  7530. # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
  7531. #
  7532. # It is *not* intended to be copied and used as the basis for a real
  7533. # homeserver.yaml. Instead, if you are starting from scratch, please generate
  7534. # a fresh config using Synapse by following the instructions in
  7535. # https://matrix-org.github.io/synapse/latest/setup/installation.html.
  7536. #
  7537. ################################################################################
  7538. # Configuration file for Synapse.
  7539. #
  7540. # This is a YAML file: see [1] for a quick introduction. Note in particular
  7541. # that *indentation is important*: all the elements of a list or dictionary
  7542. # should have the same indentation.
  7543. #
  7544. # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
  7545. #
  7546. # For more information on how to configure Synapse, including a complete accounting of
  7547. # each option, go to docs/usage/configuration/config_documentation.md or
  7548. # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
  7549. server_name: &quot;SERVERNAME&quot;
  7550. pid_file: DATADIR/homeserver.pid
  7551. listeners:
  7552. - port: 8008
  7553. tls: false
  7554. type: http
  7555. x_forwarded: true
  7556. bind_addresses: ['::1', '127.0.0.1']
  7557. resources:
  7558. - names: [client, federation]
  7559. compress: false
  7560. database:
  7561. name: sqlite3
  7562. args:
  7563. database: DATADIR/homeserver.db
  7564. log_config: &quot;CONFDIR/SERVERNAME.log.config&quot;
  7565. media_store_path: DATADIR/media_store
  7566. signing_key_path: &quot;CONFDIR/SERVERNAME.signing.key&quot;
  7567. trusted_key_servers:
  7568. - server_name: &quot;matrix.org&quot;
  7569. </code></pre>
  7570. <div style="break-before: page; page-break-before: always;"></div><h1 id="logging-sample-configuration-file"><a class="header" href="#logging-sample-configuration-file">Logging Sample Configuration File</a></h1>
  7571. <p>Below is a sample logging configuration file. This file can be tweaked to control how your
  7572. homeserver will output logs. The value of the <code>log_config</code> option in your homeserver config
  7573. should be the path to this file.</p>
  7574. <p>To apply changes made to this file, send Synapse a SIGHUP signal (or, if using <code>systemd</code>, run
  7575. <code>systemctl reload</code> on the Synapse service).</p>
  7576. <p>Note that a default logging configuration (shown below) is created automatically alongside
  7577. the homeserver config when following the <a href="usage/configuration/../../setup/installation.html">installation instructions</a>.
  7578. It should be named <code>&lt;SERVERNAME&gt;.log.config</code> by default.</p>
  7579. <pre><code class="language-yaml"># Log configuration for Synapse.
  7580. #
  7581. # This is a YAML file containing a standard Python logging configuration
  7582. # dictionary. See [1] for details on the valid settings.
  7583. #
  7584. # Synapse also supports structured logging for machine readable logs which can
  7585. # be ingested by ELK stacks. See [2] for details.
  7586. #
  7587. # [1]: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema
  7588. # [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html
  7589. version: 1
  7590. formatters:
  7591. precise:
  7592. format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
  7593. handlers:
  7594. file:
  7595. class: logging.handlers.TimedRotatingFileHandler
  7596. formatter: precise
  7597. filename: /var/log/matrix-synapse/homeserver.log
  7598. when: midnight
  7599. backupCount: 3 # Does not include the current log file.
  7600. encoding: utf8
  7601. # Default to buffering writes to log file for efficiency.
  7602. # WARNING/ERROR logs will still be flushed immediately, but there will be a
  7603. # delay (of up to `period` seconds, or until the buffer is full with
  7604. # `capacity` messages) before INFO/DEBUG logs get written.
  7605. buffer:
  7606. class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler
  7607. target: file
  7608. # The capacity is the maximum number of log lines that are buffered
  7609. # before being written to disk. Increasing this will lead to better
  7610. # performance, at the expensive of it taking longer for log lines to
  7611. # be written to disk.
  7612. # This parameter is required.
  7613. capacity: 10
  7614. # Logs with a level at or above the flush level will cause the buffer to
  7615. # be flushed immediately.
  7616. # Default value: 40 (ERROR)
  7617. # Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG)
  7618. flushLevel: 30 # Flush immediately for WARNING logs and higher
  7619. # The period of time, in seconds, between forced flushes.
  7620. # Messages will not be delayed for longer than this time.
  7621. # Default value: 5 seconds
  7622. period: 5
  7623. # A handler that writes logs to stderr. Unused by default, but can be used
  7624. # instead of &quot;buffer&quot; and &quot;file&quot; in the logger handlers.
  7625. console:
  7626. class: logging.StreamHandler
  7627. formatter: precise
  7628. loggers:
  7629. synapse.storage.SQL:
  7630. # beware: increasing this to DEBUG will make synapse log sensitive
  7631. # information such as access tokens.
  7632. level: INFO
  7633. root:
  7634. level: INFO
  7635. # Write logs to the `buffer` handler, which will buffer them together in memory,
  7636. # then write them to a file.
  7637. #
  7638. # Replace &quot;buffer&quot; with &quot;console&quot; to log to stderr instead.
  7639. #
  7640. handlers: [buffer]
  7641. disable_existing_loggers: false
  7642. </code></pre>
  7643. <div style="break-before: page; page-break-before: always;"></div><h1 id="structured-logging"><a class="header" href="#structured-logging">Structured Logging</a></h1>
  7644. <p>A structured logging system can be useful when your logs are destined for a
  7645. machine to parse and process. By maintaining its machine-readable characteristics,
  7646. it enables more efficient searching and aggregations when consumed by software
  7647. such as the <a href="https://opensource.com/article/18/9/open-source-log-aggregation-tools">ELK stack</a>.</p>
  7648. <p>Synapse's structured logging system is configured via the file that Synapse's
  7649. <code>log_config</code> config option points to. The file should include a formatter which
  7650. uses the <code>synapse.logging.TerseJsonFormatter</code> class included with Synapse and a
  7651. handler which uses the above formatter.</p>
  7652. <p>There is also a <code>synapse.logging.JsonFormatter</code> option which does not include
  7653. a timestamp in the resulting JSON. This is useful if the log ingester adds its
  7654. own timestamp.</p>
  7655. <p>A structured logging configuration looks similar to the following:</p>
  7656. <pre><code class="language-yaml">version: 1
  7657. formatters:
  7658. structured:
  7659. class: synapse.logging.TerseJsonFormatter
  7660. handlers:
  7661. file:
  7662. class: logging.handlers.TimedRotatingFileHandler
  7663. formatter: structured
  7664. filename: /path/to/my/logs/homeserver.log
  7665. when: midnight
  7666. backupCount: 3 # Does not include the current log file.
  7667. encoding: utf8
  7668. loggers:
  7669. synapse:
  7670. level: INFO
  7671. handlers: [remote]
  7672. synapse.storage.SQL:
  7673. level: WARNING
  7674. </code></pre>
  7675. <p>The above logging config will set Synapse as 'INFO' logging level by default,
  7676. with the SQL layer at 'WARNING', and will log to a file, stored as JSON.</p>
  7677. <p>It is also possible to configure Synapse to log to a remote endpoint by using the
  7678. <code>synapse.logging.RemoteHandler</code> class included with Synapse. It takes the
  7679. following arguments:</p>
  7680. <ul>
  7681. <li><code>host</code>: Hostname or IP address of the log aggregator.</li>
  7682. <li><code>port</code>: Numerical port to contact on the host.</li>
  7683. <li><code>maximum_buffer</code>: (Optional, defaults to 1000) The maximum buffer size to allow.</li>
  7684. </ul>
  7685. <p>A remote structured logging configuration looks similar to the following:</p>
  7686. <pre><code class="language-yaml">version: 1
  7687. formatters:
  7688. structured:
  7689. class: synapse.logging.TerseJsonFormatter
  7690. handlers:
  7691. remote:
  7692. class: synapse.logging.RemoteHandler
  7693. formatter: structured
  7694. host: 10.1.2.3
  7695. port: 9999
  7696. loggers:
  7697. synapse:
  7698. level: INFO
  7699. handlers: [remote]
  7700. synapse.storage.SQL:
  7701. level: WARNING
  7702. </code></pre>
  7703. <p>The above logging config will set Synapse as 'INFO' logging level by default,
  7704. with the SQL layer at 'WARNING', and will log JSON formatted messages to a
  7705. remote endpoint at 10.1.2.3:9999.</p>
  7706. <div style="break-before: page; page-break-before: always;"></div><h1 id="templates"><a class="header" href="#templates">Templates</a></h1>
  7707. <p>Synapse uses parametrised templates to generate the content of emails it sends and
  7708. webpages it shows to users.</p>
  7709. <p>By default, Synapse will use the templates listed <a href="https://github.com/matrix-org/synapse/tree/master/synapse/res/templates">here</a>.
  7710. Server admins can configure an additional directory for Synapse to look for templates
  7711. in, allowing them to specify custom templates:</p>
  7712. <pre><code class="language-yaml">templates:
  7713. custom_template_directory: /path/to/custom/templates/
  7714. </code></pre>
  7715. <p>If this setting is not set, or the files named below are not found within the directory,
  7716. default templates from within the Synapse package will be used.</p>
  7717. <p>Templates that are given variables when being rendered are rendered using <a href="https://jinja.palletsprojects.com/en/2.11.x/">Jinja 2</a>.
  7718. Templates rendered by Jinja 2 can also access two functions on top of the functions
  7719. already available as part of Jinja 2:</p>
  7720. <pre><code class="language-python">format_ts(value: int, format: str) -&gt; str
  7721. </code></pre>
  7722. <p>Formats a timestamp in milliseconds.</p>
  7723. <p>Example: <code>reason.last_sent_ts|format_ts(&quot;%c&quot;)</code></p>
  7724. <pre><code class="language-python">mxc_to_http(value: str, width: int, height: int, resize_method: str = &quot;crop&quot;) -&gt; str
  7725. </code></pre>
  7726. <p>Turns a <code>mxc://</code> URL for media content into an HTTP(S) one using the homeserver's
  7727. <code>public_baseurl</code> configuration setting as the URL's base.</p>
  7728. <p>Example: <code>message.sender_avatar_url|mxc_to_http(32,32)</code></p>
  7729. <pre><code class="language-python">localpart_from_email(address: str) -&gt; str
  7730. </code></pre>
  7731. <p>Returns the local part of an email address (e.g. <code>alice</code> in <code>alice@example.com</code>).</p>
  7732. <p>Example: <code>user.email_address|localpart_from_email</code></p>
  7733. <h2 id="email-templates"><a class="header" href="#email-templates">Email templates</a></h2>
  7734. <p>Below are the templates Synapse will look for when generating the content of an email:</p>
  7735. <ul>
  7736. <li><code>notif_mail.html</code> and <code>notif_mail.txt</code>: The contents of email notifications of missed
  7737. events.
  7738. When rendering, this template is given the following variables:
  7739. <ul>
  7740. <li><code>user_display_name</code>: the display name for the user receiving the notification</li>
  7741. <li><code>unsubscribe_link</code>: the link users can click to unsubscribe from email notifications</li>
  7742. <li><code>summary_text</code>: a summary of the notification(s). The text used can be customised
  7743. by configuring the various settings in the <code>email.subjects</code> section of the
  7744. configuration file.</li>
  7745. <li><code>rooms</code>: a list of rooms containing events to include in the email. Each element is
  7746. an object with the following attributes:
  7747. <ul>
  7748. <li><code>title</code>: a human-readable name for the room</li>
  7749. <li><code>hash</code>: a hash of the ID of the room</li>
  7750. <li><code>invite</code>: a boolean, which is <code>True</code> if the room is an invite the user hasn't
  7751. accepted yet, <code>False</code> otherwise</li>
  7752. <li><code>notifs</code>: a list of events, or an empty list if <code>invite</code> is <code>True</code>. Each element
  7753. is an object with the following attributes:
  7754. <ul>
  7755. <li><code>link</code>: a <code>matrix.to</code> link to the event</li>
  7756. <li><code>ts</code>: the time in milliseconds at which the event was received</li>
  7757. <li><code>messages</code>: a list of messages containing one message before the event, the
  7758. message in the event, and one message after the event. Each element is an
  7759. object with the following attributes:
  7760. <ul>
  7761. <li><code>event_type</code>: the type of the event</li>
  7762. <li><code>is_historical</code>: a boolean, which is <code>False</code> if the message is the one
  7763. that triggered the notification, <code>True</code> otherwise</li>
  7764. <li><code>id</code>: the ID of the event</li>
  7765. <li><code>ts</code>: the time in milliseconds at which the event was sent</li>
  7766. <li><code>sender_name</code>: the display name for the event's sender</li>
  7767. <li><code>sender_avatar_url</code>: the avatar URL (as a <code>mxc://</code> URL) for the event's
  7768. sender</li>
  7769. <li><code>sender_hash</code>: a hash of the user ID of the sender</li>
  7770. <li><code>msgtype</code>: the type of the message</li>
  7771. <li><code>body_text_html</code>: html representation of the message</li>
  7772. <li><code>body_text_plain</code>: plaintext representation of the message</li>
  7773. <li><code>image_url</code>: mxc url of an image, when &quot;msgtype&quot; is &quot;m.image&quot;</li>
  7774. </ul>
  7775. </li>
  7776. </ul>
  7777. </li>
  7778. <li><code>link</code>: a <code>matrix.to</code> link to the room</li>
  7779. <li><code>avator_url</code>: url to the room's avator</li>
  7780. </ul>
  7781. </li>
  7782. <li><code>reason</code>: information on the event that triggered the email to be sent. It's an
  7783. object with the following attributes:
  7784. <ul>
  7785. <li><code>room_id</code>: the ID of the room the event was sent in</li>
  7786. <li><code>room_name</code>: a human-readable name for the room the event was sent in</li>
  7787. <li><code>now</code>: the current time in milliseconds</li>
  7788. <li><code>received_at</code>: the time in milliseconds at which the event was received</li>
  7789. <li><code>delay_before_mail_ms</code>: the amount of time in milliseconds Synapse always waits
  7790. before ever emailing about a notification (to give the user a chance to respond
  7791. to other push or notice the window)</li>
  7792. <li><code>last_sent_ts</code>: the time in milliseconds at which a notification was last sent
  7793. for an event in this room</li>
  7794. <li><code>throttle_ms</code>: the minimum amount of time in milliseconds between two
  7795. notifications can be sent for this room</li>
  7796. </ul>
  7797. </li>
  7798. </ul>
  7799. </li>
  7800. <li><code>password_reset.html</code> and <code>password_reset.txt</code>: The contents of password reset emails
  7801. sent by the homeserver.
  7802. When rendering, these templates are given a <code>link</code> variable which contains the link the
  7803. user must click in order to reset their password.</li>
  7804. <li><code>registration.html</code> and <code>registration.txt</code>: The contents of address verification emails
  7805. sent during registration.
  7806. When rendering, these templates are given a <code>link</code> variable which contains the link the
  7807. user must click in order to validate their email address.</li>
  7808. <li><code>add_threepid.html</code> and <code>add_threepid.txt</code>: The contents of address verification emails
  7809. sent when an address is added to a Matrix account.
  7810. When rendering, these templates are given a <code>link</code> variable which contains the link the
  7811. user must click in order to validate their email address.</li>
  7812. </ul>
  7813. <h2 id="html-page-templates-for-registration-and-password-reset"><a class="header" href="#html-page-templates-for-registration-and-password-reset">HTML page templates for registration and password reset</a></h2>
  7814. <p>Below are the templates Synapse will look for when generating pages related to
  7815. registration and password reset:</p>
  7816. <ul>
  7817. <li><code>password_reset_confirmation.html</code>: An HTML page that a user will see when they follow
  7818. the link in the password reset email. The user will be asked to confirm the action
  7819. before their password is reset.
  7820. When rendering, this template is given the following variables:
  7821. <ul>
  7822. <li><code>sid</code>: the session ID for the password reset</li>
  7823. <li><code>token</code>: the token for the password reset</li>
  7824. <li><code>client_secret</code>: the client secret for the password reset</li>
  7825. </ul>
  7826. </li>
  7827. <li><code>password_reset_success.html</code> and <code>password_reset_failure.html</code>: HTML pages for success
  7828. and failure that a user will see when they confirm the password reset flow using the
  7829. page above.
  7830. When rendering, <code>password_reset_success.html</code> is given no variable, and
  7831. <code>password_reset_failure.html</code> is given a <code>failure_reason</code>, which contains the reason
  7832. for the password reset failure. </li>
  7833. <li><code>registration_success.html</code> and <code>registration_failure.html</code>: HTML pages for success and
  7834. failure that a user will see when they follow the link in an address verification email
  7835. sent during registration.
  7836. When rendering, <code>registration_success.html</code> is given no variable, and
  7837. <code>registration_failure.html</code> is given a <code>failure_reason</code>, which contains the reason
  7838. for the registration failure.</li>
  7839. <li><code>add_threepid_success.html</code> and <code>add_threepid_failure.html</code>: HTML pages for success and
  7840. failure that a user will see when they follow the link in an address verification email
  7841. sent when an address is added to a Matrix account.
  7842. When rendering, <code>add_threepid_success.html</code> is given no variable, and
  7843. <code>add_threepid_failure.html</code> is given a <code>failure_reason</code>, which contains the reason
  7844. for the registration failure.</li>
  7845. </ul>
  7846. <h2 id="html-page-templates-for-single-sign-on-sso"><a class="header" href="#html-page-templates-for-single-sign-on-sso">HTML page templates for Single Sign-On (SSO)</a></h2>
  7847. <p>Below are the templates Synapse will look for when generating pages related to SSO:</p>
  7848. <ul>
  7849. <li><code>sso_login_idp_picker.html</code>: HTML page to prompt the user to choose an
  7850. Identity Provider during login.
  7851. This is only used if multiple SSO Identity Providers are configured.
  7852. When rendering, this template is given the following variables:
  7853. <ul>
  7854. <li><code>redirect_url</code>: the URL that the user will be redirected to after
  7855. login.</li>
  7856. <li><code>server_name</code>: the homeserver's name.</li>
  7857. <li><code>providers</code>: a list of available Identity Providers. Each element is
  7858. an object with the following attributes:
  7859. <ul>
  7860. <li><code>idp_id</code>: unique identifier for the IdP</li>
  7861. <li><code>idp_name</code>: user-facing name for the IdP</li>
  7862. <li><code>idp_icon</code>: if specified in the IdP config, an MXC URI for an icon
  7863. for the IdP</li>
  7864. <li><code>idp_brand</code>: if specified in the IdP config, a textual identifier
  7865. for the brand of the IdP
  7866. The rendered HTML page should contain a form which submits its results
  7867. back as a GET request, with the following query parameters:</li>
  7868. </ul>
  7869. </li>
  7870. <li><code>redirectUrl</code>: the client redirect URI (ie, the <code>redirect_url</code> passed
  7871. to the template)</li>
  7872. <li><code>idp</code>: the 'idp_id' of the chosen IDP.</li>
  7873. </ul>
  7874. </li>
  7875. <li><code>sso_auth_account_details.html</code>: HTML page to prompt new users to enter a
  7876. userid and confirm other details. This is only shown if the
  7877. SSO implementation (with any <code>user_mapping_provider</code>) does not return
  7878. a localpart.
  7879. When rendering, this template is given the following variables:
  7880. <ul>
  7881. <li><code>server_name</code>: the homeserver's name.</li>
  7882. <li><code>idp</code>: details of the SSO Identity Provider that the user logged in
  7883. with: an object with the following attributes:
  7884. <ul>
  7885. <li><code>idp_id</code>: unique identifier for the IdP</li>
  7886. <li><code>idp_name</code>: user-facing name for the IdP</li>
  7887. <li><code>idp_icon</code>: if specified in the IdP config, an MXC URI for an icon
  7888. for the IdP</li>
  7889. <li><code>idp_brand</code>: if specified in the IdP config, a textual identifier
  7890. for the brand of the IdP</li>
  7891. </ul>
  7892. </li>
  7893. <li><code>user_attributes</code>: an object containing details about the user that
  7894. we received from the IdP. May have the following attributes:
  7895. <ul>
  7896. <li><code>display_name</code>: the user's display name</li>
  7897. <li><code>emails</code>: a list of email addresses</li>
  7898. <li><code>localpart</code>: the local part of the Matrix user ID to register,
  7899. if <code>localpart_template</code> is set in the mapping provider configuration (empty
  7900. string if not)
  7901. The template should render a form which submits the following fields:</li>
  7902. </ul>
  7903. </li>
  7904. <li><code>username</code>: the localpart of the user's chosen user id</li>
  7905. </ul>
  7906. </li>
  7907. <li><code>sso_new_user_consent.html</code>: HTML page allowing the user to consent to the
  7908. server's terms and conditions. This is only shown for new users, and only if
  7909. <code>user_consent.require_at_registration</code> is set.
  7910. When rendering, this template is given the following variables:
  7911. <ul>
  7912. <li><code>server_name</code>: the homeserver's name.</li>
  7913. <li><code>user_id</code>: the user's matrix proposed ID.</li>
  7914. <li><code>user_profile.display_name</code>: the user's proposed display name, if any.</li>
  7915. <li>consent_version: the version of the terms that the user will be
  7916. shown</li>
  7917. <li><code>terms_url</code>: a link to the page showing the terms.
  7918. The template should render a form which submits the following fields:</li>
  7919. <li><code>accepted_version</code>: the version of the terms accepted by the user
  7920. (ie, 'consent_version' from the input variables).</li>
  7921. </ul>
  7922. </li>
  7923. <li><code>sso_redirect_confirm.html</code>: HTML page for a confirmation step before redirecting back
  7924. to the client with the login token.
  7925. When rendering, this template is given the following variables:
  7926. <ul>
  7927. <li><code>redirect_url</code>: the URL the user is about to be redirected to.</li>
  7928. <li><code>display_url</code>: the same as <code>redirect_url</code>, but with the query
  7929. parameters stripped. The intention is to have a
  7930. human-readable URL to show to users, not to use it as
  7931. the final address to redirect to.</li>
  7932. <li><code>server_name</code>: the homeserver's name.</li>
  7933. <li><code>new_user</code>: a boolean indicating whether this is the user's first time
  7934. logging in.</li>
  7935. <li><code>user_id</code>: the user's matrix ID.</li>
  7936. <li><code>user_profile.avatar_url</code>: an MXC URI for the user's avatar, if any.
  7937. <code>None</code> if the user has not set an avatar.</li>
  7938. <li><code>user_profile.display_name</code>: the user's display name. <code>None</code> if the user
  7939. has not set a display name.</li>
  7940. </ul>
  7941. </li>
  7942. <li><code>sso_auth_confirm.html</code>: HTML page which notifies the user that they are authenticating
  7943. to confirm an operation on their account during the user interactive authentication
  7944. process.
  7945. When rendering, this template is given the following variables:
  7946. <ul>
  7947. <li><code>redirect_url</code>: the URL the user is about to be redirected to.</li>
  7948. <li><code>description</code>: the operation which the user is being asked to confirm</li>
  7949. <li><code>idp</code>: details of the Identity Provider that we will use to confirm
  7950. the user's identity: an object with the following attributes:
  7951. <ul>
  7952. <li><code>idp_id</code>: unique identifier for the IdP</li>
  7953. <li><code>idp_name</code>: user-facing name for the IdP</li>
  7954. <li><code>idp_icon</code>: if specified in the IdP config, an MXC URI for an icon
  7955. for the IdP</li>
  7956. <li><code>idp_brand</code>: if specified in the IdP config, a textual identifier
  7957. for the brand of the IdP</li>
  7958. </ul>
  7959. </li>
  7960. </ul>
  7961. </li>
  7962. <li><code>sso_auth_success.html</code>: HTML page shown after a successful user interactive
  7963. authentication session.
  7964. Note that this page must include the JavaScript which notifies of a successful
  7965. authentication (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
  7966. This template has no additional variables.</li>
  7967. <li><code>sso_auth_bad_user.html</code>: HTML page shown after a user-interactive authentication
  7968. session which does not map correctly onto the expected user.
  7969. When rendering, this template is given the following variables:
  7970. <ul>
  7971. <li><code>server_name</code>: the homeserver's name.</li>
  7972. <li><code>user_id_to_verify</code>: the MXID of the user that we are trying to
  7973. validate.</li>
  7974. </ul>
  7975. </li>
  7976. <li><code>sso_account_deactivated.html</code>: HTML page shown during single sign-on if a deactivated
  7977. user (according to Synapse's database) attempts to login.
  7978. This template has no additional variables.</li>
  7979. <li><code>sso_error.html</code>: HTML page to display to users if something goes wrong during the
  7980. OpenID Connect authentication process.
  7981. When rendering, this template is given two variables:
  7982. <ul>
  7983. <li><code>error</code>: the technical name of the error</li>
  7984. <li><code>error_description</code>: a human-readable message for the error</li>
  7985. </ul>
  7986. </li>
  7987. </ul>
  7988. <div style="break-before: page; page-break-before: always;"></div><h1 id="user-authentication"><a class="header" href="#user-authentication">User Authentication</a></h1>
  7989. <p>Synapse supports multiple methods of authenticating users, either out-of-the-box or through custom pluggable
  7990. authentication modules.</p>
  7991. <p>Included in Synapse is support for authenticating users via:</p>
  7992. <ul>
  7993. <li>A username and password.</li>
  7994. <li>An email address and password.</li>
  7995. <li>Single Sign-On through the SAML, Open ID Connect or CAS protocols.</li>
  7996. <li>JSON Web Tokens.</li>
  7997. <li>An administrator's shared secret.</li>
  7998. </ul>
  7999. <p>Synapse can additionally be extended to support custom authentication schemes through optional &quot;password auth provider&quot;
  8000. modules.</p>
  8001. <div style="break-before: page; page-break-before: always;"></div><h1 id="single-sign-on"><a class="header" href="#single-sign-on">Single Sign-On</a></h1>
  8002. <p>Synapse supports single sign-on through the SAML, Open ID Connect or CAS protocols.
  8003. LDAP and other login methods are supported through first and third-party password
  8004. auth provider modules.</p>
  8005. <div style="break-before: page; page-break-before: always;"></div><h1 id="configuring-synapse-to-authenticate-against-an-openid-connect-provider"><a class="header" href="#configuring-synapse-to-authenticate-against-an-openid-connect-provider">Configuring Synapse to authenticate against an OpenID Connect provider</a></h1>
  8006. <p>Synapse can be configured to use an OpenID Connect Provider (OP) for
  8007. authentication, instead of its own local password database.</p>
  8008. <p>Any OP should work with Synapse, as long as it supports the authorization code
  8009. flow. There are a few options for that:</p>
  8010. <ul>
  8011. <li>
  8012. <p>start a local OP. Synapse has been tested with <a href="https://www.ory.sh/docs/hydra/">Hydra</a> and
  8013. <a href="https://github.com/dexidp/dex">Dex</a>. Note that for an OP to work, it should be served under a
  8014. secure (HTTPS) origin. A certificate signed with a self-signed, locally
  8015. trusted CA should work. In that case, start Synapse with a <code>SSL_CERT_FILE</code>
  8016. environment variable set to the path of the CA.</p>
  8017. </li>
  8018. <li>
  8019. <p>set up a SaaS OP, like <a href="https://developers.google.com/identity/protocols/oauth2/openid-connect">Google</a>, <a href="https://auth0.com/">Auth0</a> or
  8020. <a href="https://www.okta.com/">Okta</a>. Synapse has been tested with Auth0 and Google.</p>
  8021. </li>
  8022. </ul>
  8023. <p>It may also be possible to use other OAuth2 providers which provide the
  8024. <a href="https://tools.ietf.org/html/rfc6749#section-4.1">authorization code grant type</a>,
  8025. such as <a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps">Github</a>.</p>
  8026. <h2 id="preparing-synapse"><a class="header" href="#preparing-synapse">Preparing Synapse</a></h2>
  8027. <p>The OpenID integration in Synapse uses the
  8028. <a href="https://pypi.org/project/Authlib/"><code>authlib</code></a> library, which must be installed
  8029. as follows:</p>
  8030. <ul>
  8031. <li>
  8032. <p>The relevant libraries are included in the Docker images and Debian packages
  8033. provided by <code>matrix.org</code> so no further action is needed.</p>
  8034. </li>
  8035. <li>
  8036. <p>If you installed Synapse into a virtualenv, run <code>/path/to/env/bin/pip install matrix-synapse[oidc]</code> to install the necessary dependencies.</p>
  8037. </li>
  8038. <li>
  8039. <p>For other installation mechanisms, see the documentation provided by the
  8040. maintainer.</p>
  8041. </li>
  8042. </ul>
  8043. <p>To enable the OpenID integration, you should then add a section to the <code>oidc_providers</code>
  8044. setting in your configuration file.
  8045. See the <a href="usage/configuration/config_documentation.html#oidc_providers">configuration manual</a> for some sample settings, as well as
  8046. the text below for example configurations for specific providers.</p>
  8047. <h2 id="oidc-back-channel-logout"><a class="header" href="#oidc-back-channel-logout">OIDC Back-Channel Logout</a></h2>
  8048. <p>Synapse supports receiving <a href="https://openid.net/specs/openid-connect-backchannel-1_0.html">OpenID Connect Back-Channel Logout</a> notifications.</p>
  8049. <p>This lets the OpenID Connect Provider notify Synapse when a user logs out, so that Synapse can end that user session.
  8050. This feature can be enabled by setting the <code>backchannel_logout_enabled</code> property to <code>true</code> in the provider configuration, and setting the following URL as destination for Back-Channel Logout notifications in your OpenID Connect Provider: <code>[synapse public baseurl]/_synapse/client/oidc/backchannel_logout</code></p>
  8051. <h2 id="sample-configs"><a class="header" href="#sample-configs">Sample configs</a></h2>
  8052. <p>Here are a few configs for providers that should work with Synapse.</p>
  8053. <h3 id="microsoft-azure-active-directory"><a class="header" href="#microsoft-azure-active-directory">Microsoft Azure Active Directory</a></h3>
  8054. <p>Azure AD can act as an OpenID Connect Provider. Register a new application under
  8055. <em>App registrations</em> in the Azure AD management console. The RedirectURI for your
  8056. application should point to your matrix server:
  8057. <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></p>
  8058. <p>Go to <em>Certificates &amp; secrets</em> and register a new client secret. Make note of your
  8059. Directory (tenant) ID as it will be used in the Azure links.
  8060. Edit your Synapse config file and change the <code>oidc_config</code> section:</p>
  8061. <pre><code class="language-yaml">oidc_providers:
  8062. - idp_id: microsoft
  8063. idp_name: Microsoft
  8064. issuer: &quot;https://login.microsoftonline.com/&lt;tenant id&gt;/v2.0&quot;
  8065. client_id: &quot;&lt;client id&gt;&quot;
  8066. client_secret: &quot;&lt;client secret&gt;&quot;
  8067. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  8068. authorization_endpoint: &quot;https://login.microsoftonline.com/&lt;tenant id&gt;/oauth2/v2.0/authorize&quot;
  8069. token_endpoint: &quot;https://login.microsoftonline.com/&lt;tenant id&gt;/oauth2/v2.0/token&quot;
  8070. userinfo_endpoint: &quot;https://graph.microsoft.com/oidc/userinfo&quot;
  8071. user_mapping_provider:
  8072. config:
  8073. localpart_template: &quot;{{ user.preferred_username.split('@')[0] }}&quot;
  8074. display_name_template: &quot;{{ user.name }}&quot;
  8075. </code></pre>
  8076. <h3 id="apple"><a class="header" href="#apple">Apple</a></h3>
  8077. <p>Configuring &quot;Sign in with Apple&quot; (SiWA) requires an Apple Developer account.</p>
  8078. <p>You will need to create a new &quot;Services ID&quot; for SiWA, and create and download a
  8079. private key with &quot;SiWA&quot; enabled.</p>
  8080. <p>As well as the private key file, you will need:</p>
  8081. <ul>
  8082. <li>Client ID: the &quot;identifier&quot; you gave the &quot;Services ID&quot;</li>
  8083. <li>Team ID: a 10-character ID associated with your developer account.</li>
  8084. <li>Key ID: the 10-character identifier for the key.</li>
  8085. </ul>
  8086. <p><a href="https://help.apple.com/developer-account/?lang=en#/dev77c875b7e">Apple's developer documentation</a>
  8087. has more information on setting up SiWA.</p>
  8088. <p>The synapse config will look like this:</p>
  8089. <pre><code class="language-yaml"> - idp_id: apple
  8090. idp_name: Apple
  8091. issuer: &quot;https://appleid.apple.com&quot;
  8092. client_id: &quot;your-client-id&quot; # Set to the &quot;identifier&quot; for your &quot;ServicesID&quot;
  8093. client_auth_method: &quot;client_secret_post&quot;
  8094. client_secret_jwt_key:
  8095. key_file: &quot;/path/to/AuthKey_KEYIDCODE.p8&quot; # point to your key file
  8096. jwt_header:
  8097. alg: ES256
  8098. kid: &quot;KEYIDCODE&quot; # Set to the 10-char Key ID
  8099. jwt_payload:
  8100. iss: TEAMIDCODE # Set to the 10-char Team ID
  8101. scopes: [&quot;name&quot;, &quot;email&quot;, &quot;openid&quot;]
  8102. authorization_endpoint: https://appleid.apple.com/auth/authorize?response_mode=form_post
  8103. user_mapping_provider:
  8104. config:
  8105. email_template: &quot;{{ user.email }}&quot;
  8106. </code></pre>
  8107. <h3 id="auth0"><a class="header" href="#auth0">Auth0</a></h3>
  8108. <p><a href="https://auth0.com/">Auth0</a> is a hosted SaaS IdP solution.</p>
  8109. <ol>
  8110. <li>
  8111. <p>Create a regular web application for Synapse</p>
  8112. </li>
  8113. <li>
  8114. <p>Set the Allowed Callback URLs to <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></p>
  8115. </li>
  8116. <li>
  8117. <p>Add a rule with any name to add the <code>preferred_username</code> claim.
  8118. (See https://auth0.com/docs/customize/rules/create-rules for more information on how to create rules.)</p>
  8119. <details>
  8120. <summary>Code sample</summary>
  8121. <pre><code class="language-js">function addPersistenceAttribute(user, context, callback) {
  8122. user.user_metadata = user.user_metadata || {};
  8123. user.user_metadata.preferred_username = user.user_metadata.preferred_username || user.user_id;
  8124. context.idToken.preferred_username = user.user_metadata.preferred_username;
  8125. auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
  8126. .then(function(){
  8127. callback(null, user, context);
  8128. })
  8129. .catch(function(err){
  8130. callback(err);
  8131. });
  8132. }
  8133. </code></pre>
  8134. </li>
  8135. </ol>
  8136. </details>
  8137. <p>Synapse config:</p>
  8138. <pre><code class="language-yaml">oidc_providers:
  8139. - idp_id: auth0
  8140. idp_name: Auth0
  8141. issuer: &quot;https://your-tier.eu.auth0.com/&quot; # TO BE FILLED
  8142. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8143. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8144. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  8145. user_mapping_provider:
  8146. config:
  8147. localpart_template: &quot;{{ user.preferred_username }}&quot;
  8148. display_name_template: &quot;{{ user.name }}&quot;
  8149. </code></pre>
  8150. <h3 id="authentik"><a class="header" href="#authentik">Authentik</a></h3>
  8151. <p><a href="https://goauthentik.io/">Authentik</a> is an open-source IdP solution.</p>
  8152. <ol>
  8153. <li>Create a provider in Authentik, with type OAuth2/OpenID.</li>
  8154. <li>The parameters are:</li>
  8155. </ol>
  8156. <ul>
  8157. <li>Client Type: Confidential</li>
  8158. <li>JWT Algorithm: RS256</li>
  8159. <li>Scopes: OpenID, Email and Profile</li>
  8160. <li>RSA Key: Select any available key</li>
  8161. <li>Redirect URIs: <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></li>
  8162. </ul>
  8163. <ol start="3">
  8164. <li>Create an application for synapse in Authentik and link it to the provider.</li>
  8165. <li>Note the slug of your application, Client ID and Client Secret.</li>
  8166. </ol>
  8167. <p>Note: RSA keys must be used for signing for Authentik, ECC keys do not work.</p>
  8168. <p>Synapse config:</p>
  8169. <pre><code class="language-yaml">oidc_providers:
  8170. - idp_id: authentik
  8171. idp_name: authentik
  8172. discover: true
  8173. issuer: &quot;https://your.authentik.example.org/application/o/your-app-slug/&quot; # TO BE FILLED: domain and slug
  8174. client_id: &quot;your client id&quot; # TO BE FILLED
  8175. client_secret: &quot;your client secret&quot; # TO BE FILLED
  8176. scopes:
  8177. - &quot;openid&quot;
  8178. - &quot;profile&quot;
  8179. - &quot;email&quot;
  8180. user_mapping_provider:
  8181. config:
  8182. localpart_template: &quot;{{ user.preferred_username }}&quot;
  8183. display_name_template: &quot;{{ user.preferred_username|capitalize }}&quot; # TO BE FILLED: If your users have names in Authentik and you want those in Synapse, this should be replaced with user.name|capitalize.
  8184. </code></pre>
  8185. <h3 id="dex"><a class="header" href="#dex">Dex</a></h3>
  8186. <p><a href="https://github.com/dexidp/dex">Dex</a> is a simple, open-source OpenID Connect Provider.
  8187. Although it is designed to help building a full-blown provider with an
  8188. external database, it can be configured with static passwords in a config file.</p>
  8189. <p>Follow the <a href="https://dexidp.io/docs/getting-started/">Getting Started guide</a>
  8190. to install Dex.</p>
  8191. <p>Edit <code>examples/config-dev.yaml</code> config file from the Dex repo to add a client:</p>
  8192. <pre><code class="language-yaml">staticClients:
  8193. - id: synapse
  8194. secret: secret
  8195. redirectURIs:
  8196. - '[synapse public baseurl]/_synapse/client/oidc/callback'
  8197. name: 'Synapse'
  8198. </code></pre>
  8199. <p>Run with <code>dex serve examples/config-dev.yaml</code>.</p>
  8200. <p>Synapse config:</p>
  8201. <pre><code class="language-yaml">oidc_providers:
  8202. - idp_id: dex
  8203. idp_name: &quot;My Dex server&quot;
  8204. skip_verification: true # This is needed as Dex is served on an insecure endpoint
  8205. issuer: &quot;http://127.0.0.1:5556/dex&quot;
  8206. client_id: &quot;synapse&quot;
  8207. client_secret: &quot;secret&quot;
  8208. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  8209. user_mapping_provider:
  8210. config:
  8211. localpart_template: &quot;{{ user.name }}&quot;
  8212. display_name_template: &quot;{{ user.name|capitalize }}&quot;
  8213. </code></pre>
  8214. <h3 id="django-oauth-toolkit"><a class="header" href="#django-oauth-toolkit">Django OAuth Toolkit</a></h3>
  8215. <p><a href="https://github.com/jazzband/django-oauth-toolkit">django-oauth-toolkit</a> is a
  8216. Django application providing out of the box all the endpoints, data and logic
  8217. needed to add OAuth2 capabilities to your Django projects. It supports
  8218. <a href="https://django-oauth-toolkit.readthedocs.io/en/latest/oidc.html">OpenID Connect too</a>.</p>
  8219. <p>Configuration on Django's side:</p>
  8220. <ol>
  8221. <li>Add an application: <code>https://example.com/admin/oauth2_provider/application/add/</code> and choose parameters like this:</li>
  8222. </ol>
  8223. <ul>
  8224. <li><code>Redirect uris</code>: <code>https://synapse.example.com/_synapse/client/oidc/callback</code></li>
  8225. <li><code>Client type</code>: <code>Confidential</code></li>
  8226. <li><code>Authorization grant type</code>: <code>Authorization code</code></li>
  8227. <li><code>Algorithm</code>: <code>HMAC with SHA-2 256</code></li>
  8228. </ul>
  8229. <ol start="2">
  8230. <li>
  8231. <p>You can <a href="https://django-oauth-toolkit.readthedocs.io/en/latest/oidc.html#customizing-the-oidc-responses">customize the claims</a> Django gives to synapse (optional):</p>
  8232. <details>
  8233. <summary>Code sample</summary>
  8234. <pre><code class="language-python">class CustomOAuth2Validator(OAuth2Validator):
  8235. def get_additional_claims(self, request):
  8236. return {
  8237. &quot;sub&quot;: request.user.email,
  8238. &quot;email&quot;: request.user.email,
  8239. &quot;first_name&quot;: request.user.first_name,
  8240. &quot;last_name&quot;: request.user.last_name,
  8241. }
  8242. </code></pre>
  8243. </details>
  8244. </li>
  8245. </ol>
  8246. <p>Your synapse config is then:</p>
  8247. <pre><code class="language-yaml">oidc_providers:
  8248. - idp_id: django_example
  8249. idp_name: &quot;Django Example&quot;
  8250. issuer: &quot;https://example.com/o/&quot;
  8251. client_id: &quot;your-client-id&quot; # CHANGE ME
  8252. client_secret: &quot;your-client-secret&quot; # CHANGE ME
  8253. scopes: [&quot;openid&quot;]
  8254. user_profile_method: &quot;userinfo_endpoint&quot; # needed because oauth-toolkit does not include user information in the authorization response
  8255. user_mapping_provider:
  8256. config:
  8257. localpart_template: &quot;{{ user.email.split('@')[0] }}&quot;
  8258. display_name_template: &quot;{{ user.first_name }} {{ user.last_name }}&quot;
  8259. email_template: &quot;{{ user.email }}&quot;
  8260. </code></pre>
  8261. <h3 id="facebook"><a class="header" href="#facebook">Facebook</a></h3>
  8262. <ol start="0">
  8263. <li>You will need a Facebook developer account. You can register for one
  8264. <a href="https://developers.facebook.com/async/registration/">here</a>.</li>
  8265. <li>On the <a href="https://developers.facebook.com/apps/">apps</a> page of the developer
  8266. console, &quot;Create App&quot;, and choose &quot;Build Connected Experiences&quot;.</li>
  8267. <li>Once the app is created, add &quot;Facebook Login&quot; and choose &quot;Web&quot;. You don't
  8268. need to go through the whole form here.</li>
  8269. <li>In the left-hand menu, open &quot;Products&quot;/&quot;Facebook Login&quot;/&quot;Settings&quot;.
  8270. <ul>
  8271. <li>Add <code>[synapse public baseurl]/_synapse/client/oidc/callback</code> as an OAuth Redirect
  8272. URL.</li>
  8273. </ul>
  8274. </li>
  8275. <li>In the left-hand menu, open &quot;Settings/Basic&quot;. Here you can copy the &quot;App ID&quot;
  8276. and &quot;App Secret&quot; for use below.</li>
  8277. </ol>
  8278. <p>Synapse config:</p>
  8279. <pre><code class="language-yaml"> - idp_id: facebook
  8280. idp_name: Facebook
  8281. idp_brand: &quot;facebook&quot; # optional: styling hint for clients
  8282. discover: false
  8283. issuer: &quot;https://www.facebook.com&quot;
  8284. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8285. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8286. scopes: [&quot;openid&quot;, &quot;email&quot;]
  8287. authorization_endpoint: &quot;https://facebook.com/dialog/oauth&quot;
  8288. token_endpoint: &quot;https://graph.facebook.com/v9.0/oauth/access_token&quot;
  8289. jwks_uri: &quot;https://www.facebook.com/.well-known/oauth/openid/jwks/&quot;
  8290. user_mapping_provider:
  8291. config:
  8292. display_name_template: &quot;{{ user.name }}&quot;
  8293. email_template: &quot;{{ user.email }}&quot;
  8294. </code></pre>
  8295. <p>Relevant documents:</p>
  8296. <ul>
  8297. <li><a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow">Manually Build a Login Flow</a></li>
  8298. <li><a href="https://developers.facebook.com/docs/graph-api/using-graph-api/">Using Facebook's Graph API</a></li>
  8299. <li><a href="https://developers.facebook.com/docs/graph-api/reference/user">Reference to the User endpoint</a></li>
  8300. </ul>
  8301. <p>Facebook do have an <a href="https://www.facebook.com/.well-known/openid-configuration">OIDC discovery endpoint</a>,
  8302. but it has a <code>response_types_supported</code> which excludes &quot;code&quot; (which we rely on, and
  8303. is even mentioned in their <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login">documentation</a>),
  8304. so we have to disable discovery and configure the URIs manually.</p>
  8305. <h3 id="github"><a class="header" href="#github">GitHub</a></h3>
  8306. <p><a href="https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps">GitHub</a> is a bit special as it is not an OpenID Connect compliant provider, but
  8307. just a regular OAuth2 provider.</p>
  8308. <p>The <a href="https://developer.github.com/v3/users/#get-the-authenticated-user"><code>/user</code> API endpoint</a>
  8309. can be used to retrieve information on the authenticated user. As the Synapse
  8310. login mechanism needs an attribute to uniquely identify users, and that endpoint
  8311. does not return a <code>sub</code> property, an alternative <code>subject_claim</code> has to be set.</p>
  8312. <ol>
  8313. <li>Create a new OAuth application: <a href="https://github.com/settings/applications/new">https://github.com/settings/applications/new</a>.</li>
  8314. <li>Set the callback URL to <code>[synapse public baseurl]/_synapse/client/oidc/callback</code>.</li>
  8315. </ol>
  8316. <p>Synapse config:</p>
  8317. <pre><code class="language-yaml">oidc_providers:
  8318. - idp_id: github
  8319. idp_name: Github
  8320. idp_brand: &quot;github&quot; # optional: styling hint for clients
  8321. discover: false
  8322. issuer: &quot;https://github.com/&quot;
  8323. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8324. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8325. authorization_endpoint: &quot;https://github.com/login/oauth/authorize&quot;
  8326. token_endpoint: &quot;https://github.com/login/oauth/access_token&quot;
  8327. userinfo_endpoint: &quot;https://api.github.com/user&quot;
  8328. scopes: [&quot;read:user&quot;]
  8329. user_mapping_provider:
  8330. config:
  8331. subject_claim: &quot;id&quot;
  8332. localpart_template: &quot;{{ user.login }}&quot;
  8333. display_name_template: &quot;{{ user.name }}&quot;
  8334. </code></pre>
  8335. <h3 id="gitlab"><a class="header" href="#gitlab">GitLab</a></h3>
  8336. <ol>
  8337. <li>Create a <a href="https://gitlab.com/profile/applications">new application</a>.</li>
  8338. <li>Add the <code>read_user</code> and <code>openid</code> scopes.</li>
  8339. <li>Add this Callback URL: <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></li>
  8340. </ol>
  8341. <p>Synapse config:</p>
  8342. <pre><code class="language-yaml">oidc_providers:
  8343. - idp_id: gitlab
  8344. idp_name: Gitlab
  8345. idp_brand: &quot;gitlab&quot; # optional: styling hint for clients
  8346. issuer: &quot;https://gitlab.com/&quot;
  8347. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8348. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8349. client_auth_method: &quot;client_secret_post&quot;
  8350. scopes: [&quot;openid&quot;, &quot;read_user&quot;]
  8351. user_profile_method: &quot;userinfo_endpoint&quot;
  8352. user_mapping_provider:
  8353. config:
  8354. localpart_template: '{{ user.nickname }}'
  8355. display_name_template: '{{ user.name }}'
  8356. </code></pre>
  8357. <h3 id="gitea"><a class="header" href="#gitea">Gitea</a></h3>
  8358. <p>Gitea is, like Github, not an OpenID provider, but just an OAuth2 provider.</p>
  8359. <p>The <a href="https://try.gitea.io/api/swagger#/user/userGetCurrent"><code>/user</code> API endpoint</a>
  8360. can be used to retrieve information on the authenticated user. As the Synapse
  8361. login mechanism needs an attribute to uniquely identify users, and that endpoint
  8362. does not return a <code>sub</code> property, an alternative <code>subject_claim</code> has to be set.</p>
  8363. <ol>
  8364. <li>Create a new application.</li>
  8365. <li>Add this Callback URL: <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></li>
  8366. </ol>
  8367. <p>Synapse config:</p>
  8368. <pre><code class="language-yaml">oidc_providers:
  8369. - idp_id: gitea
  8370. idp_name: Gitea
  8371. discover: false
  8372. issuer: &quot;https://your-gitea.com/&quot;
  8373. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8374. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8375. client_auth_method: client_secret_post
  8376. scopes: [] # Gitea doesn't support Scopes
  8377. authorization_endpoint: &quot;https://your-gitea.com/login/oauth/authorize&quot;
  8378. token_endpoint: &quot;https://your-gitea.com/login/oauth/access_token&quot;
  8379. userinfo_endpoint: &quot;https://your-gitea.com/api/v1/user&quot;
  8380. user_mapping_provider:
  8381. config:
  8382. subject_claim: &quot;id&quot;
  8383. localpart_template: &quot;{{ user.login }}&quot;
  8384. display_name_template: &quot;{{ user.full_name }}&quot;
  8385. </code></pre>
  8386. <h3 id="google"><a class="header" href="#google">Google</a></h3>
  8387. <p><a href="https://developers.google.com/identity/protocols/oauth2/openid-connect">Google</a> is an OpenID certified authentication and authorisation provider.</p>
  8388. <ol>
  8389. <li>Set up a project in the Google API Console (see
  8390. <a href="https://developers.google.com/identity/protocols/oauth2/openid-connect#appsetup">documentation</a>).</li>
  8391. <li>Add an &quot;OAuth Client ID&quot; for a Web Application under &quot;Credentials&quot;.</li>
  8392. <li>Copy the Client ID and Client Secret, and add the following to your synapse config:
  8393. <pre><code class="language-yaml">oidc_providers:
  8394. - idp_id: google
  8395. idp_name: Google
  8396. idp_brand: &quot;google&quot; # optional: styling hint for clients
  8397. issuer: &quot;https://accounts.google.com/&quot;
  8398. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8399. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8400. scopes: [&quot;openid&quot;, &quot;profile&quot;, &quot;email&quot;] # email is optional, read below
  8401. user_mapping_provider:
  8402. config:
  8403. localpart_template: &quot;{{ user.given_name|lower }}&quot;
  8404. display_name_template: &quot;{{ user.name }}&quot;
  8405. email_template: &quot;{{ user.email }}&quot; # needs &quot;email&quot; in scopes above
  8406. </code></pre>
  8407. </li>
  8408. <li>Back in the Google console, add this Authorized redirect URI: <code>[synapse public baseurl]/_synapse/client/oidc/callback</code>.</li>
  8409. </ol>
  8410. <h3 id="keycloak"><a class="header" href="#keycloak">Keycloak</a></h3>
  8411. <p><a href="https://www.keycloak.org/docs/latest/server_admin/#sso-protocols">Keycloak</a> is an opensource IdP maintained by Red Hat.</p>
  8412. <p>Keycloak supports OIDC Back-Channel Logout, which sends logout notification to Synapse, so that Synapse users get logged out when they log out from Keycloak.
  8413. This can be optionally enabled by setting <code>backchannel_logout_enabled</code> to <code>true</code> in the Synapse configuration, and by setting the &quot;Backchannel Logout URL&quot; in Keycloak.</p>
  8414. <p>Follow the <a href="https://www.keycloak.org/guides">Getting Started Guide</a> to install Keycloak and set up a realm.</p>
  8415. <ol>
  8416. <li>
  8417. <p>Click <code>Clients</code> in the sidebar and click <code>Create</code></p>
  8418. </li>
  8419. <li>
  8420. <p>Fill in the fields as below:</p>
  8421. </li>
  8422. </ol>
  8423. <table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody>
  8424. <tr><td>Client ID</td><td><code>synapse</code></td></tr>
  8425. <tr><td>Client Protocol</td><td><code>openid-connect</code></td></tr>
  8426. </tbody></table>
  8427. <ol start="3">
  8428. <li>Click <code>Save</code></li>
  8429. <li>Fill in the fields as below:</li>
  8430. </ol>
  8431. <table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody>
  8432. <tr><td>Client ID</td><td><code>synapse</code></td></tr>
  8433. <tr><td>Enabled</td><td><code>On</code></td></tr>
  8434. <tr><td>Client Protocol</td><td><code>openid-connect</code></td></tr>
  8435. <tr><td>Access Type</td><td><code>confidential</code></td></tr>
  8436. <tr><td>Valid Redirect URIs</td><td><code>[synapse public baseurl]/_synapse/client/oidc/callback</code></td></tr>
  8437. <tr><td>Backchannel Logout URL (optional)</td><td> <code>[synapse public baseurl]/_synapse/client/oidc/backchannel_logout</code></td></tr>
  8438. <tr><td>Backchannel Logout Session Required (optional)</td><td> <code>On</code></td></tr>
  8439. </tbody></table>
  8440. <ol start="5">
  8441. <li>Click <code>Save</code></li>
  8442. <li>On the Credentials tab, update the fields:</li>
  8443. </ol>
  8444. <table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody>
  8445. <tr><td>Client Authenticator</td><td><code>Client ID and Secret</code></td></tr>
  8446. </tbody></table>
  8447. <ol start="7">
  8448. <li>Click <code>Regenerate Secret</code></li>
  8449. <li>Copy Secret</li>
  8450. </ol>
  8451. <pre><code class="language-yaml">oidc_providers:
  8452. - idp_id: keycloak
  8453. idp_name: &quot;My KeyCloak server&quot;
  8454. issuer: &quot;https://127.0.0.1:8443/realms/{realm_name}&quot;
  8455. client_id: &quot;synapse&quot;
  8456. client_secret: &quot;copy secret generated from above&quot;
  8457. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  8458. user_mapping_provider:
  8459. config:
  8460. localpart_template: &quot;{{ user.preferred_username }}&quot;
  8461. display_name_template: &quot;{{ user.name }}&quot;
  8462. backchannel_logout_enabled: true # Optional
  8463. </code></pre>
  8464. <h3 id="lemonldap"><a class="header" href="#lemonldap">LemonLDAP</a></h3>
  8465. <p><a href="https://lemonldap-ng.org/">LemonLDAP::NG</a> is an open-source IdP solution.</p>
  8466. <ol>
  8467. <li>Create an OpenID Connect Relying Parties in LemonLDAP::NG</li>
  8468. <li>The parameters are:</li>
  8469. </ol>
  8470. <ul>
  8471. <li>Client ID under the basic menu of the new Relying Parties (<code>Options &gt; Basic &gt; Client ID</code>)</li>
  8472. <li>Client secret (<code>Options &gt; Basic &gt; Client secret</code>)</li>
  8473. <li>JWT Algorithm: RS256 within the security menu of the new Relying Parties
  8474. (<code>Options &gt; Security &gt; ID Token signature algorithm</code> and <code>Options &gt; Security &gt; Access Token signature algorithm</code>)</li>
  8475. <li>Scopes: OpenID, Email and Profile</li>
  8476. <li>Allowed redirection addresses for login (<code>Options &gt; Basic &gt; Allowed redirection addresses for login</code> ) :
  8477. <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></li>
  8478. </ul>
  8479. <p>Synapse config:</p>
  8480. <pre><code class="language-yaml">oidc_providers:
  8481. - idp_id: lemonldap
  8482. idp_name: lemonldap
  8483. discover: true
  8484. issuer: &quot;https://auth.example.org/&quot; # TO BE FILLED: replace with your domain
  8485. client_id: &quot;your client id&quot; # TO BE FILLED
  8486. client_secret: &quot;your client secret&quot; # TO BE FILLED
  8487. scopes:
  8488. - &quot;openid&quot;
  8489. - &quot;profile&quot;
  8490. - &quot;email&quot;
  8491. user_mapping_provider:
  8492. config:
  8493. localpart_template: &quot;{{ user.preferred_username }}}&quot;
  8494. # TO BE FILLED: If your users have names in LemonLDAP::NG and you want those in Synapse, this should be replaced with user.name|capitalize or any valid filter.
  8495. display_name_template: &quot;{{ user.preferred_username|capitalize }}&quot;
  8496. </code></pre>
  8497. <h3 id="mastodon"><a class="header" href="#mastodon">Mastodon</a></h3>
  8498. <p><a href="https://docs.joinmastodon.org/">Mastodon</a> instances provide an <a href="https://docs.joinmastodon.org/spec/oauth/">OAuth API</a>, allowing those instances to be used as a single sign-on provider for Synapse.</p>
  8499. <p>The first step is to register Synapse as an application with your Mastodon instance, using the <a href="https://docs.joinmastodon.org/methods/apps/#create">Create an application API</a> (see also <a href="https://docs.joinmastodon.org/client/token/">here</a>). There are several ways to do this, but in the example below we are using CURL.</p>
  8500. <p>This example assumes that:</p>
  8501. <ul>
  8502. <li>the Mastodon instance website URL is <code>https://your.mastodon.instance.url</code>, and</li>
  8503. <li>Synapse will be registered as an app named <code>my_synapse_app</code>.</li>
  8504. </ul>
  8505. <p>Send the following request, substituting the value of <code>synapse_public_baseurl</code> from your Synapse installation.</p>
  8506. <pre><code class="language-sh">curl -d &quot;client_name=my_synapse_app&amp;redirect_uris=https://[synapse_public_baseurl]/_synapse/client/oidc/callback&quot; -X POST https://your.mastodon.instance.url/api/v1/apps
  8507. </code></pre>
  8508. <p>You should receive a response similar to the following. Make sure to save it.</p>
  8509. <pre><code class="language-json">{&quot;client_id&quot;:&quot;someclientid_123&quot;,&quot;client_secret&quot;:&quot;someclientsecret_123&quot;,&quot;id&quot;:&quot;12345&quot;,&quot;name&quot;:&quot;my_synapse_app&quot;,&quot;redirect_uri&quot;:&quot;https://[synapse_public_baseurl]/_synapse/client/oidc/callback&quot;,&quot;website&quot;:null,&quot;vapid_key&quot;:&quot;somerandomvapidkey_123&quot;}
  8510. </code></pre>
  8511. <p>As the Synapse login mechanism needs an attribute to uniquely identify users, and Mastodon's endpoint does not return a <code>sub</code> property, an alternative <code>subject_template</code> has to be set. Your Synapse configuration should include the following:</p>
  8512. <pre><code class="language-yaml">oidc_providers:
  8513. - idp_id: my_mastodon
  8514. idp_name: &quot;Mastodon Instance Example&quot;
  8515. discover: false
  8516. issuer: &quot;https://your.mastodon.instance.url/@admin&quot;
  8517. client_id: &quot;someclientid_123&quot;
  8518. client_secret: &quot;someclientsecret_123&quot;
  8519. authorization_endpoint: &quot;https://your.mastodon.instance.url/oauth/authorize&quot;
  8520. token_endpoint: &quot;https://your.mastodon.instance.url/oauth/token&quot;
  8521. userinfo_endpoint: &quot;https://your.mastodon.instance.url/api/v1/accounts/verify_credentials&quot;
  8522. scopes: [&quot;read&quot;]
  8523. user_mapping_provider:
  8524. config:
  8525. subject_template: &quot;{{ user.id }}&quot;
  8526. localpart_template: &quot;{{ user.username }}&quot;
  8527. display_name_template: &quot;{{ user.display_name }}&quot;
  8528. </code></pre>
  8529. <p>Note that the fields <code>client_id</code> and <code>client_secret</code> are taken from the CURL response above.</p>
  8530. <h3 id="shibboleth-with-oidc-plugin"><a class="header" href="#shibboleth-with-oidc-plugin">Shibboleth with OIDC Plugin</a></h3>
  8531. <p><a href="https://www.shibboleth.net/">Shibboleth</a> is an open Standard IdP solution widely used by Universities.</p>
  8532. <ol>
  8533. <li>Shibboleth needs the <a href="https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/1376878976/OIDC+OP">OIDC Plugin</a> installed and working correctly.</li>
  8534. <li>Create a new config on the IdP Side, ensure that the <code>client_id</code> and <code>client_secret</code>
  8535. are randomly generated data.</li>
  8536. </ol>
  8537. <pre><code class="language-json">{
  8538. &quot;client_id&quot;: &quot;SOME-CLIENT-ID&quot;,
  8539. &quot;client_secret&quot;: &quot;SOME-SUPER-SECRET-SECRET&quot;,
  8540. &quot;response_types&quot;: [&quot;code&quot;],
  8541. &quot;grant_types&quot;: [&quot;authorization_code&quot;],
  8542. &quot;scope&quot;: &quot;openid profile email&quot;,
  8543. &quot;redirect_uris&quot;: [&quot;https://[synapse public baseurl]/_synapse/client/oidc/callback&quot;]
  8544. }
  8545. </code></pre>
  8546. <p>Synapse config:</p>
  8547. <pre><code class="language-yaml">oidc_providers:
  8548. # Shibboleth IDP
  8549. #
  8550. - idp_id: shibboleth
  8551. idp_name: &quot;Shibboleth Login&quot;
  8552. discover: true
  8553. issuer: &quot;https://YOUR-IDP-URL.TLD&quot;
  8554. client_id: &quot;YOUR_CLIENT_ID&quot;
  8555. client_secret: &quot;YOUR-CLIENT-SECRECT-FROM-YOUR-IDP&quot;
  8556. scopes: [&quot;openid&quot;, &quot;profile&quot;, &quot;email&quot;]
  8557. allow_existing_users: true
  8558. user_profile_method: &quot;userinfo_endpoint&quot;
  8559. user_mapping_provider:
  8560. config:
  8561. subject_claim: &quot;sub&quot;
  8562. localpart_template: &quot;{{ user.sub.split('@')[0] }}&quot;
  8563. display_name_template: &quot;{{ user.name }}&quot;
  8564. email_template: &quot;{{ user.email }}&quot;
  8565. </code></pre>
  8566. <h3 id="twitch"><a class="header" href="#twitch">Twitch</a></h3>
  8567. <ol>
  8568. <li>Setup a developer account on <a href="https://dev.twitch.tv/">Twitch</a></li>
  8569. <li>Obtain the OAuth 2.0 credentials by <a href="https://dev.twitch.tv/console/apps/">creating an app</a></li>
  8570. <li>Add this OAuth Redirect URL: <code>[synapse public baseurl]/_synapse/client/oidc/callback</code></li>
  8571. </ol>
  8572. <p>Synapse config:</p>
  8573. <pre><code class="language-yaml">oidc_providers:
  8574. - idp_id: twitch
  8575. idp_name: Twitch
  8576. issuer: &quot;https://id.twitch.tv/oauth2/&quot;
  8577. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8578. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8579. client_auth_method: &quot;client_secret_post&quot;
  8580. user_mapping_provider:
  8581. config:
  8582. localpart_template: &quot;{{ user.preferred_username }}&quot;
  8583. display_name_template: &quot;{{ user.name }}&quot;
  8584. </code></pre>
  8585. <h3 id="twitter"><a class="header" href="#twitter">Twitter</a></h3>
  8586. <p><em>Using Twitter as an identity provider requires using Synapse 1.75.0 or later.</em></p>
  8587. <ol>
  8588. <li>Setup a developer account on <a href="https://developer.twitter.com/en/portal/dashboard">Twitter</a></li>
  8589. <li>Create a project &amp; app.</li>
  8590. <li>Enable user authentication and under &quot;Type of App&quot; choose &quot;Web App, Automated App or Bot&quot;.</li>
  8591. <li>Under &quot;App info&quot; set the callback URL to <code>[synapse public baseurl]/_synapse/client/oidc/callback</code>.</li>
  8592. <li>Obtain the OAuth 2.0 credentials under the &quot;Keys and tokens&quot; tab, copy the &quot;OAuth 2.0 Client ID and Client Secret&quot;</li>
  8593. </ol>
  8594. <p>Synapse config:</p>
  8595. <pre><code class="language-yaml">oidc_providers:
  8596. - idp_id: twitter
  8597. idp_name: Twitter
  8598. idp_brand: &quot;twitter&quot; # optional: styling hint for clients
  8599. discover: false # Twitter is not OpenID compliant.
  8600. issuer: &quot;https://twitter.com/&quot;
  8601. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8602. client_secret: &quot;your-client-secret&quot; # TO BE FILLED
  8603. pkce_method: &quot;always&quot;
  8604. # offline.access providers refresh tokens, tweet.read and users.read needed for userinfo request.
  8605. scopes: [&quot;offline.access&quot;, &quot;tweet.read&quot;, &quot;users.read&quot;]
  8606. authorization_endpoint: https://twitter.com/i/oauth2/authorize
  8607. token_endpoint: https://api.twitter.com/2/oauth2/token
  8608. userinfo_endpoint: https://api.twitter.com/2/users/me?user.fields=profile_image_url
  8609. user_mapping_provider:
  8610. config:
  8611. subject_template: &quot;{{ user.data.id }}&quot;
  8612. localpart_template: &quot;{{ user.data.username }}&quot;
  8613. display_name_template: &quot;{{ user.data.name }}&quot;
  8614. picture_template: &quot;{{ user.data.profile_image_url }}&quot;
  8615. </code></pre>
  8616. <h3 id="xwiki"><a class="header" href="#xwiki">XWiki</a></h3>
  8617. <p>Install <a href="https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Provider/">OpenID Connect Provider</a> extension in your <a href="https://www.xwiki.org">XWiki</a> instance.</p>
  8618. <p>Synapse config:</p>
  8619. <pre><code class="language-yaml">oidc_providers:
  8620. - idp_id: xwiki
  8621. idp_name: &quot;XWiki&quot;
  8622. issuer: &quot;https://myxwikihost/xwiki/oidc/&quot;
  8623. client_id: &quot;your-client-id&quot; # TO BE FILLED
  8624. client_auth_method: none
  8625. scopes: [&quot;openid&quot;, &quot;profile&quot;]
  8626. user_profile_method: &quot;userinfo_endpoint&quot;
  8627. user_mapping_provider:
  8628. config:
  8629. localpart_template: &quot;{{ user.preferred_username }}&quot;
  8630. display_name_template: &quot;{{ user.name }}&quot;
  8631. </code></pre>
  8632. <div style="break-before: page; page-break-before: always;"></div><h1 id="saml"><a class="header" href="#saml">SAML</a></h1>
  8633. <p>Synapse supports authenticating users via the <a href="https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language">Security Assertion
  8634. Markup Language</a>
  8635. (SAML) protocol natively.</p>
  8636. <p>Please see the <code>saml2_config</code> and <code>sso</code> sections of the <a href="usage/configuration/user_authentication/single_sign_on/../../../configuration/homeserver_sample_config.html">Synapse configuration
  8637. file</a> for more details.</p>
  8638. <div style="break-before: page; page-break-before: always;"></div><h1 id="cas"><a class="header" href="#cas">CAS</a></h1>
  8639. <p>Synapse supports authenticating users via the <a href="https://en.wikipedia.org/wiki/Central_Authentication_Service">Central Authentication
  8640. Service protocol</a>
  8641. (CAS) natively.</p>
  8642. <p>Please see the <a href="usage/configuration/user_authentication/single_sign_on/../../../configuration/config_documentation.html#cas_config">cas_config</a> and <a href="usage/configuration/user_authentication/single_sign_on/../../../configuration/config_documentation.html#sso">sso</a>
  8643. sections of the configuration manual for more details.</p>
  8644. <div style="break-before: page; page-break-before: always;"></div><h1 id="sso-mapping-providers"><a class="header" href="#sso-mapping-providers">SSO Mapping Providers</a></h1>
  8645. <p>A mapping provider is a Python class (loaded via a Python module) that
  8646. works out how to map attributes of a SSO response to Matrix-specific
  8647. user attributes. Details such as user ID localpart, displayname, and even avatar
  8648. URLs are all things that can be mapped from talking to a SSO service.</p>
  8649. <p>As an example, a SSO service may return the email address
  8650. &quot;john.smith@example.com&quot; for a user, whereas Synapse will need to figure out how
  8651. to turn that into a displayname when creating a Matrix user for this individual.
  8652. It may choose <code>John Smith</code>, or <code>Smith, John [Example.com]</code> or any number of
  8653. variations. As each Synapse configuration may want something different, this is
  8654. where SAML mapping providers come into play.</p>
  8655. <p>SSO mapping providers are currently supported for OpenID and SAML SSO
  8656. configurations. Please see the details below for how to implement your own.</p>
  8657. <p>It is up to the mapping provider whether the user should be assigned a predefined
  8658. Matrix ID based on the SSO attributes, or if the user should be allowed to
  8659. choose their own username.</p>
  8660. <p>In the first case - where users are automatically allocated a Matrix ID - it is
  8661. the responsibility of the mapping provider to normalise the SSO attributes and
  8662. map them to a valid Matrix ID. The <a href="https://spec.matrix.org/latest/appendices/#user-identifiers">specification for Matrix
  8663. IDs</a> has some
  8664. information about what is considered valid.</p>
  8665. <p>If the mapping provider does not assign a Matrix ID, then Synapse will
  8666. automatically serve an HTML page allowing the user to pick their own username.</p>
  8667. <p>External mapping providers are provided to Synapse in the form of an external
  8668. Python module. You can retrieve this module from <a href="https://pypi.org">PyPI</a> or elsewhere,
  8669. but it must be importable via Synapse (e.g. it must be in the same virtualenv
  8670. as Synapse). The Synapse config is then modified to point to the mapping provider
  8671. (and optionally provide additional configuration for it).</p>
  8672. <h2 id="openid-mapping-providers"><a class="header" href="#openid-mapping-providers">OpenID Mapping Providers</a></h2>
  8673. <p>The OpenID mapping provider can be customized by editing the
  8674. <a href="usage/configuration/config_documentation.html#oidc_providers"><code>oidc_providers.user_mapping_provider.module</code></a>
  8675. config option.</p>
  8676. <p><code>oidc_providers.user_mapping_provider.config</code> allows you to provide custom
  8677. configuration options to the module. Check with the module's documentation for
  8678. what options it provides (if any). The options listed by default are for the
  8679. user mapping provider built in to Synapse. If using a custom module, you should
  8680. comment these options out and use those specified by the module instead.</p>
  8681. <h3 id="building-a-custom-openid-mapping-provider"><a class="header" href="#building-a-custom-openid-mapping-provider">Building a Custom OpenID Mapping Provider</a></h3>
  8682. <p>A custom mapping provider must specify the following methods:</p>
  8683. <ul>
  8684. <li><code>def __init__(self, parsed_config)</code>
  8685. <ul>
  8686. <li>Arguments:
  8687. <ul>
  8688. <li><code>parsed_config</code> - A configuration object that is the return value of the
  8689. <code>parse_config</code> method. You should set any configuration options needed by
  8690. the module here.</li>
  8691. </ul>
  8692. </li>
  8693. </ul>
  8694. </li>
  8695. <li><code>def parse_config(config)</code>
  8696. <ul>
  8697. <li>This method should have the <code>@staticmethod</code> decoration.</li>
  8698. <li>Arguments:
  8699. <ul>
  8700. <li><code>config</code> - A <code>dict</code> representing the parsed content of the
  8701. <code>oidc_providers.user_mapping_provider.config</code> homeserver config option.
  8702. Runs on homeserver startup. Providers should extract and validate
  8703. any option values they need here.</li>
  8704. </ul>
  8705. </li>
  8706. <li>Whatever is returned will be passed back to the user mapping provider module's
  8707. <code>__init__</code> method during construction.</li>
  8708. </ul>
  8709. </li>
  8710. <li><code>def get_remote_user_id(self, userinfo)</code>
  8711. <ul>
  8712. <li>Arguments:
  8713. <ul>
  8714. <li><code>userinfo</code> - A <code>authlib.oidc.core.claims.UserInfo</code> object to extract user
  8715. information from.</li>
  8716. </ul>
  8717. </li>
  8718. <li>This method must return a string, which is the unique, immutable identifier
  8719. for the user. Commonly the <code>sub</code> claim of the response.</li>
  8720. </ul>
  8721. </li>
  8722. <li><code>async def map_user_attributes(self, userinfo, token, failures)</code>
  8723. <ul>
  8724. <li>This method must be async.</li>
  8725. <li>Arguments:
  8726. <ul>
  8727. <li><code>userinfo</code> - An <a href="https://docs.authlib.org/en/latest/specs/oidc.html#authlib.oidc.core.UserInfo"><code>authlib.oidc.core.claims.UserInfo</code></a>
  8728. object to extract user information from.</li>
  8729. <li><code>token</code> - A dictionary which includes information necessary to make
  8730. further requests to the OpenID provider.</li>
  8731. <li><code>failures</code> - An <code>int</code> that represents the amount of times the returned
  8732. mxid localpart mapping has failed. This should be used
  8733. to create a deduplicated mxid localpart which should be
  8734. returned instead. For example, if this method returns
  8735. <code>john.doe</code> as the value of <code>localpart</code> in the returned
  8736. dict, and that is already taken on the homeserver, this
  8737. method will be called again with the same parameters but
  8738. with failures=1. The method should then return a different
  8739. <code>localpart</code> value, such as <code>john.doe1</code>.</li>
  8740. </ul>
  8741. </li>
  8742. <li>Returns a dictionary with two keys:
  8743. <ul>
  8744. <li><code>localpart</code>: A string, used to generate the Matrix ID. If this is
  8745. <code>None</code>, the user is prompted to pick their own username. This is only used
  8746. during a user's first login. Once a localpart has been associated with a
  8747. remote user ID (see <code>get_remote_user_id</code>) it cannot be updated.</li>
  8748. <li><code>confirm_localpart</code>: A boolean. If set to <code>True</code>, when a <code>localpart</code>
  8749. string is returned from this method, Synapse will prompt the user to
  8750. either accept this localpart or pick their own username. Otherwise this
  8751. option has no effect. If omitted, defaults to <code>False</code>.</li>
  8752. <li><code>display_name</code>: An optional string, the display name for the user.</li>
  8753. <li><code>emails</code>: A list of strings, the email address(es) to associate with
  8754. this user. If omitted, defaults to an empty list.</li>
  8755. </ul>
  8756. </li>
  8757. </ul>
  8758. </li>
  8759. <li><code>async def get_extra_attributes(self, userinfo, token)</code>
  8760. <ul>
  8761. <li>
  8762. <p>This method must be async.</p>
  8763. </li>
  8764. <li>
  8765. <p>Arguments:</p>
  8766. <ul>
  8767. <li><code>userinfo</code> - A <code>authlib.oidc.core.claims.UserInfo</code> object to extract user
  8768. information from.</li>
  8769. <li><code>token</code> - A dictionary which includes information necessary to make
  8770. further requests to the OpenID provider.</li>
  8771. </ul>
  8772. </li>
  8773. <li>
  8774. <p>Returns a dictionary that is suitable to be serialized to JSON. This
  8775. will be returned as part of the response during a successful login.</p>
  8776. <p>Note that care should be taken to not overwrite any of the parameters
  8777. usually returned as part of the <a href="https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3login">login response</a>.</p>
  8778. </li>
  8779. </ul>
  8780. </li>
  8781. </ul>
  8782. <h3 id="default-openid-mapping-provider"><a class="header" href="#default-openid-mapping-provider">Default OpenID Mapping Provider</a></h3>
  8783. <p>Synapse has a built-in OpenID mapping provider if a custom provider isn't
  8784. specified in the config. It is located at
  8785. <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/handlers/oidc.py"><code>synapse.handlers.oidc.JinjaOidcMappingProvider</code></a>.</p>
  8786. <h2 id="saml-mapping-providers"><a class="header" href="#saml-mapping-providers">SAML Mapping Providers</a></h2>
  8787. <p>The SAML mapping provider can be customized by editing the
  8788. <a href="usage/configuration/config_documentation.html#saml2_config"><code>saml2_config.user_mapping_provider.module</code></a>
  8789. config option.</p>
  8790. <p><code>saml2_config.user_mapping_provider.config</code> allows you to provide custom
  8791. configuration options to the module. Check with the module's documentation for
  8792. what options it provides (if any). The options listed by default are for the
  8793. user mapping provider built in to Synapse. If using a custom module, you should
  8794. comment these options out and use those specified by the module instead.</p>
  8795. <h3 id="building-a-custom-saml-mapping-provider"><a class="header" href="#building-a-custom-saml-mapping-provider">Building a Custom SAML Mapping Provider</a></h3>
  8796. <p>A custom mapping provider must specify the following methods:</p>
  8797. <ul>
  8798. <li><code>def __init__(self, parsed_config, module_api)</code>
  8799. <ul>
  8800. <li>Arguments:
  8801. <ul>
  8802. <li><code>parsed_config</code> - A configuration object that is the return value of the
  8803. <code>parse_config</code> method. You should set any configuration options needed by
  8804. the module here.</li>
  8805. <li><code>module_api</code> - a <code>synapse.module_api.ModuleApi</code> object which provides the
  8806. stable API available for extension modules.</li>
  8807. </ul>
  8808. </li>
  8809. </ul>
  8810. </li>
  8811. <li><code>def parse_config(config)</code>
  8812. <ul>
  8813. <li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
  8814. <li>Arguments:
  8815. <ul>
  8816. <li><code>config</code> - A <code>dict</code> representing the parsed content of the
  8817. <code>saml_config.user_mapping_provider.config</code> homeserver config option.
  8818. Runs on homeserver startup. Providers should extract and validate
  8819. any option values they need here.</li>
  8820. </ul>
  8821. </li>
  8822. <li>Whatever is returned will be passed back to the user mapping provider module's
  8823. <code>__init__</code> method during construction.</li>
  8824. </ul>
  8825. </li>
  8826. <li><code>def get_saml_attributes(config)</code>
  8827. <ul>
  8828. <li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
  8829. <li>Arguments:
  8830. <ul>
  8831. <li><code>config</code> - A object resulting from a call to <code>parse_config</code>.</li>
  8832. </ul>
  8833. </li>
  8834. <li>Returns a tuple of two sets. The first set equates to the SAML auth
  8835. response attributes that are required for the module to function, whereas
  8836. the second set consists of those attributes which can be used if available,
  8837. but are not necessary.</li>
  8838. </ul>
  8839. </li>
  8840. <li><code>def get_remote_user_id(self, saml_response, client_redirect_url)</code>
  8841. <ul>
  8842. <li>Arguments:
  8843. <ul>
  8844. <li><code>saml_response</code> - A <code>saml2.response.AuthnResponse</code> object to extract user
  8845. information from.</li>
  8846. <li><code>client_redirect_url</code> - A string, the URL that the client will be
  8847. redirected to.</li>
  8848. </ul>
  8849. </li>
  8850. <li>This method must return a string, which is the unique, immutable identifier
  8851. for the user. Commonly the <code>uid</code> claim of the response.</li>
  8852. </ul>
  8853. </li>
  8854. <li><code>def saml_response_to_user_attributes(self, saml_response, failures, client_redirect_url)</code>
  8855. <ul>
  8856. <li>
  8857. <p>Arguments:</p>
  8858. <ul>
  8859. <li><code>saml_response</code> - A <code>saml2.response.AuthnResponse</code> object to extract user
  8860. information from.</li>
  8861. <li><code>failures</code> - An <code>int</code> that represents the amount of times the returned
  8862. mxid localpart mapping has failed. This should be used
  8863. to create a deduplicated mxid localpart which should be
  8864. returned instead. For example, if this method returns
  8865. <code>john.doe</code> as the value of <code>mxid_localpart</code> in the returned
  8866. dict, and that is already taken on the homeserver, this
  8867. method will be called again with the same parameters but
  8868. with failures=1. The method should then return a different
  8869. <code>mxid_localpart</code> value, such as <code>john.doe1</code>.</li>
  8870. <li><code>client_redirect_url</code> - A string, the URL that the client will be
  8871. redirected to.</li>
  8872. </ul>
  8873. </li>
  8874. <li>
  8875. <p>This method must return a dictionary, which will then be used by Synapse
  8876. to build a new user. The following keys are allowed:</p>
  8877. <ul>
  8878. <li><code>mxid_localpart</code> - A string, the mxid localpart of the new user. If this is
  8879. <code>None</code>, the user is prompted to pick their own username. This is only used
  8880. during a user's first login. Once a localpart has been associated with a
  8881. remote user ID (see <code>get_remote_user_id</code>) it cannot be updated.</li>
  8882. <li><code>displayname</code> - The displayname of the new user. If not provided, will default to
  8883. the value of <code>mxid_localpart</code>.</li>
  8884. <li><code>emails</code> - A list of emails for the new user. If not provided, will
  8885. default to an empty list.</li>
  8886. </ul>
  8887. <p>Alternatively it can raise a <code>synapse.api.errors.RedirectException</code> to
  8888. redirect the user to another page. This is useful to prompt the user for
  8889. additional information, e.g. if you want them to provide their own username.
  8890. It is the responsibility of the mapping provider to either redirect back
  8891. to <code>client_redirect_url</code> (including any additional information) or to
  8892. complete registration using methods from the <code>ModuleApi</code>.</p>
  8893. </li>
  8894. </ul>
  8895. </li>
  8896. </ul>
  8897. <h3 id="default-saml-mapping-provider"><a class="header" href="#default-saml-mapping-provider">Default SAML Mapping Provider</a></h3>
  8898. <p>Synapse has a built-in SAML mapping provider if a custom provider isn't
  8899. specified in the config. It is located at
  8900. <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/handlers/saml.py"><code>synapse.handlers.saml.DefaultSamlMappingProvider</code></a>.</p>
  8901. <div style="break-before: page; page-break-before: always;"></div><h2 style="color:red">
  8902. This page of the Synapse documentation is now deprecated. For up to date
  8903. documentation on setting up or writing a password auth provider module, please see
  8904. <a href="modules/index.html">this page</a>.
  8905. </h2>
  8906. <h1 id="password-auth-provider-modules"><a class="header" href="#password-auth-provider-modules">Password auth provider modules</a></h1>
  8907. <p>Password auth providers offer a way for server administrators to
  8908. integrate their Synapse installation with an existing authentication
  8909. system.</p>
  8910. <p>A password auth provider is a Python class which is dynamically loaded
  8911. into Synapse, and provides a number of methods by which it can integrate
  8912. with the authentication system.</p>
  8913. <p>This document serves as a reference for those looking to implement their
  8914. own password auth providers. Additionally, here is a list of known
  8915. password auth provider module implementations:</p>
  8916. <ul>
  8917. <li><a href="https://github.com/matrix-org/matrix-synapse-ldap3/">matrix-synapse-ldap3</a></li>
  8918. <li><a href="https://github.com/devture/matrix-synapse-shared-secret-auth">matrix-synapse-shared-secret-auth</a></li>
  8919. <li><a href="https://github.com/ma1uta/matrix-synapse-rest-password-provider">matrix-synapse-rest-password-provider</a></li>
  8920. </ul>
  8921. <h2 id="required-methods"><a class="header" href="#required-methods">Required methods</a></h2>
  8922. <p>Password auth provider classes must provide the following methods:</p>
  8923. <ul>
  8924. <li>
  8925. <p><code>parse_config(config)</code>
  8926. This method is passed the <code>config</code> object for this module from the
  8927. homeserver configuration file.</p>
  8928. <p>It should perform any appropriate sanity checks on the provided
  8929. configuration, and return an object which is then passed into
  8930. <code>__init__</code>.</p>
  8931. <p>This method should have the <code>@staticmethod</code> decoration.</p>
  8932. </li>
  8933. <li>
  8934. <p><code>__init__(self, config, account_handler)</code></p>
  8935. <p>The constructor is passed the config object returned by
  8936. <code>parse_config</code>, and a <code>synapse.module_api.ModuleApi</code> object which
  8937. allows the password provider to check if accounts exist and/or create
  8938. new ones.</p>
  8939. </li>
  8940. </ul>
  8941. <h2 id="optional-methods"><a class="header" href="#optional-methods">Optional methods</a></h2>
  8942. <p>Password auth provider classes may optionally provide the following methods:</p>
  8943. <ul>
  8944. <li>
  8945. <p><code>get_db_schema_files(self)</code></p>
  8946. <p>This method, if implemented, should return an Iterable of
  8947. <code>(name, stream)</code> pairs of database schema files. Each file is applied
  8948. in turn at initialisation, and a record is then made in the database
  8949. so that it is not re-applied on the next start.</p>
  8950. </li>
  8951. <li>
  8952. <p><code>get_supported_login_types(self)</code></p>
  8953. <p>This method, if implemented, should return a <code>dict</code> mapping from a
  8954. login type identifier (such as <code>m.login.password</code>) to an iterable
  8955. giving the fields which must be provided by the user in the submission
  8956. to <a href="https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login">the <code>/login</code> API</a>.
  8957. These fields are passed in the <code>login_dict</code> dictionary to <code>check_auth</code>.</p>
  8958. <p>For example, if a password auth provider wants to implement a custom
  8959. login type of <code>com.example.custom_login</code>, where the client is expected
  8960. to pass the fields <code>secret1</code> and <code>secret2</code>, the provider should
  8961. implement this method and return the following dict:</p>
  8962. <pre><code class="language-python">{&quot;com.example.custom_login&quot;: (&quot;secret1&quot;, &quot;secret2&quot;)}
  8963. </code></pre>
  8964. </li>
  8965. <li>
  8966. <p><code>check_auth(self, username, login_type, login_dict)</code></p>
  8967. <p>This method does the real work. If implemented, it
  8968. will be called for each login attempt where the login type matches one
  8969. of the keys returned by <code>get_supported_login_types</code>.</p>
  8970. <p>It is passed the (possibly unqualified) <code>user</code> field provided by the client,
  8971. the login type, and a dictionary of login secrets passed by the
  8972. client.</p>
  8973. <p>The method should return an <code>Awaitable</code> object, which resolves
  8974. to the canonical <code>@localpart:domain</code> user ID if authentication is
  8975. successful, and <code>None</code> if not.</p>
  8976. <p>Alternatively, the <code>Awaitable</code> can resolve to a <code>(str, func)</code> tuple, in
  8977. which case the second field is a callback which will be called with
  8978. the result from the <code>/login</code> call (including <code>access_token</code>,
  8979. <code>device_id</code>, etc.)</p>
  8980. </li>
  8981. <li>
  8982. <p><code>check_3pid_auth(self, medium, address, password)</code></p>
  8983. <p>This method, if implemented, is called when a user attempts to
  8984. register or log in with a third party identifier, such as email. It is
  8985. passed the medium (ex. &quot;email&quot;), an address (ex.
  8986. &quot;<a href="mailto:jdoe@example.com">jdoe@example.com</a>&quot;) and the user's password.</p>
  8987. <p>The method should return an <code>Awaitable</code> object, which resolves
  8988. to a <code>str</code> containing the user's (canonical) User id if
  8989. authentication was successful, and <code>None</code> if not.</p>
  8990. <p>As with <code>check_auth</code>, the <code>Awaitable</code> may alternatively resolve to a
  8991. <code>(user_id, callback)</code> tuple.</p>
  8992. </li>
  8993. <li>
  8994. <p><code>check_password(self, user_id, password)</code></p>
  8995. <p>This method provides a simpler interface than
  8996. <code>get_supported_login_types</code> and <code>check_auth</code> for password auth
  8997. providers that just want to provide a mechanism for validating
  8998. <code>m.login.password</code> logins.</p>
  8999. <p>If implemented, it will be called to check logins with an
  9000. <code>m.login.password</code> login type. It is passed a qualified
  9001. <code>@localpart:domain</code> user id, and the password provided by the user.</p>
  9002. <p>The method should return an <code>Awaitable</code> object, which resolves
  9003. to <code>True</code> if authentication is successful, and <code>False</code> if not.</p>
  9004. </li>
  9005. <li>
  9006. <p><code>on_logged_out(self, user_id, device_id, access_token)</code></p>
  9007. <p>This method, if implemented, is called when a user logs out. It is
  9008. passed the qualified user ID, the ID of the deactivated device (if
  9009. any: access tokens are occasionally created without an associated
  9010. device ID), and the (now deactivated) access token.</p>
  9011. <p>It may return an <code>Awaitable</code> object; the logout request will
  9012. wait for the <code>Awaitable</code> to complete, but the result is ignored.</p>
  9013. </li>
  9014. </ul>
  9015. <div style="break-before: page; page-break-before: always;"></div><h1 id="jwt-login-type"><a class="header" href="#jwt-login-type">JWT Login Type</a></h1>
  9016. <p>Synapse comes with a non-standard login type to support
  9017. <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JSON Web Tokens</a>. In general the
  9018. documentation for
  9019. <a href="https://matrix.org/docs/spec/client_server/r0.6.1#login">the login endpoint</a>
  9020. is still valid (and the mechanism works similarly to the
  9021. <a href="https://matrix.org/docs/spec/client_server/r0.6.1#token-based">token based login</a>).</p>
  9022. <p>To log in using a JSON Web Token, clients should submit a <code>/login</code> request as
  9023. follows:</p>
  9024. <pre><code class="language-json">{
  9025. &quot;type&quot;: &quot;org.matrix.login.jwt&quot;,
  9026. &quot;token&quot;: &quot;&lt;jwt&gt;&quot;
  9027. }
  9028. </code></pre>
  9029. <p>The <code>token</code> field should include the JSON web token with the following claims:</p>
  9030. <ul>
  9031. <li>A claim that encodes the local part of the user ID is required. By default,
  9032. the <code>sub</code> (subject) claim is used, or a custom claim can be set in the
  9033. configuration file.</li>
  9034. <li>The expiration time (<code>exp</code>), not before time (<code>nbf</code>), and issued at (<code>iat</code>)
  9035. claims are optional, but validated if present.</li>
  9036. <li>The issuer (<code>iss</code>) claim is optional, but required and validated if configured.</li>
  9037. <li>The audience (<code>aud</code>) claim is optional, but required and validated if configured.
  9038. Providing the audience claim when not configured will cause validation to fail.</li>
  9039. </ul>
  9040. <p>In the case that the token is not valid, the homeserver must respond with
  9041. <code>403 Forbidden</code> and an error code of <code>M_FORBIDDEN</code>.</p>
  9042. <p>As with other login types, there are additional fields (e.g. <code>device_id</code> and
  9043. <code>initial_device_display_name</code>) which can be included in the above request.</p>
  9044. <h2 id="preparing-synapse-1"><a class="header" href="#preparing-synapse-1">Preparing Synapse</a></h2>
  9045. <p>The JSON Web Token integration in Synapse uses the
  9046. <a href="https://docs.authlib.org/en/latest/index.html"><code>Authlib</code></a> library, which must be installed
  9047. as follows:</p>
  9048. <ul>
  9049. <li>
  9050. <p>The relevant libraries are included in the Docker images and Debian packages
  9051. provided by <code>matrix.org</code> so no further action is needed.</p>
  9052. </li>
  9053. <li>
  9054. <p>If you installed Synapse into a virtualenv, run <code>/path/to/env/bin/pip install synapse[jwt]</code> to install the necessary dependencies.</p>
  9055. </li>
  9056. <li>
  9057. <p>For other installation mechanisms, see the documentation provided by the
  9058. maintainer.</p>
  9059. </li>
  9060. </ul>
  9061. <p>To enable the JSON web token integration, you should then add a <code>jwt_config</code> option
  9062. to your configuration file. See the <a href="usage/configuration/config_documentation.html#jwt_config">configuration manual</a> for some
  9063. sample settings.</p>
  9064. <h2 id="how-to-test-jwt-as-a-developer"><a class="header" href="#how-to-test-jwt-as-a-developer">How to test JWT as a developer</a></h2>
  9065. <p>Although JSON Web Tokens are typically generated from an external server, the
  9066. example below uses a locally generated JWT.</p>
  9067. <ol>
  9068. <li>
  9069. <p>Configure Synapse with JWT logins, note that this example uses a pre-shared
  9070. secret and an algorithm of HS256:</p>
  9071. <pre><code class="language-yaml">jwt_config:
  9072. enabled: true
  9073. secret: &quot;my-secret-token&quot;
  9074. algorithm: &quot;HS256&quot;
  9075. </code></pre>
  9076. </li>
  9077. <li>
  9078. <p>Generate a JSON web token:</p>
  9079. <p>You can use the following short Python snippet to generate a JWT
  9080. protected by an HMAC.
  9081. Take care that the <code>secret</code> and the algorithm given in the <code>header</code> match
  9082. the entries from <code>jwt_config</code> above.</p>
  9083. <pre><code class="language-python">from authlib.jose import jwt
  9084. header = {&quot;alg&quot;: &quot;HS256&quot;}
  9085. payload = {&quot;sub&quot;: &quot;user1&quot;, &quot;aud&quot;: [&quot;audience&quot;]}
  9086. secret = &quot;my-secret-token&quot;
  9087. result = jwt.encode(header, payload, secret)
  9088. print(result.decode(&quot;ascii&quot;))
  9089. </code></pre>
  9090. </li>
  9091. <li>
  9092. <p>Query for the login types and ensure <code>org.matrix.login.jwt</code> is there:</p>
  9093. <pre><code class="language-bash">curl http://localhost:8080/_matrix/client/r0/login
  9094. </code></pre>
  9095. </li>
  9096. <li>
  9097. <p>Login used the generated JSON web token from above:</p>
  9098. <pre><code class="language-bash">$ curl http://localhost:8082/_matrix/client/r0/login -X POST \
  9099. --data '{&quot;type&quot;:&quot;org.matrix.login.jwt&quot;,&quot;token&quot;:&quot;eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.Ag71GT8v01UO3w80aqRPTeuVPBIBZkYhNTJJ-_-zQIc&quot;}'
  9100. {
  9101. &quot;access_token&quot;: &quot;&lt;access token&gt;&quot;,
  9102. &quot;device_id&quot;: &quot;ACBDEFGHI&quot;,
  9103. &quot;home_server&quot;: &quot;localhost:8080&quot;,
  9104. &quot;user_id&quot;: &quot;@test-user:localhost:8480&quot;
  9105. }
  9106. </code></pre>
  9107. </li>
  9108. </ol>
  9109. <p>You should now be able to use the returned access token to query the client API.</p>
  9110. <div style="break-before: page; page-break-before: always;"></div><h1 id="refresh-tokens"><a class="header" href="#refresh-tokens">Refresh Tokens</a></h1>
  9111. <p>Synapse supports refresh tokens since version 1.49 (some earlier versions had support for an earlier, experimental draft of <a href="https://github.com/matrix-org/matrix-doc/blob/main/proposals/2918-refreshtokens.md#msc2918-refresh-tokens">MSC2918</a> which is not compatible).</p>
  9112. <h2 id="background-and-motivation"><a class="header" href="#background-and-motivation">Background and motivation</a></h2>
  9113. <p>Synapse users' sessions are identified by <strong>access tokens</strong>; access tokens are
  9114. issued to users on login. Each session gets a unique access token which identifies
  9115. it; the access token must be kept secret as it grants access to the user's account.</p>
  9116. <p>Traditionally, these access tokens were eternally valid (at least until the user
  9117. explicitly chose to log out).</p>
  9118. <p>In some cases, it may be desirable for these access tokens to expire so that the
  9119. potential damage caused by leaking an access token is reduced.
  9120. On the other hand, forcing a user to re-authenticate (log in again) often might
  9121. be too much of an inconvenience.</p>
  9122. <p><strong>Refresh tokens</strong> are a mechanism to avoid some of this inconvenience whilst
  9123. still getting most of the benefits of short access token lifetimes.
  9124. Refresh tokens are also a concept present in OAuth 2 — further reading is available
  9125. <a href="https://datatracker.ietf.org/doc/html/rfc6749#section-1.5">here</a>.</p>
  9126. <p>When refresh tokens are in use, both an access token and a refresh token will be
  9127. issued to users on login. The access token will expire after a predetermined amount
  9128. of time, but otherwise works in the same way as before. When the access token is
  9129. close to expiring (or has expired), the user's client should present the homeserver
  9130. (Synapse) with the refresh token.</p>
  9131. <p>The homeserver will then generate a new access token and refresh token for the user
  9132. and return them. The old refresh token is invalidated and can not be used again*.</p>
  9133. <p>Finally, refresh tokens also make it possible for sessions to be logged out if they
  9134. are inactive for too long, before the session naturally ends; see the configuration
  9135. guide below.</p>
  9136. <p>*To prevent issues if clients lose connection half-way through refreshing a token,
  9137. the refresh token is only invalidated once the new access token has been used at
  9138. least once. For all intents and purposes, the above simplification is sufficient.</p>
  9139. <h2 id="caveats"><a class="header" href="#caveats">Caveats</a></h2>
  9140. <p>There are some caveats:</p>
  9141. <ul>
  9142. <li>If a third party gets both your access token and refresh token, they will be able to
  9143. continue to enjoy access to your session.
  9144. <ul>
  9145. <li>This is still an improvement because you (the user) will notice when <em>your</em>
  9146. session expires and you're not able to use your refresh token.
  9147. That would be a giveaway that someone else has compromised your session.
  9148. You would be able to log in again and terminate that session.
  9149. Previously (with long-lived access tokens), a third party that has your access
  9150. token could go undetected for a very long time.</li>
  9151. </ul>
  9152. </li>
  9153. <li>Clients need to implement support for refresh tokens in order for them to be a
  9154. useful mechanism.
  9155. <ul>
  9156. <li>It is up to homeserver administrators if they want to issue long-lived access
  9157. tokens to clients not implementing refresh tokens.
  9158. <ul>
  9159. <li>For compatibility, it is likely that they should, at least until client support
  9160. is widespread.
  9161. <ul>
  9162. <li>Users with clients that support refresh tokens will still benefit from the
  9163. added security; it's not possible to downgrade a session to using long-lived
  9164. access tokens so this effectively gives users the choice.</li>
  9165. </ul>
  9166. </li>
  9167. <li>In a closed environment where all users use known clients, this may not be
  9168. an issue as the homeserver administrator can know if the clients have refresh
  9169. token support. In that case, the non-refreshable access token lifetime
  9170. may be set to a short duration so that a similar level of security is provided.</li>
  9171. </ul>
  9172. </li>
  9173. </ul>
  9174. </li>
  9175. </ul>
  9176. <h2 id="configuration-guide"><a class="header" href="#configuration-guide">Configuration Guide</a></h2>
  9177. <p>The following configuration options, in the <code>registration</code> section, are related:</p>
  9178. <ul>
  9179. <li><code>session_lifetime</code>: maximum length of a session, even if it's refreshed.
  9180. In other words, the client must log in again after this time period.
  9181. In most cases, this can be unset (infinite) or set to a long time (years or months).</li>
  9182. <li><code>refreshable_access_token_lifetime</code>: lifetime of access tokens that are created
  9183. by clients supporting refresh tokens.
  9184. This should be short; a good value might be 5 minutes (<code>5m</code>).</li>
  9185. <li><code>nonrefreshable_access_token_lifetime</code>: lifetime of access tokens that are created
  9186. by clients which don't support refresh tokens.
  9187. Make this short if you want to effectively force use of refresh tokens.
  9188. Make this long if you don't want to inconvenience users of clients which don't
  9189. support refresh tokens (by forcing them to frequently re-authenticate using
  9190. login credentials).</li>
  9191. <li><code>refresh_token_lifetime</code>: lifetime of refresh tokens.
  9192. In other words, the client must refresh within this time period to maintain its session.
  9193. Unless you want to log inactive sessions out, it is often fine to use a long
  9194. value here or even leave it unset (infinite).
  9195. Beware that making it too short will inconvenience clients that do not connect
  9196. very often, including mobile clients and clients of infrequent users (by making
  9197. it more difficult for them to refresh in time, which may force them to need to
  9198. re-authenticate using login credentials).</li>
  9199. </ul>
  9200. <p><strong>Note:</strong> All four options above only apply when tokens are created (by logging in or refreshing).
  9201. Changes to these settings do not apply retroactively.</p>
  9202. <h3 id="using-refresh-token-expiry-to-log-out-inactive-sessions"><a class="header" href="#using-refresh-token-expiry-to-log-out-inactive-sessions">Using refresh token expiry to log out inactive sessions</a></h3>
  9203. <p>If you'd like to force sessions to be logged out upon inactivity, you can enable
  9204. refreshable access token expiry and refresh token expiry.</p>
  9205. <p>This works because a client must refresh at least once within a period of
  9206. <code>refresh_token_lifetime</code> in order to maintain valid credentials to access the
  9207. account.</p>
  9208. <p>(It's suggested that <code>refresh_token_lifetime</code> should be longer than
  9209. <code>refreshable_access_token_lifetime</code> and this section assumes that to be the case
  9210. for simplicity.)</p>
  9211. <p>Note: this will only affect sessions using refresh tokens. You may wish to
  9212. set a short <code>nonrefreshable_access_token_lifetime</code> to prevent this being bypassed
  9213. by clients that do not support refresh tokens.</p>
  9214. <h4 id="choosing-values-that-guarantee-permitting-some-inactivity"><a class="header" href="#choosing-values-that-guarantee-permitting-some-inactivity">Choosing values that guarantee permitting some inactivity</a></h4>
  9215. <p>It may be desirable to permit some short periods of inactivity, for example to
  9216. accommodate brief outages in client connectivity.</p>
  9217. <p>The following model aims to provide guidance for choosing <code>refresh_token_lifetime</code>
  9218. and <code>refreshable_access_token_lifetime</code> to satisfy requirements of the form:</p>
  9219. <ol>
  9220. <li>inactivity longer than <code>L</code> <strong>MUST</strong> cause the session to be logged out; and</li>
  9221. <li>inactivity shorter than <code>S</code> <strong>MUST NOT</strong> cause the session to be logged out.</li>
  9222. </ol>
  9223. <p>This model makes the weakest assumption that all active clients will refresh as
  9224. needed to maintain an active access token, but no sooner.
  9225. <em>In reality, clients may refresh more often than this model assumes, but the
  9226. above requirements will still hold.</em></p>
  9227. <p>To satisfy the above model,</p>
  9228. <ul>
  9229. <li><code>refresh_token_lifetime</code> should be set to <code>L</code>; and</li>
  9230. <li><code>refreshable_access_token_lifetime</code> should be set to <code>L - S</code>.</li>
  9231. </ul>
  9232. <div style="break-before: page; page-break-before: always;"></div><h1 id="overview-2"><a class="header" href="#overview-2">Overview</a></h1>
  9233. <p>A captcha can be enabled on your homeserver to help prevent bots from registering
  9234. accounts. Synapse currently uses Google's reCAPTCHA service which requires API keys
  9235. from Google.</p>
  9236. <h2 id="getting-api-keys"><a class="header" href="#getting-api-keys">Getting API keys</a></h2>
  9237. <ol>
  9238. <li>Create a new site at <a href="https://www.google.com/recaptcha/admin/create">https://www.google.com/recaptcha/admin/create</a></li>
  9239. <li>Set the label to anything you want</li>
  9240. <li>Set the type to reCAPTCHA v2 using the &quot;I'm not a robot&quot; Checkbox option.
  9241. This is the only type of captcha that works with Synapse.</li>
  9242. <li>Add the public hostname for your server, as set in <code>public_baseurl</code>
  9243. in <code>homeserver.yaml</code>, to the list of authorized domains. If you have not set
  9244. <code>public_baseurl</code>, use <code>server_name</code>.</li>
  9245. <li>Agree to the terms of service and submit.</li>
  9246. <li>Copy your site key and secret key and add them to your <code>homeserver.yaml</code>
  9247. configuration file
  9248. <pre><code class="language-yaml">recaptcha_public_key: YOUR_SITE_KEY
  9249. recaptcha_private_key: YOUR_SECRET_KEY
  9250. </code></pre>
  9251. </li>
  9252. <li>Enable the CAPTCHA for new registrations
  9253. <pre><code class="language-yaml">enable_registration_captcha: true
  9254. </code></pre>
  9255. </li>
  9256. <li>Go to the settings page for the CAPTCHA you just created</li>
  9257. <li>Uncheck the &quot;Verify the origin of reCAPTCHA solutions&quot; checkbox so that the
  9258. captcha can be displayed in any client. If you do not disable this option then you
  9259. must specify the domains of every client that is allowed to display the CAPTCHA.</li>
  9260. </ol>
  9261. <h2 id="configuring-ip-used-for-auth"><a class="header" href="#configuring-ip-used-for-auth">Configuring IP used for auth</a></h2>
  9262. <p>The reCAPTCHA API requires that the IP address of the user who solved the
  9263. CAPTCHA is sent. If the client is connecting through a proxy or load balancer,
  9264. it may be required to use the <code>X-Forwarded-For</code> (XFF) header instead of the origin
  9265. IP address. This can be configured using the <code>x_forwarded</code> directive in the
  9266. listeners section of the <code>homeserver.yaml</code> configuration file.</p>
  9267. <div style="break-before: page; page-break-before: always;"></div><h1 id="registering-an-application-service"><a class="header" href="#registering-an-application-service">Registering an Application Service</a></h1>
  9268. <p>The registration of new application services depends on the homeserver used.
  9269. In synapse, you need to create a new configuration file for your AS and add it
  9270. to the list specified under the <code>app_service_config_files</code> config
  9271. option in your synapse config.</p>
  9272. <p>For example:</p>
  9273. <pre><code class="language-yaml">app_service_config_files:
  9274. - /home/matrix/.synapse/&lt;your-AS&gt;.yaml
  9275. </code></pre>
  9276. <p>The format of the AS configuration file is as follows:</p>
  9277. <pre><code class="language-yaml">id: &lt;your-AS-id&gt;
  9278. url: &lt;base url of AS&gt;
  9279. as_token: &lt;token AS will add to requests to HS&gt;
  9280. hs_token: &lt;token HS will add to requests to AS&gt;
  9281. sender_localpart: &lt;localpart of AS user&gt;
  9282. namespaces:
  9283. users: # List of users we're interested in
  9284. - exclusive: &lt;bool&gt;
  9285. regex: &lt;regex&gt;
  9286. group_id: &lt;group&gt;
  9287. - ...
  9288. aliases: [] # List of aliases we're interested in
  9289. rooms: [] # List of room ids we're interested in
  9290. </code></pre>
  9291. <p><code>exclusive</code>: If enabled, only this application service is allowed to register users in its namespace(s).
  9292. <code>group_id</code>: All users of this application service are dynamically joined to this group. This is useful for e.g user organisation or flairs.</p>
  9293. <p>See the <a href="https://matrix.org/docs/spec/application_service/unstable.html">spec</a> for further details on how application services work.</p>
  9294. <div style="break-before: page; page-break-before: always;"></div><h1 id="server-notices"><a class="header" href="#server-notices">Server Notices</a></h1>
  9295. <p>'Server Notices' are a new feature introduced in Synapse 0.30. They provide a
  9296. channel whereby server administrators can send messages to users on the server.</p>
  9297. <p>They are used as part of communication of the server polices (see
  9298. <a href="consent_tracking.html">Consent Tracking</a>), however the intention is that
  9299. they may also find a use for features such as &quot;Message of the day&quot;.</p>
  9300. <p>This is a feature specific to Synapse, but it uses standard Matrix
  9301. communication mechanisms, so should work with any Matrix client.</p>
  9302. <h2 id="user-experience"><a class="header" href="#user-experience">User experience</a></h2>
  9303. <p>When the user is first sent a server notice, they will get an invitation to a
  9304. room (typically called 'Server Notices', though this is configurable in
  9305. <code>homeserver.yaml</code>). They will be <strong>unable to reject</strong> this invitation -
  9306. attempts to do so will receive an error.</p>
  9307. <p>Once they accept the invitation, they will see the notice message in the room
  9308. history; it will appear to have come from the 'server notices user' (see
  9309. below).</p>
  9310. <p>The user is prevented from sending any messages in this room by the power
  9311. levels.</p>
  9312. <p>Having joined the room, the user can leave the room if they want. Subsequent
  9313. server notices will then cause a new room to be created.</p>
  9314. <h2 id="synapse-configuration"><a class="header" href="#synapse-configuration">Synapse configuration</a></h2>
  9315. <p>Server notices come from a specific user id on the server. Server
  9316. administrators are free to choose the user id - something like <code>server</code> is
  9317. suggested, meaning the notices will come from
  9318. <code>@server:&lt;your_server_name&gt;</code>. Once the Server Notices user is configured, that
  9319. user id becomes a special, privileged user, so administrators should ensure
  9320. that <strong>it is not already allocated</strong>.</p>
  9321. <p>In order to support server notices, it is necessary to add some configuration
  9322. to the <code>homeserver.yaml</code> file. In particular, you should add a <code>server_notices</code>
  9323. section, which should look like this:</p>
  9324. <pre><code class="language-yaml">server_notices:
  9325. system_mxid_localpart: server
  9326. system_mxid_display_name: &quot;Server Notices&quot;
  9327. system_mxid_avatar_url: &quot;mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ&quot;
  9328. room_name: &quot;Server Notices&quot;
  9329. auto_join: true
  9330. </code></pre>
  9331. <p>The only compulsory setting is <code>system_mxid_localpart</code>, which defines the user
  9332. id of the Server Notices user, as above. <code>room_name</code> defines the name of the
  9333. room which will be created.</p>
  9334. <p><code>system_mxid_display_name</code> and <code>system_mxid_avatar_url</code> can be used to set the
  9335. displayname and avatar of the Server Notices user.</p>
  9336. <p><code>auto_join</code> will autojoin users to the notices room instead of sending an invite.</p>
  9337. <h2 id="sending-notices"><a class="header" href="#sending-notices">Sending notices</a></h2>
  9338. <p>To send server notices to users you can use the
  9339. <a href="admin_api/server_notices.html">admin_api</a>.</p>
  9340. <div style="break-before: page; page-break-before: always;"></div><h1 id="support-in-synapse-for-tracking-agreement-to-server-terms-and-conditions"><a class="header" href="#support-in-synapse-for-tracking-agreement-to-server-terms-and-conditions">Support in Synapse for tracking agreement to server terms and conditions</a></h1>
  9341. <p>Synapse 0.30 introduces support for tracking whether users have agreed to the
  9342. terms and conditions set by the administrator of a server - and blocking access
  9343. to the server until they have.</p>
  9344. <p>There are several parts to this functionality; each requires some specific
  9345. configuration in <code>homeserver.yaml</code> to be enabled.</p>
  9346. <p>Note that various parts of the configuration and this document refer to the
  9347. &quot;privacy policy&quot;: agreement with a privacy policy is one particular use of this
  9348. feature, but of course administrators can specify other terms and conditions
  9349. unrelated to &quot;privacy&quot; per se.</p>
  9350. <h2 id="collecting-policy-agreement-from-a-user"><a class="header" href="#collecting-policy-agreement-from-a-user">Collecting policy agreement from a user</a></h2>
  9351. <p>Synapse can be configured to serve the user a simple policy form with an
  9352. &quot;accept&quot; button. Clicking &quot;Accept&quot; records the user's acceptance in the
  9353. database and shows a success page.</p>
  9354. <p>To enable this, first create templates for the policy and success pages.
  9355. These should be stored on the local filesystem.</p>
  9356. <p>These templates use the <a href="http://jinja.pocoo.org">Jinja2</a> templating language,
  9357. and <a href="https://github.com/matrix-org/synapse/tree/develop/docs/privacy_policy_templates/">docs/privacy_policy_templates</a>
  9358. gives examples of the sort of thing that can be done.</p>
  9359. <p>Note that the templates must be stored under a name giving the language of the
  9360. template - currently this must always be <code>en</code> (for &quot;English&quot;);
  9361. internationalisation support is intended for the future.</p>
  9362. <p>The template for the policy itself should be versioned and named according to
  9363. the version: for example <code>1.0.html</code>. The version of the policy which the user
  9364. has agreed to is stored in the database.</p>
  9365. <p>Once the templates are in place, make the following changes to <code>homeserver.yaml</code>:</p>
  9366. <ol>
  9367. <li>
  9368. <p>Add a <code>user_consent</code> section, which should look like:</p>
  9369. <pre><code class="language-yaml">user_consent:
  9370. template_dir: privacy_policy_templates
  9371. version: 1.0
  9372. </code></pre>
  9373. <p><code>template_dir</code> points to the directory containing the policy
  9374. templates. <code>version</code> defines the version of the policy which will be served
  9375. to the user. In the example above, Synapse will serve
  9376. <code>privacy_policy_templates/en/1.0.html</code>.</p>
  9377. </li>
  9378. <li>
  9379. <p>Add a <code>form_secret</code> setting at the top level:</p>
  9380. <pre><code class="language-yaml">form_secret: &quot;&lt;unique secret&gt;&quot;
  9381. </code></pre>
  9382. <p>This should be set to an arbitrary secret string (try <code>pwgen -y 30</code> to
  9383. generate suitable secrets).</p>
  9384. <p>More on what this is used for below.</p>
  9385. </li>
  9386. <li>
  9387. <p>Add <code>consent</code> wherever the <code>client</code> resource is currently enabled in the
  9388. <code>listeners</code> configuration. For example:</p>
  9389. <pre><code class="language-yaml">listeners:
  9390. - port: 8008
  9391. resources:
  9392. - names:
  9393. - client
  9394. - consent
  9395. </code></pre>
  9396. </li>
  9397. </ol>
  9398. <p>Finally, ensure that <code>jinja2</code> is installed. If you are using a virtualenv, this
  9399. should be a matter of <code>pip install Jinja2</code>. On debian, try <code>apt-get install python-jinja2</code>.</p>
  9400. <p>Once this is complete, and the server has been restarted, try visiting
  9401. <code>https://&lt;server&gt;/_matrix/consent</code>. If correctly configured, this should give
  9402. an error &quot;Missing string query parameter 'u'&quot;. It is now possible to manually
  9403. construct URIs where users can give their consent.</p>
  9404. <h3 id="enabling-consent-tracking-at-registration"><a class="header" href="#enabling-consent-tracking-at-registration">Enabling consent tracking at registration</a></h3>
  9405. <ol>
  9406. <li>
  9407. <p>Add the following to your configuration:</p>
  9408. <pre><code class="language-yaml">user_consent:
  9409. require_at_registration: true
  9410. policy_name: &quot;Privacy Policy&quot; # or whatever you'd like to call the policy
  9411. </code></pre>
  9412. </li>
  9413. <li>
  9414. <p>In your consent templates, make use of the <code>public_version</code> variable to
  9415. see if an unauthenticated user is viewing the page. This is typically
  9416. wrapped around the form that would be used to actually agree to the document:</p>
  9417. <pre><code class="language-html">{% if not public_version %}
  9418. &lt;!-- The variables used here are only provided when the 'u' param is given to the homeserver --&gt;
  9419. &lt;form method=&quot;post&quot; action=&quot;consent&quot;&gt;
  9420. &lt;input type=&quot;hidden&quot; name=&quot;v&quot; value=&quot;{{version}}&quot;/&gt;
  9421. &lt;input type=&quot;hidden&quot; name=&quot;u&quot; value=&quot;{{user}}&quot;/&gt;
  9422. &lt;input type=&quot;hidden&quot; name=&quot;h&quot; value=&quot;{{userhmac}}&quot;/&gt;
  9423. &lt;input type=&quot;submit&quot; value=&quot;Sure thing!&quot;/&gt;
  9424. &lt;/form&gt;
  9425. {% endif %}
  9426. </code></pre>
  9427. </li>
  9428. <li>
  9429. <p>Restart Synapse to apply the changes.</p>
  9430. </li>
  9431. </ol>
  9432. <p>Visiting <code>https://&lt;server&gt;/_matrix/consent</code> should now give you a view of the privacy
  9433. document. This is what users will be able to see when registering for accounts.</p>
  9434. <h3 id="constructing-the-consent-uri"><a class="header" href="#constructing-the-consent-uri">Constructing the consent URI</a></h3>
  9435. <p>It may be useful to manually construct the &quot;consent URI&quot; for a given user - for
  9436. instance, in order to send them an email asking them to consent. To do this,
  9437. take the base <code>https://&lt;server&gt;/_matrix/consent</code> URL and add the following
  9438. query parameters:</p>
  9439. <ul>
  9440. <li>
  9441. <p><code>u</code>: the user id of the user. This can either be a full MXID
  9442. (<code>@user:server.com</code>) or just the localpart (<code>user</code>).</p>
  9443. </li>
  9444. <li>
  9445. <p><code>h</code>: hex-encoded HMAC-SHA256 of <code>u</code> using the <code>form_secret</code> as a key. It is
  9446. possible to calculate this on the commandline with something like:</p>
  9447. <pre><code class="language-bash">echo -n '&lt;user&gt;' | openssl sha256 -hmac '&lt;form_secret&gt;'
  9448. </code></pre>
  9449. <p>This should result in a URI which looks something like:
  9450. <code>https://&lt;server&gt;/_matrix/consent?u=&lt;user&gt;&amp;h=68a152465a4d...</code>.</p>
  9451. </li>
  9452. </ul>
  9453. <p>Note that not providing a <code>u</code> parameter will be interpreted as wanting to view
  9454. the document from an unauthenticated perspective, such as prior to registration.
  9455. Therefore, the <code>h</code> parameter is not required in this scenario. To enable this
  9456. behaviour, set <code>require_at_registration</code> to <code>true</code> in your <code>user_consent</code> config.</p>
  9457. <h2 id="sending-users-a-server-notice-asking-them-to-agree-to-the-policy"><a class="header" href="#sending-users-a-server-notice-asking-them-to-agree-to-the-policy">Sending users a server notice asking them to agree to the policy</a></h2>
  9458. <p>It is possible to configure Synapse to send a <a href="server_notices.html">server
  9459. notice</a> to anybody who has not yet agreed to the current
  9460. version of the policy. To do so:</p>
  9461. <ul>
  9462. <li>
  9463. <p>ensure that the consent resource is configured, as in the previous section</p>
  9464. </li>
  9465. <li>
  9466. <p>ensure that server notices are configured, as in <a href="server_notices.html">the server notice documentation</a>.</p>
  9467. </li>
  9468. <li>
  9469. <p>Add <code>server_notice_content</code> under <code>user_consent</code> in <code>homeserver.yaml</code>. For
  9470. example:</p>
  9471. <pre><code class="language-yaml">user_consent:
  9472. server_notice_content:
  9473. msgtype: m.text
  9474. body: &gt;-
  9475. Please give your consent to the privacy policy at %(consent_uri)s.
  9476. </code></pre>
  9477. <p>Synapse automatically replaces the placeholder <code>%(consent_uri)s</code> with the
  9478. consent uri for that user.</p>
  9479. </li>
  9480. <li>
  9481. <p>ensure that <code>public_baseurl</code> is set in <code>homeserver.yaml</code>, and gives the base
  9482. URI that clients use to connect to the server. (It is used to construct
  9483. <code>consent_uri</code> in the server notice.)</p>
  9484. </li>
  9485. </ul>
  9486. <h2 id="blocking-users-from-using-the-server-until-they-agree-to-the-policy"><a class="header" href="#blocking-users-from-using-the-server-until-they-agree-to-the-policy">Blocking users from using the server until they agree to the policy</a></h2>
  9487. <p>Synapse can be configured to block any attempts to join rooms or send messages
  9488. until the user has given their agreement to the policy. (Joining the server
  9489. notices room is exempted from this).</p>
  9490. <p>To enable this, add <code>block_events_error</code> under <code>user_consent</code>. For example:</p>
  9491. <pre><code class="language-yaml">user_consent:
  9492. block_events_error: &gt;-
  9493. You can't send any messages until you consent to the privacy policy at
  9494. %(consent_uri)s.
  9495. </code></pre>
  9496. <p>Synapse automatically replaces the placeholder <code>%(consent_uri)s</code> with the
  9497. consent uri for that user.</p>
  9498. <p>ensure that <code>public_baseurl</code> is set in <code>homeserver.yaml</code>, and gives the base
  9499. URI that clients use to connect to the server. (It is used to construct
  9500. <code>consent_uri</code> in the error.)</p>
  9501. <div style="break-before: page; page-break-before: always;"></div><h1 id="user-directory-api-implementation"><a class="header" href="#user-directory-api-implementation">User Directory API Implementation</a></h1>
  9502. <p>The user directory is maintained based on users that are 'visible' to the homeserver -
  9503. i.e. ones which are local to the server and ones which any local user shares a
  9504. room with.</p>
  9505. <p>The directory info is stored in various tables, which can sometimes get out of
  9506. sync (although this is considered a bug). If this happens, for now the
  9507. solution to fix it is to use the <a href="usage/administration/admin_api/background_updates.html#run">admin API</a>
  9508. and execute the job <code>regenerate_directory</code>. This should then start a background task to
  9509. flush the current tables and regenerate the directory. Depending on the size
  9510. of your homeserver (number of users and rooms) this can take a while.</p>
  9511. <h2 id="data-model"><a class="header" href="#data-model">Data model</a></h2>
  9512. <p>There are five relevant tables that collectively form the &quot;user directory&quot;.
  9513. Three of them track a list of all known users. The last two (collectively called
  9514. the &quot;search tables&quot;) track which users are visible to each other.</p>
  9515. <p>From all of these tables we exclude three types of local user:</p>
  9516. <ul>
  9517. <li>support users</li>
  9518. <li>appservice users</li>
  9519. <li>deactivated users</li>
  9520. </ul>
  9521. <p>A description of each table follows:</p>
  9522. <ul>
  9523. <li>
  9524. <p><code>user_directory</code>. This contains the user ID, display name and avatar of each user.</p>
  9525. <ul>
  9526. <li>Because there is only one directory entry per user, it is important that it
  9527. only contain publicly visible information. Otherwise, this will leak the
  9528. nickname or avatar used in a private room.</li>
  9529. <li>Indexed on rooms. Indexed on users.</li>
  9530. </ul>
  9531. </li>
  9532. <li>
  9533. <p><code>user_directory_search</code>. To be joined to <code>user_directory</code>. It contains an extra
  9534. column that enables full text search based on user IDs and display names.
  9535. Different schemas for SQLite and Postgres are used.</p>
  9536. <ul>
  9537. <li>Indexed on the full text search data. Indexed on users.</li>
  9538. </ul>
  9539. </li>
  9540. <li>
  9541. <p><code>user_directory_stream_pos</code>. When the initial background update to populate
  9542. the directory is complete, we record a stream position here. This indicates
  9543. that synapse should now listen for room changes and incrementally update
  9544. the directory where necessary. (See <a href="development/synapse_architecture/streams.html">stream positions</a>.)</p>
  9545. </li>
  9546. <li>
  9547. <p><code>users_in_public_rooms</code>. Contains associations between users and the public
  9548. rooms they're in. Used to determine which users are in public rooms and should
  9549. be publicly visible in the directory. Both local and remote users are tracked.</p>
  9550. </li>
  9551. <li>
  9552. <p><code>users_who_share_private_rooms</code>. Rows are triples <code>(L, M, room id)</code> where <code>L</code>
  9553. is a local user and <code>M</code> is a local or remote user. <code>L</code> and <code>M</code> should be
  9554. different, but this isn't enforced by a constraint.</p>
  9555. <p>Note that if two local users share a room then there will be two entries:
  9556. <code>(user1, user2, !room_id)</code> and <code>(user2, user1, !room_id)</code>.</p>
  9557. </li>
  9558. </ul>
  9559. <h2 id="configuration-options"><a class="header" href="#configuration-options">Configuration options</a></h2>
  9560. <p>The exact way user search works can be tweaked via some server-level
  9561. <a href="usage/configuration/config_documentation.html#user_directory">configuration options</a>.</p>
  9562. <p>The information is not repeated here, but the options are mentioned below.</p>
  9563. <h2 id="search-algorithm"><a class="header" href="#search-algorithm">Search algorithm</a></h2>
  9564. <p>If <code>search_all_users</code> is <code>false</code>, then results are limited to users who:</p>
  9565. <ol>
  9566. <li>Are found in the <code>users_in_public_rooms</code> table, or</li>
  9567. <li>Are found in the <code>users_who_share_private_rooms</code> where <code>L</code> is the requesting
  9568. user and <code>M</code> is the search result.</li>
  9569. </ol>
  9570. <p>Otherwise, if <code>search_all_users</code> is <code>true</code>, no such limits are placed and all
  9571. users known to the server (matching the search query) will be returned.</p>
  9572. <p>By default, locked users are not returned. If <code>show_locked_users</code> is <code>true</code> then
  9573. no filtering on the locked status of a user is done.</p>
  9574. <p>The user provided search term is lowercased and normalized using <a href="https://en.wikipedia.org/wiki/Unicode_equivalence#Normalization">NFKC</a>,
  9575. this treats the string as case-insensitive, canonicalizes different forms of the
  9576. same text, and maps some &quot;roughly equivalent&quot; characters together.</p>
  9577. <p>The search term is then split into words:</p>
  9578. <ul>
  9579. <li>If <a href="https://en.wikipedia.org/wiki/International_Components_for_Unicode">ICU</a> is
  9580. available, then the system's <a href="https://unicode-org.github.io/icu/userguide/locale/#default-locales">default locale</a>
  9581. will be used to break the search term into words. (See the
  9582. <a href="setup/installation.html">installation instructions</a> for how to install ICU.)</li>
  9583. <li>If unavailable, then runs of ASCII characters, numbers, underscores, and hyphens
  9584. are considered words.</li>
  9585. </ul>
  9586. <p>The queries for PostgreSQL and SQLite are detailed below, by their overall goal
  9587. is to find matching users, preferring users who are &quot;real&quot; (e.g. not bots,
  9588. not deactivated). It is assumed that real users will have an display name and
  9589. avatar set.</p>
  9590. <h3 id="postgresql"><a class="header" href="#postgresql">PostgreSQL</a></h3>
  9591. <p>The above words are then transformed into two queries:</p>
  9592. <ol>
  9593. <li>&quot;exact&quot; which matches the parsed words exactly (using <a href="https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES"><code>to_tsquery</code></a>);</li>
  9594. <li>&quot;prefix&quot; which matches the parsed words as prefixes (using <code>to_tsquery</code>).</li>
  9595. </ol>
  9596. <p>Results are composed of all rows in the <code>user_directory_search</code> table whose information
  9597. matches one (or both) of these queries. Results are ordered by calculating a weighted
  9598. score for each result, higher scores are returned first:</p>
  9599. <ul>
  9600. <li>4x if a user ID exists.</li>
  9601. <li>1.2x if the user has a display name set.</li>
  9602. <li>1.2x if the user has an avatar set.</li>
  9603. <li>0x-3x by the full text search results using the <a href="https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING"><code>ts_rank_cd</code> function</a>
  9604. against the &quot;exact&quot; search query; this has four variables with the following weightings:
  9605. <ul>
  9606. <li><code>D</code>: 0.1 for the user ID's domain</li>
  9607. <li><code>C</code>: 0.1 for unused</li>
  9608. <li><code>B</code>: 0.9 for the user's display name (or an empty string if it is not set)</li>
  9609. <li><code>A</code>: 0.1 for the user ID's localpart</li>
  9610. </ul>
  9611. </li>
  9612. <li>0x-1x by the full text search results using the <code>ts_rank_cd</code> function against the
  9613. &quot;prefix&quot; search query. (Using the same weightings as above.)</li>
  9614. <li>If <code>prefer_local_users</code> is <code>true</code>, then 2x if the user is local to the homeserver.</li>
  9615. </ul>
  9616. <p>Note that <code>ts_rank_cd</code> returns a weight between 0 and 1. The initial weighting of
  9617. all results is 1.</p>
  9618. <h3 id="sqlite"><a class="header" href="#sqlite">SQLite</a></h3>
  9619. <p>Results are composed of all rows in the <code>user_directory_search</code> whose information
  9620. matches the query. Results are ordered by the following information, with each
  9621. subsequent column used as a tiebreaker, for each result:</p>
  9622. <ol>
  9623. <li>By the <a href="https://www.sqlite.org/windowfunctions.html#built_in_window_functions"><code>rank</code></a>
  9624. of the full text search results using the <a href="https://www.sqlite.org/fts3.html#matchinfo"><code>matchinfo</code> function</a>. Higher
  9625. ranks are returned first.</li>
  9626. <li>If <code>prefer_local_users</code> is <code>true</code>, then users local to the homeserver are
  9627. returned first.</li>
  9628. <li>Users with a display name set are returned first.</li>
  9629. <li>Users with an avatar set are returned first.</li>
  9630. </ol>
  9631. <div style="break-before: page; page-break-before: always;"></div><h1 id="message-retention-policies"><a class="header" href="#message-retention-policies">Message retention policies</a></h1>
  9632. <p>Synapse admins can enable support for message retention policies on
  9633. their homeserver. Message retention policies exist at a room level,
  9634. follow the semantics described in
  9635. <a href="https://github.com/matrix-org/matrix-doc/blob/matthew/msc1763/proposals/1763-configurable-retention-periods.md">MSC1763</a>,
  9636. and allow server and room admins to configure how long messages should
  9637. be kept in a homeserver's database before being purged from it.
  9638. <strong>Please note that, as this feature isn't part of the Matrix
  9639. specification yet, this implementation is to be considered as
  9640. experimental.</strong></p>
  9641. <p>A message retention policy is mainly defined by its <code>max_lifetime</code>
  9642. parameter, which defines how long a message can be kept around after
  9643. it was sent to the room. If a room doesn't have a message retention
  9644. policy, and there's no default one for a given server, then no message
  9645. sent in that room is ever purged on that server.</p>
  9646. <p>MSC1763 also specifies semantics for a <code>min_lifetime</code> parameter which
  9647. defines the amount of time after which an event <em>can</em> get purged (after
  9648. it was sent to the room), but Synapse doesn't currently support it
  9649. beyond registering it.</p>
  9650. <p>Both <code>max_lifetime</code> and <code>min_lifetime</code> are optional parameters.</p>
  9651. <p>Note that message retention policies don't apply to state events.</p>
  9652. <p>Once an event reaches its expiry date (defined as the time it was sent
  9653. plus the value for <code>max_lifetime</code> in the room), two things happen:</p>
  9654. <ul>
  9655. <li>Synapse stops serving the event to clients via any endpoint.</li>
  9656. <li>The message gets picked up by the next purge job (see the &quot;Purge jobs&quot;
  9657. section) and is removed from Synapse's database.</li>
  9658. </ul>
  9659. <p>Since purge jobs don't run continuously, this means that an event might
  9660. stay in a server's database for longer than the value for <code>max_lifetime</code>
  9661. in the room would allow, though hidden from clients.</p>
  9662. <p>Similarly, if a server (with support for message retention policies
  9663. enabled) receives from another server an event that should have been
  9664. purged according to its room's policy, then the receiving server will
  9665. process and store that event until it's picked up by the next purge job,
  9666. though it will always hide it from clients.</p>
  9667. <p>Synapse requires at least one message in each room, so it will never
  9668. delete the last message in a room. It will, however, hide it from
  9669. clients.</p>
  9670. <h2 id="server-configuration"><a class="header" href="#server-configuration">Server configuration</a></h2>
  9671. <p>Support for this feature can be enabled and configured by adding a the
  9672. <code>retention</code> in the Synapse configuration file (see
  9673. <a href="usage/configuration/config_documentation.html#retention">configuration manual</a>).</p>
  9674. <p>To enable support for message retention policies, set the setting
  9675. <code>enabled</code> in this section to <code>true</code>.</p>
  9676. <h3 id="default-policy"><a class="header" href="#default-policy">Default policy</a></h3>
  9677. <p>A default message retention policy is a policy defined in Synapse's
  9678. configuration that is used by Synapse for every room that doesn't have a
  9679. message retention policy configured in its state. This allows server
  9680. admins to ensure that messages are never kept indefinitely in a server's
  9681. database. </p>
  9682. <p>A default policy can be defined as such, by adding the <code>retention</code> option in
  9683. the configuration file and adding these sub-options:</p>
  9684. <pre><code class="language-yaml">default_policy:
  9685. min_lifetime: 1d
  9686. max_lifetime: 1y
  9687. </code></pre>
  9688. <p>Here, <code>min_lifetime</code> and <code>max_lifetime</code> have the same meaning and level
  9689. of support as previously described. They can be expressed either as a
  9690. duration (using the units <code>s</code> (seconds), <code>m</code> (minutes), <code>h</code> (hours),
  9691. <code>d</code> (days), <code>w</code> (weeks) and <code>y</code> (years)) or as a number of milliseconds.</p>
  9692. <h3 id="purge-jobs"><a class="header" href="#purge-jobs">Purge jobs</a></h3>
  9693. <p>Purge jobs are the jobs that Synapse runs in the background to purge
  9694. expired events from the database. They are only run if support for
  9695. message retention policies is enabled in the server's configuration. If
  9696. no configuration for purge jobs is configured by the server admin,
  9697. Synapse will use a default configuration, which is described here in the
  9698. <a href="usage/configuration/config_documentation.html#retention">configuration manual</a>.</p>
  9699. <p>Some server admins might want a finer control on when events are removed
  9700. depending on an event's room's policy. This can be done by setting the
  9701. <code>purge_jobs</code> sub-section in the <code>retention</code> section of the configuration
  9702. file. An example of such configuration could be:</p>
  9703. <pre><code class="language-yaml">purge_jobs:
  9704. - longest_max_lifetime: 3d
  9705. interval: 12h
  9706. - shortest_max_lifetime: 3d
  9707. longest_max_lifetime: 1w
  9708. interval: 1d
  9709. - shortest_max_lifetime: 1w
  9710. interval: 2d
  9711. </code></pre>
  9712. <p>In this example, we define three jobs:</p>
  9713. <ul>
  9714. <li>one that runs twice a day (every 12 hours) and purges events in rooms
  9715. which policy's <code>max_lifetime</code> is lower or equal to 3 days.</li>
  9716. <li>one that runs once a day and purges events in rooms which policy's
  9717. <code>max_lifetime</code> is between 3 days and a week.</li>
  9718. <li>one that runs once every 2 days and purges events in rooms which
  9719. policy's <code>max_lifetime</code> is greater than a week.</li>
  9720. </ul>
  9721. <p>Note that this example is tailored to show different configurations and
  9722. features slightly more jobs than it's probably necessary (in practice, a
  9723. server admin would probably consider it better to replace the two last
  9724. jobs with one that runs once a day and handles rooms which
  9725. policy's <code>max_lifetime</code> is greater than 3 days).</p>
  9726. <p>Keep in mind, when configuring these jobs, that a purge job can become
  9727. quite heavy on the server if it targets many rooms, therefore prefer
  9728. having jobs with a low interval that target a limited set of rooms. Also
  9729. make sure to include a job with no minimum and one with no maximum to
  9730. make sure your configuration handles every policy.</p>
  9731. <p>As previously mentioned in this documentation, while a purge job that
  9732. runs e.g. every day means that an expired event might stay in the
  9733. database for up to a day after its expiry, Synapse hides expired events
  9734. from clients as soon as they expire, so the event is not visible to
  9735. local users between its expiry date and the moment it gets purged from
  9736. the server's database.</p>
  9737. <h3 id="lifetime-limits"><a class="header" href="#lifetime-limits">Lifetime limits</a></h3>
  9738. <p>Server admins can set limits on the values of <code>max_lifetime</code> to use when
  9739. purging old events in a room. These limits can be defined under the
  9740. <code>retention</code> option in the configuration file:</p>
  9741. <pre><code class="language-yaml">allowed_lifetime_min: 1d
  9742. allowed_lifetime_max: 1y
  9743. </code></pre>
  9744. <p>The limits are considered when running purge jobs. If necessary, the
  9745. effective value of <code>max_lifetime</code> will be brought between
  9746. <code>allowed_lifetime_min</code> and <code>allowed_lifetime_max</code> (inclusive).
  9747. This means that, if the value of <code>max_lifetime</code> defined in the room's state
  9748. is lower than <code>allowed_lifetime_min</code>, the value of <code>allowed_lifetime_min</code>
  9749. will be used instead. Likewise, if the value of <code>max_lifetime</code> is higher
  9750. than <code>allowed_lifetime_max</code>, the value of <code>allowed_lifetime_max</code> will be
  9751. used instead.</p>
  9752. <p>In the example above, we ensure Synapse never deletes events that are less
  9753. than one day old, and that it always deletes events that are over a year
  9754. old.</p>
  9755. <p>If a default policy is set, and its <code>max_lifetime</code> value is lower than
  9756. <code>allowed_lifetime_min</code> or higher than <code>allowed_lifetime_max</code>, the same
  9757. process applies.</p>
  9758. <p>Both parameters are optional; if one is omitted Synapse won't use it to
  9759. adjust the effective value of <code>max_lifetime</code>.</p>
  9760. <p>Like other settings in this section, these parameters can be expressed
  9761. either as a duration or as a number of milliseconds.</p>
  9762. <h2 id="room-configuration"><a class="header" href="#room-configuration">Room configuration</a></h2>
  9763. <p>To configure a room's message retention policy, a room's admin or
  9764. moderator needs to send a state event in that room with the type
  9765. <code>m.room.retention</code> and the following content:</p>
  9766. <pre><code class="language-json">{
  9767. &quot;max_lifetime&quot;: ...
  9768. }
  9769. </code></pre>
  9770. <p>In this event's content, the <code>max_lifetime</code> parameter has the same
  9771. meaning as previously described, and needs to be expressed in
  9772. milliseconds. The event's content can also include a <code>min_lifetime</code>
  9773. parameter, which has the same meaning and limited support as previously
  9774. described.</p>
  9775. <p>Note that over every server in the room, only the ones with support for
  9776. message retention policies will actually remove expired events. This
  9777. support is currently not enabled by default in Synapse.</p>
  9778. <h2 id="note-on-reclaiming-disk-space"><a class="header" href="#note-on-reclaiming-disk-space">Note on reclaiming disk space</a></h2>
  9779. <p>While purge jobs actually delete data from the database, the disk space
  9780. used by the database might not decrease immediately on the database's
  9781. host. However, even though the database engine won't free up the disk
  9782. space, it will start writing new data into where the purged data was.</p>
  9783. <p>If you want to reclaim the freed disk space anyway and return it to the
  9784. operating system, the server admin needs to run <code>VACUUM FULL;</code> (or
  9785. <code>VACUUM;</code> for SQLite databases) on Synapse's database (see the related
  9786. <a href="https://www.postgresql.org/docs/current/sql-vacuum.html">PostgreSQL documentation</a>).</p>
  9787. <div style="break-before: page; page-break-before: always;"></div><h1 id="modules-2"><a class="header" href="#modules-2">Modules</a></h1>
  9788. <p>Synapse supports extending its functionality by configuring external modules.</p>
  9789. <p><strong>Note</strong>: When using third-party modules, you effectively allow someone else to run
  9790. custom code on your Synapse homeserver. Server admins are encouraged to verify the
  9791. provenance of the modules they use on their homeserver and make sure the modules aren't
  9792. running malicious code on their instance.</p>
  9793. <h2 id="using-modules"><a class="header" href="#using-modules">Using modules</a></h2>
  9794. <p>To use a module on Synapse, add it to the <code>modules</code> section of the configuration file:</p>
  9795. <pre><code class="language-yaml">modules:
  9796. - module: my_super_module.MySuperClass
  9797. config:
  9798. do_thing: true
  9799. - module: my_other_super_module.SomeClass
  9800. config: {}
  9801. </code></pre>
  9802. <p>Each module is defined by a path to a Python class as well as a configuration. This
  9803. information for a given module should be available in the module's own documentation.</p>
  9804. <h2 id="using-multiple-modules"><a class="header" href="#using-multiple-modules">Using multiple modules</a></h2>
  9805. <p>The order in which modules are listed in this section is important. When processing an
  9806. action that can be handled by several modules, Synapse will always prioritise the module
  9807. that appears first (i.e. is the highest in the list). This means:</p>
  9808. <ul>
  9809. <li>If several modules register the same callback, the callback registered by the module
  9810. that appears first is used.</li>
  9811. <li>If several modules try to register a handler for the same HTTP path, only the handler
  9812. registered by the module that appears first is used. Handlers registered by the other
  9813. module(s) are ignored and Synapse will log a warning message about them.</li>
  9814. </ul>
  9815. <p>Note that Synapse doesn't allow multiple modules implementing authentication checkers via
  9816. the password auth provider feature for the same login type with different fields. If this
  9817. happens, Synapse will refuse to start.</p>
  9818. <h2 id="current-status"><a class="header" href="#current-status">Current status</a></h2>
  9819. <p>We are currently in the process of migrating module interfaces to this system. While some
  9820. interfaces might be compatible with it, others still require configuring modules in
  9821. another part of Synapse's configuration file.</p>
  9822. <p>Currently, only the following pre-existing interfaces are compatible with this new system:</p>
  9823. <ul>
  9824. <li>spam checker</li>
  9825. <li>third-party rules</li>
  9826. <li>presence router</li>
  9827. <li>password auth providers</li>
  9828. </ul>
  9829. <div style="break-before: page; page-break-before: always;"></div><h1 id="writing-a-module"><a class="header" href="#writing-a-module">Writing a module</a></h1>
  9830. <p>A module is a Python class that uses Synapse's module API to interact with the
  9831. homeserver. It can register callbacks that Synapse will call on specific operations, as
  9832. well as web resources to attach to Synapse's web server.</p>
  9833. <p>When instantiated, a module is given its parsed configuration as well as an instance of
  9834. the <code>synapse.module_api.ModuleApi</code> class. The configuration is a dictionary, and is
  9835. either the output of the module's <code>parse_config</code> static method (see below), or the
  9836. configuration associated with the module in Synapse's configuration file.</p>
  9837. <p>See the documentation for the <code>ModuleApi</code> class
  9838. <a href="https://github.com/matrix-org/synapse/blob/master/synapse/module_api/__init__.py">here</a>.</p>
  9839. <h2 id="when-synapse-runs-with-several-modules-configured"><a class="header" href="#when-synapse-runs-with-several-modules-configured">When Synapse runs with several modules configured</a></h2>
  9840. <p>If Synapse is running with other modules configured, the order each module appears in
  9841. within the <code>modules</code> section of the Synapse configuration file might restrict what it can
  9842. or cannot register. See <a href="modules/index.html#using-multiple-modules">this section</a> for more
  9843. information.</p>
  9844. <p>On top of the rules listed in the link above, if a callback returns a value that should
  9845. cause the current operation to fail (e.g. if a callback checking an event returns with a
  9846. value that should cause the event to be denied), Synapse will fail the operation and
  9847. ignore any subsequent callbacks that should have been run after this one.</p>
  9848. <p>The documentation for each callback mentions how Synapse behaves when
  9849. multiple modules implement it.</p>
  9850. <h2 id="handling-the-modules-configuration"><a class="header" href="#handling-the-modules-configuration">Handling the module's configuration</a></h2>
  9851. <p>A module can implement the following static method:</p>
  9852. <pre><code class="language-python">@staticmethod
  9853. def parse_config(config: dict) -&gt; Any
  9854. </code></pre>
  9855. <p>This method is given a dictionary resulting from parsing the YAML configuration for the
  9856. module. It may modify it (for example by parsing durations expressed as strings (e.g.
  9857. &quot;5d&quot;) into milliseconds, etc.), and return the modified dictionary. It may also verify
  9858. that the configuration is correct, and raise an instance of
  9859. <code>synapse.module_api.errors.ConfigError</code> if not.</p>
  9860. <h2 id="registering-a-web-resource"><a class="header" href="#registering-a-web-resource">Registering a web resource</a></h2>
  9861. <p>Modules can register web resources onto Synapse's web server using the following module
  9862. API method:</p>
  9863. <pre><code class="language-python">def ModuleApi.register_web_resource(path: str, resource: IResource) -&gt; None
  9864. </code></pre>
  9865. <p>The path is the full absolute path to register the resource at. For example, if you
  9866. register a resource for the path <code>/_synapse/client/my_super_module/say_hello</code>, Synapse
  9867. will serve it at <code>http(s)://[HS_URL]/_synapse/client/my_super_module/say_hello</code>. Note
  9868. that Synapse does not allow registering resources for several sub-paths in the <code>/_matrix</code>
  9869. namespace (such as anything under <code>/_matrix/client</code> for example). It is strongly
  9870. recommended that modules register their web resources under the <code>/_synapse/client</code>
  9871. namespace.</p>
  9872. <p>The provided resource is a Python class that implements Twisted's <a href="https://docs.twistedmatrix.com/en/stable/api/twisted.web.resource.IResource.html">IResource</a>
  9873. interface (such as <a href="https://docs.twistedmatrix.com/en/stable/api/twisted.web.resource.Resource.html">Resource</a>).</p>
  9874. <p>Only one resource can be registered for a given path. If several modules attempt to
  9875. register a resource for the same path, the module that appears first in Synapse's
  9876. configuration file takes priority.</p>
  9877. <p>Modules <strong>must</strong> register their web resources in their <code>__init__</code> method.</p>
  9878. <h2 id="registering-a-callback"><a class="header" href="#registering-a-callback">Registering a callback</a></h2>
  9879. <p>Modules can use Synapse's module API to register callbacks. Callbacks are functions that
  9880. Synapse will call when performing specific actions. Callbacks must be asynchronous (unless
  9881. specified otherwise), and are split in categories. A single module may implement callbacks
  9882. from multiple categories, and is under no obligation to implement all callbacks from the
  9883. categories it registers callbacks for.</p>
  9884. <p>Modules can register callbacks using one of the module API's <code>register_[...]_callbacks</code>
  9885. methods. The callback functions are passed to these methods as keyword arguments, with
  9886. the callback name as the argument name and the function as its value. A
  9887. <code>register_[...]_callbacks</code> method exists for each category.</p>
  9888. <p>Callbacks for each category can be found on their respective page of the
  9889. <a href="https://matrix-org.github.io/synapse">Synapse documentation website</a>.</p>
  9890. <h2 id="caching-1"><a class="header" href="#caching-1">Caching</a></h2>
  9891. <p><em>Added in Synapse 1.74.0.</em></p>
  9892. <p>Modules can leverage Synapse's caching tools to manage their own cached functions. This
  9893. can be helpful for modules that need to repeatedly request the same data from the database
  9894. or a remote service.</p>
  9895. <p>Functions that need to be wrapped with a cache need to be decorated with a <code>@cached()</code>
  9896. decorator (which can be imported from <code>synapse.module_api</code>) and registered with the
  9897. <a href="https://github.com/matrix-org/synapse/blob/release-v1.77/synapse/module_api/__init__.py#L888"><code>ModuleApi.register_cached_function</code></a>
  9898. API when initialising the module. If the module needs to invalidate an entry in a cache,
  9899. it needs to use the <a href="https://github.com/matrix-org/synapse/blob/release-v1.77/synapse/module_api/__init__.py#L904"><code>ModuleApi.invalidate_cache</code></a>
  9900. API, with the function to invalidate the cache of and the key(s) of the entry to
  9901. invalidate.</p>
  9902. <p>Below is an example of a simple module using a cached function:</p>
  9903. <pre><code class="language-python">from typing import Any
  9904. from synapse.module_api import cached, ModuleApi
  9905. class MyModule:
  9906. def __init__(self, config: Any, api: ModuleApi):
  9907. self.api = api
  9908. # Register the cached function so Synapse knows how to correctly invalidate
  9909. # entries for it.
  9910. self.api.register_cached_function(self.get_user_from_id)
  9911. @cached()
  9912. async def get_department_for_user(self, user_id: str) -&gt; str:
  9913. &quot;&quot;&quot;A function with a cache.&quot;&quot;&quot;
  9914. # Request a department from an external service.
  9915. return await self.http_client.get_json(
  9916. &quot;https://int.example.com/users&quot;, {&quot;user_id&quot;: user_id)
  9917. )[&quot;department&quot;]
  9918. async def do_something_with_users(self) -&gt; None:
  9919. &quot;&quot;&quot;Calls the cached function and then invalidates an entry in its cache.&quot;&quot;&quot;
  9920. user_id = &quot;@alice:example.com&quot;
  9921. # Get the user. Since get_department_for_user is wrapped with a cache,
  9922. # the return value for this user_id will be cached.
  9923. department = await self.get_department_for_user(user_id)
  9924. # Do something with `department`...
  9925. # Let's say something has changed with our user, and the entry we have for
  9926. # them in the cache is out of date, so we want to invalidate it.
  9927. await self.api.invalidate_cache(self.get_department_for_user, (user_id,))
  9928. </code></pre>
  9929. <p>See the <a href="https://github.com/matrix-org/synapse/blob/release-v1.77/synapse/module_api/__init__.py#L190"><code>cached</code> docstring</a> for more details.</p>
  9930. <div style="break-before: page; page-break-before: always;"></div><h1 id="spam-checker-callbacks"><a class="header" href="#spam-checker-callbacks">Spam checker callbacks</a></h1>
  9931. <p>Spam checker callbacks allow module developers to implement spam mitigation actions for
  9932. Synapse instances. Spam checker callbacks can be registered using the module API's
  9933. <code>register_spam_checker_callbacks</code> method.</p>
  9934. <h2 id="callbacks"><a class="header" href="#callbacks">Callbacks</a></h2>
  9935. <p>The available spam checker callbacks are:</p>
  9936. <h3 id="check_event_for_spam"><a class="header" href="#check_event_for_spam"><code>check_event_for_spam</code></a></h3>
  9937. <p><em>First introduced in Synapse v1.37.0</em></p>
  9938. <p><em>Changed in Synapse v1.60.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean or a string is now deprecated.</em> </p>
  9939. <pre><code class="language-python">async def check_event_for_spam(event: &quot;synapse.module_api.EventBase&quot;) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, str, bool]
  9940. </code></pre>
  9941. <p>Called when receiving an event from a client or via federation. The callback must return one of:</p>
  9942. <ul>
  9943. <li><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  9944. decide to reject it.</li>
  9945. <li><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  9946. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</li>
  9947. <li>(deprecated) a non-<code>Codes</code> <code>str</code> to reject the operation and specify an error message. Note that clients
  9948. typically will not localize the error message to the user's preferred locale.</li>
  9949. <li>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</li>
  9950. <li>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</li>
  9951. </ul>
  9952. <p>If multiple modules implement this callback, they will be considered in order. If a
  9953. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  9954. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  9955. be used. If this happens, Synapse will not call any of the subsequent implementations of
  9956. this callback.</p>
  9957. <h3 id="user_may_join_room"><a class="header" href="#user_may_join_room"><code>user_may_join_room</code></a></h3>
  9958. <p><em>First introduced in Synapse v1.37.0</em></p>
  9959. <p><em>Changed in Synapse v1.61.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  9960. <pre><code class="language-python">async def user_may_join_room(user: str, room: str, is_invited: bool) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  9961. </code></pre>
  9962. <p>Called when a user is trying to join a room. The user is represented by their Matrix user ID (e.g.
  9963. <code>@alice:example.com</code>) and the room is represented by its Matrix ID (e.g.
  9964. <code>!room:example.com</code>). The module is also given a boolean to indicate whether the user
  9965. currently has a pending invite in the room.</p>
  9966. <p>This callback isn't called if the join is performed by a server administrator, or in the
  9967. context of a room creation.</p>
  9968. <p>The callback must return one of:</p>
  9969. <ul>
  9970. <li><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  9971. decide to reject it.</li>
  9972. <li><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  9973. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</li>
  9974. <li>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</li>
  9975. <li>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</li>
  9976. </ul>
  9977. <p>If multiple modules implement this callback, they will be considered in order. If a
  9978. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  9979. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  9980. be used. If this happens, Synapse will not call any of the subsequent implementations of
  9981. this callback.</p>
  9982. <h3 id="user_may_invite"><a class="header" href="#user_may_invite"><code>user_may_invite</code></a></h3>
  9983. <p><em>First introduced in Synapse v1.37.0</em></p>
  9984. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  9985. <pre><code class="language-python">async def user_may_invite(inviter: str, invitee: str, room_id: str) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  9986. </code></pre>
  9987. <p>Called when processing an invitation. Both inviter and invitee are
  9988. represented by their Matrix user ID (e.g. <code>@alice:example.com</code>).</p>
  9989. <p>The callback must return one of:</p>
  9990. <ul>
  9991. <li>
  9992. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  9993. decide to reject it.</p>
  9994. </li>
  9995. <li>
  9996. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  9997. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  9998. </li>
  9999. <li>
  10000. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10001. </li>
  10002. <li>
  10003. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10004. </li>
  10005. </ul>
  10006. <p>If multiple modules implement this callback, they will be considered in order. If a
  10007. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10008. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10009. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10010. this callback.</p>
  10011. <h3 id="user_may_send_3pid_invite"><a class="header" href="#user_may_send_3pid_invite"><code>user_may_send_3pid_invite</code></a></h3>
  10012. <p><em>First introduced in Synapse v1.45.0</em></p>
  10013. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  10014. <pre><code class="language-python">async def user_may_send_3pid_invite(
  10015. inviter: str,
  10016. medium: str,
  10017. address: str,
  10018. room_id: str,
  10019. ) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  10020. </code></pre>
  10021. <p>Called when processing an invitation using a third-party identifier (also called a 3PID,
  10022. e.g. an email address or a phone number). </p>
  10023. <p>The inviter is represented by their Matrix user ID (e.g. <code>@alice:example.com</code>), and the
  10024. invitee is represented by its medium (e.g. &quot;email&quot;) and its address
  10025. (e.g. <code>alice@example.com</code>). See <a href="https://matrix.org/docs/spec/appendices#pid-types">the Matrix specification</a>
  10026. for more information regarding third-party identifiers.</p>
  10027. <p>For example, a call to this callback to send an invitation to the email address
  10028. <code>alice@example.com</code> would look like this:</p>
  10029. <pre><code class="language-python">await user_may_send_3pid_invite(
  10030. &quot;@bob:example.com&quot;, # The inviter's user ID
  10031. &quot;email&quot;, # The medium of the 3PID to invite
  10032. &quot;alice@example.com&quot;, # The address of the 3PID to invite
  10033. &quot;!some_room:example.com&quot;, # The ID of the room to send the invite into
  10034. )
  10035. </code></pre>
  10036. <p><strong>Note</strong>: If the third-party identifier is already associated with a matrix user ID,
  10037. <a href="modules/spam_checker_callbacks.html#user_may_invite"><code>user_may_invite</code></a> will be used instead.</p>
  10038. <p>The callback must return one of:</p>
  10039. <ul>
  10040. <li>
  10041. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  10042. decide to reject it.</p>
  10043. </li>
  10044. <li>
  10045. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  10046. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  10047. </li>
  10048. <li>
  10049. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10050. </li>
  10051. <li>
  10052. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10053. </li>
  10054. </ul>
  10055. <p>If multiple modules implement this callback, they will be considered in order. If a
  10056. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10057. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10058. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10059. this callback.</p>
  10060. <h3 id="user_may_create_room"><a class="header" href="#user_may_create_room"><code>user_may_create_room</code></a></h3>
  10061. <p><em>First introduced in Synapse v1.37.0</em></p>
  10062. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  10063. <pre><code class="language-python">async def user_may_create_room(user_id: str) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  10064. </code></pre>
  10065. <p>Called when processing a room creation request.</p>
  10066. <p>The callback must return one of:</p>
  10067. <ul>
  10068. <li>
  10069. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  10070. decide to reject it.</p>
  10071. </li>
  10072. <li>
  10073. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  10074. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  10075. </li>
  10076. <li>
  10077. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10078. </li>
  10079. <li>
  10080. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10081. </li>
  10082. </ul>
  10083. <p>If multiple modules implement this callback, they will be considered in order. If a
  10084. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10085. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10086. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10087. this callback.</p>
  10088. <h3 id="user_may_create_room_alias"><a class="header" href="#user_may_create_room_alias"><code>user_may_create_room_alias</code></a></h3>
  10089. <p><em>First introduced in Synapse v1.37.0</em></p>
  10090. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  10091. <pre><code class="language-python">async def user_may_create_room_alias(user_id: str, room_alias: &quot;synapse.module_api.RoomAlias&quot;) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  10092. </code></pre>
  10093. <p>Called when trying to associate an alias with an existing room.</p>
  10094. <p>The callback must return one of:</p>
  10095. <ul>
  10096. <li>
  10097. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  10098. decide to reject it.</p>
  10099. </li>
  10100. <li>
  10101. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  10102. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  10103. </li>
  10104. <li>
  10105. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10106. </li>
  10107. <li>
  10108. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10109. </li>
  10110. </ul>
  10111. <p>If multiple modules implement this callback, they will be considered in order. If a
  10112. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10113. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10114. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10115. this callback.</p>
  10116. <h3 id="user_may_publish_room"><a class="header" href="#user_may_publish_room"><code>user_may_publish_room</code></a></h3>
  10117. <p><em>First introduced in Synapse v1.37.0</em></p>
  10118. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  10119. <pre><code class="language-python">async def user_may_publish_room(user_id: str, room_id: str) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  10120. </code></pre>
  10121. <p>Called when trying to publish a room to the homeserver's public rooms directory.</p>
  10122. <p>The callback must return one of:</p>
  10123. <ul>
  10124. <li>
  10125. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  10126. decide to reject it.</p>
  10127. </li>
  10128. <li>
  10129. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  10130. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  10131. </li>
  10132. <li>
  10133. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10134. </li>
  10135. <li>
  10136. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10137. </li>
  10138. </ul>
  10139. <p>If multiple modules implement this callback, they will be considered in order. If a
  10140. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10141. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10142. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10143. this callback.</p>
  10144. <h3 id="check_username_for_spam"><a class="header" href="#check_username_for_spam"><code>check_username_for_spam</code></a></h3>
  10145. <p><em>First introduced in Synapse v1.37.0</em></p>
  10146. <pre><code class="language-python">async def check_username_for_spam(user_profile: synapse.module_api.UserProfile) -&gt; bool
  10147. </code></pre>
  10148. <p>Called when computing search results in the user directory. The module must return a
  10149. <code>bool</code> indicating whether the given user should be excluded from user directory
  10150. searches. Return <code>True</code> to indicate that the user is spammy and exclude them from
  10151. search results; otherwise return <code>False</code>.</p>
  10152. <p>The profile is represented as a dictionary with the following keys:</p>
  10153. <ul>
  10154. <li><code>user_id: str</code>. The Matrix ID for this user.</li>
  10155. <li><code>display_name: Optional[str]</code>. The user's display name, or <code>None</code> if this user
  10156. has not set a display name.</li>
  10157. <li><code>avatar_url: Optional[str]</code>. The <code>mxc://</code> URL to the user's avatar, or <code>None</code>
  10158. if this user has not set an avatar.</li>
  10159. </ul>
  10160. <p>The module is given a copy of the original dictionary, so modifying it from within the
  10161. module cannot modify a user's profile when included in user directory search results.</p>
  10162. <p>If multiple modules implement this callback, they will be considered in order. If a
  10163. callback returns <code>False</code>, Synapse falls through to the next one. The value of the first
  10164. callback that does not return <code>False</code> will be used. If this happens, Synapse will not call
  10165. any of the subsequent implementations of this callback.</p>
  10166. <h3 id="check_registration_for_spam"><a class="header" href="#check_registration_for_spam"><code>check_registration_for_spam</code></a></h3>
  10167. <p><em>First introduced in Synapse v1.37.0</em></p>
  10168. <pre><code class="language-python">async def check_registration_for_spam(
  10169. email_threepid: Optional[dict],
  10170. username: Optional[str],
  10171. request_info: Collection[Tuple[str, str]],
  10172. auth_provider_id: Optional[str] = None,
  10173. ) -&gt; &quot;synapse.spam_checker_api.RegistrationBehaviour&quot;
  10174. </code></pre>
  10175. <p>Called when registering a new user. The module must return a <code>RegistrationBehaviour</code>
  10176. indicating whether the registration can go through or must be denied, or whether the user
  10177. may be allowed to register but will be shadow banned.</p>
  10178. <p>The arguments passed to this callback are:</p>
  10179. <ul>
  10180. <li><code>email_threepid</code>: The email address used for registering, if any.</li>
  10181. <li><code>username</code>: The username the user would like to register. Can be <code>None</code>, meaning that
  10182. Synapse will generate one later.</li>
  10183. <li><code>request_info</code>: A collection of tuples, which first item is a user agent, and which
  10184. second item is an IP address. These user agents and IP addresses are the ones that were
  10185. used during the registration process.</li>
  10186. <li><code>auth_provider_id</code>: The identifier of the SSO authentication provider, if any.</li>
  10187. </ul>
  10188. <p>If multiple modules implement this callback, they will be considered in order. If a
  10189. callback returns <code>RegistrationBehaviour.ALLOW</code>, Synapse falls through to the next one.
  10190. The value of the first callback that does not return <code>RegistrationBehaviour.ALLOW</code> will
  10191. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10192. this callback.</p>
  10193. <h3 id="check_media_file_for_spam"><a class="header" href="#check_media_file_for_spam"><code>check_media_file_for_spam</code></a></h3>
  10194. <p><em>First introduced in Synapse v1.37.0</em></p>
  10195. <p><em>Changed in Synapse v1.62.0: <code>synapse.module_api.NOT_SPAM</code> and <code>synapse.module_api.errors.Codes</code> can be returned by this callback. Returning a boolean is now deprecated.</em> </p>
  10196. <pre><code class="language-python">async def check_media_file_for_spam(
  10197. file_wrapper: &quot;synapse.media.media_storage.ReadableFileWrapper&quot;,
  10198. file_info: &quot;synapse.media._base.FileInfo&quot;,
  10199. ) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;, bool]
  10200. </code></pre>
  10201. <p>Called when storing a local or remote file.</p>
  10202. <p>The callback must return one of:</p>
  10203. <ul>
  10204. <li>
  10205. <p><code>synapse.module_api.NOT_SPAM</code>, to allow the operation. Other callbacks may still
  10206. decide to reject it.</p>
  10207. </li>
  10208. <li>
  10209. <p><code>synapse.module_api.errors.Codes</code> to reject the operation with an error code. In case
  10210. of doubt, <code>synapse.module_api.errors.Codes.FORBIDDEN</code> is a good error code.</p>
  10211. </li>
  10212. <li>
  10213. <p>(deprecated) <code>False</code>, which is the same as returning <code>synapse.module_api.NOT_SPAM</code>.</p>
  10214. </li>
  10215. <li>
  10216. <p>(deprecated) <code>True</code>, which is the same as returning <code>synapse.module_api.errors.Codes.FORBIDDEN</code>.</p>
  10217. </li>
  10218. </ul>
  10219. <p>If multiple modules implement this callback, they will be considered in order. If a
  10220. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10221. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10222. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10223. this callback.</p>
  10224. <h3 id="should_drop_federated_event"><a class="header" href="#should_drop_federated_event"><code>should_drop_federated_event</code></a></h3>
  10225. <p><em>First introduced in Synapse v1.60.0</em></p>
  10226. <pre><code class="language-python">async def should_drop_federated_event(event: &quot;synapse.events.EventBase&quot;) -&gt; bool
  10227. </code></pre>
  10228. <p>Called when checking whether a remote server can federate an event with us. <strong>Returning
  10229. <code>True</code> from this function will silently drop a federated event and split-brain our view
  10230. of a room's DAG, and thus you shouldn't use this callback unless you know what you are
  10231. doing.</strong></p>
  10232. <p>If multiple modules implement this callback, they will be considered in order. If a
  10233. callback returns <code>False</code>, Synapse falls through to the next one. The value of the first
  10234. callback that does not return <code>False</code> will be used. If this happens, Synapse will not call
  10235. any of the subsequent implementations of this callback.</p>
  10236. <h3 id="check_login_for_spam"><a class="header" href="#check_login_for_spam"><code>check_login_for_spam</code></a></h3>
  10237. <p><em>First introduced in Synapse v1.87.0</em></p>
  10238. <pre><code class="language-python">async def check_login_for_spam(
  10239. user_id: str,
  10240. device_id: Optional[str],
  10241. initial_display_name: Optional[str],
  10242. request_info: Collection[Tuple[Optional[str], str]],
  10243. auth_provider_id: Optional[str] = None,
  10244. ) -&gt; Union[&quot;synapse.module_api.NOT_SPAM&quot;, &quot;synapse.module_api.errors.Codes&quot;]
  10245. </code></pre>
  10246. <p>Called when a user logs in.</p>
  10247. <p>The arguments passed to this callback are:</p>
  10248. <ul>
  10249. <li><code>user_id</code>: The user ID the user is logging in with</li>
  10250. <li><code>device_id</code>: The device ID the user is re-logging into.</li>
  10251. <li><code>initial_display_name</code>: The device display name, if any.</li>
  10252. <li><code>request_info</code>: A collection of tuples, which first item is a user agent, and which
  10253. second item is an IP address. These user agents and IP addresses are the ones that were
  10254. used during the login process.</li>
  10255. <li><code>auth_provider_id</code>: The identifier of the SSO authentication provider, if any.</li>
  10256. </ul>
  10257. <p>If multiple modules implement this callback, they will be considered in order. If a
  10258. callback returns <code>synapse.module_api.NOT_SPAM</code>, Synapse falls through to the next one.
  10259. The value of the first callback that does not return <code>synapse.module_api.NOT_SPAM</code> will
  10260. be used. If this happens, Synapse will not call any of the subsequent implementations of
  10261. this callback.</p>
  10262. <p><em>Note:</em> This will not be called when a user registers.</p>
  10263. <h2 id="example"><a class="header" href="#example">Example</a></h2>
  10264. <p>The example below is a module that implements the spam checker callback
  10265. <code>check_event_for_spam</code> to deny any message sent by users whose Matrix user IDs are
  10266. mentioned in a configured list, and registers a web resource to the path
  10267. <code>/_synapse/client/list_spam_checker/is_evil</code> that returns a JSON object indicating
  10268. whether the provided user appears in that list.</p>
  10269. <pre><code class="language-python">import json
  10270. from typing import Union
  10271. from twisted.web.resource import Resource
  10272. from twisted.web.server import Request
  10273. from synapse.module_api import ModuleApi
  10274. class IsUserEvilResource(Resource):
  10275. def __init__(self, config):
  10276. super(IsUserEvilResource, self).__init__()
  10277. self.evil_users = config.get(&quot;evil_users&quot;) or []
  10278. def render_GET(self, request: Request):
  10279. user = request.args.get(b&quot;user&quot;)[0].decode()
  10280. request.setHeader(b&quot;Content-Type&quot;, b&quot;application/json&quot;)
  10281. return json.dumps({&quot;evil&quot;: user in self.evil_users}).encode()
  10282. class ListSpamChecker:
  10283. def __init__(self, config: dict, api: ModuleApi):
  10284. self.api = api
  10285. self.evil_users = config.get(&quot;evil_users&quot;) or []
  10286. self.api.register_spam_checker_callbacks(
  10287. check_event_for_spam=self.check_event_for_spam,
  10288. )
  10289. self.api.register_web_resource(
  10290. path=&quot;/_synapse/client/list_spam_checker/is_evil&quot;,
  10291. resource=IsUserEvilResource(config),
  10292. )
  10293. async def check_event_for_spam(self, event: &quot;synapse.events.EventBase&quot;) -&gt; Union[Literal[&quot;NOT_SPAM&quot;], Codes]:
  10294. if event.sender in self.evil_users:
  10295. return Codes.FORBIDDEN
  10296. else:
  10297. return synapse.module_api.NOT_SPAM
  10298. </code></pre>
  10299. <div style="break-before: page; page-break-before: always;"></div><h1 id="third-party-rules-callbacks"><a class="header" href="#third-party-rules-callbacks">Third party rules callbacks</a></h1>
  10300. <p>Third party rules callbacks allow module developers to add extra checks to verify the
  10301. validity of incoming events. Third party event rules callbacks can be registered using
  10302. the module API's <code>register_third_party_rules_callbacks</code> method.</p>
  10303. <h2 id="callbacks-1"><a class="header" href="#callbacks-1">Callbacks</a></h2>
  10304. <p>The available third party rules callbacks are:</p>
  10305. <h3 id="check_event_allowed"><a class="header" href="#check_event_allowed"><code>check_event_allowed</code></a></h3>
  10306. <p><em>First introduced in Synapse v1.39.0</em></p>
  10307. <pre><code class="language-python">async def check_event_allowed(
  10308. event: &quot;synapse.events.EventBase&quot;,
  10309. state_events: &quot;synapse.types.StateMap&quot;,
  10310. ) -&gt; Tuple[bool, Optional[dict]]
  10311. </code></pre>
  10312. <p><strong><span style="color:red">
  10313. This callback is very experimental and can and will break without notice. Module developers
  10314. are encouraged to implement <code>check_event_for_spam</code> from the spam checker category instead.
  10315. </span></strong></p>
  10316. <p>Called when processing any incoming event, with the event and a <code>StateMap</code>
  10317. representing the current state of the room the event is being sent into. A <code>StateMap</code> is
  10318. a dictionary that maps tuples containing an event type and a state key to the
  10319. corresponding state event. For example retrieving the room's <code>m.room.create</code> event from
  10320. the <code>state_events</code> argument would look like this: <code>state_events.get((&quot;m.room.create&quot;, &quot;&quot;))</code>.
  10321. The module must return a boolean indicating whether the event can be allowed.</p>
  10322. <p>Note that this callback function processes incoming events coming via federation
  10323. traffic (on top of client traffic). This means denying an event might cause the local
  10324. copy of the room's history to diverge from that of remote servers. This may cause
  10325. federation issues in the room. It is strongly recommended to only deny events using this
  10326. callback function if the sender is a local user, or in a private federation in which all
  10327. servers are using the same module, with the same configuration.</p>
  10328. <p>If the boolean returned by the module is <code>True</code>, it may also tell Synapse to replace the
  10329. event with new data by returning the new event's data as a dictionary. In order to do
  10330. that, it is recommended the module calls <code>event.get_dict()</code> to get the current event as a
  10331. dictionary, and modify the returned dictionary accordingly.</p>
  10332. <p>If <code>check_event_allowed</code> raises an exception, the module is assumed to have failed.
  10333. The event will not be accepted but is not treated as explicitly rejected, either.
  10334. An HTTP request causing the module check will likely result in a 500 Internal
  10335. Server Error.</p>
  10336. <p>When the boolean returned by the module is <code>False</code>, the event is rejected.
  10337. (Module developers should not use exceptions for rejection.)</p>
  10338. <p>Note that replacing the event only works for events sent by local users, not for events
  10339. received over federation.</p>
  10340. <p>If multiple modules implement this callback, they will be considered in order. If a
  10341. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10342. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10343. any of the subsequent implementations of this callback.</p>
  10344. <h3 id="on_create_room"><a class="header" href="#on_create_room"><code>on_create_room</code></a></h3>
  10345. <p><em>First introduced in Synapse v1.39.0</em></p>
  10346. <pre><code class="language-python">async def on_create_room(
  10347. requester: &quot;synapse.types.Requester&quot;,
  10348. request_content: dict,
  10349. is_requester_admin: bool,
  10350. ) -&gt; None
  10351. </code></pre>
  10352. <p>Called when processing a room creation request, with the <code>Requester</code> object for the user
  10353. performing the request, a dictionary representing the room creation request's JSON body
  10354. (see <a href="https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-createroom">the spec</a>
  10355. for a list of possible parameters), and a boolean indicating whether the user performing
  10356. the request is a server admin.</p>
  10357. <p>Modules can modify the <code>request_content</code> (by e.g. adding events to its <code>initial_state</code>),
  10358. or deny the room's creation by raising a <code>module_api.errors.SynapseError</code>.</p>
  10359. <p>If multiple modules implement this callback, they will be considered in order. If a
  10360. callback returns without raising an exception, Synapse falls through to the next one. The
  10361. room creation will be forbidden as soon as one of the callbacks raises an exception. If
  10362. this happens, Synapse will not call any of the subsequent implementations of this
  10363. callback.</p>
  10364. <h3 id="check_threepid_can_be_invited"><a class="header" href="#check_threepid_can_be_invited"><code>check_threepid_can_be_invited</code></a></h3>
  10365. <p><em>First introduced in Synapse v1.39.0</em></p>
  10366. <pre><code class="language-python">async def check_threepid_can_be_invited(
  10367. medium: str,
  10368. address: str,
  10369. state_events: &quot;synapse.types.StateMap&quot;,
  10370. ) -&gt; bool:
  10371. </code></pre>
  10372. <p>Called when processing an invite via a third-party identifier (i.e. email or phone number).
  10373. The module must return a boolean indicating whether the invite can go through.</p>
  10374. <p>If multiple modules implement this callback, they will be considered in order. If a
  10375. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10376. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10377. any of the subsequent implementations of this callback.</p>
  10378. <h3 id="check_visibility_can_be_modified"><a class="header" href="#check_visibility_can_be_modified"><code>check_visibility_can_be_modified</code></a></h3>
  10379. <p><em>First introduced in Synapse v1.39.0</em></p>
  10380. <pre><code class="language-python">async def check_visibility_can_be_modified(
  10381. room_id: str,
  10382. state_events: &quot;synapse.types.StateMap&quot;,
  10383. new_visibility: str,
  10384. ) -&gt; bool:
  10385. </code></pre>
  10386. <p>Called when changing the visibility of a room in the local public room directory. The
  10387. visibility is a string that's either &quot;public&quot; or &quot;private&quot;. The module must return a
  10388. boolean indicating whether the change can go through.</p>
  10389. <p>If multiple modules implement this callback, they will be considered in order. If a
  10390. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10391. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10392. any of the subsequent implementations of this callback.</p>
  10393. <h3 id="on_new_event"><a class="header" href="#on_new_event"><code>on_new_event</code></a></h3>
  10394. <p><em>First introduced in Synapse v1.47.0</em></p>
  10395. <pre><code class="language-python">async def on_new_event(
  10396. event: &quot;synapse.events.EventBase&quot;,
  10397. state_events: &quot;synapse.types.StateMap&quot;,
  10398. ) -&gt; None:
  10399. </code></pre>
  10400. <p>Called after sending an event into a room. The module is passed the event, as well
  10401. as the state of the room <em>after</em> the event. This means that if the event is a state event,
  10402. it will be included in this state.</p>
  10403. <p>Note that this callback is called when the event has already been processed and stored
  10404. into the room, which means this callback cannot be used to deny persisting the event. To
  10405. deny an incoming event, see <a href="modules/spam_checker_callbacks.html#check_event_for_spam"><code>check_event_for_spam</code></a> instead.</p>
  10406. <p>For any given event, this callback will be called on every worker process, even if that worker will not end up
  10407. acting on that event. This callback will not be called for events that are marked as rejected.</p>
  10408. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10409. <h3 id="check_can_shutdown_room"><a class="header" href="#check_can_shutdown_room"><code>check_can_shutdown_room</code></a></h3>
  10410. <p><em>First introduced in Synapse v1.55.0</em></p>
  10411. <pre><code class="language-python">async def check_can_shutdown_room(
  10412. user_id: str, room_id: str,
  10413. ) -&gt; bool:
  10414. </code></pre>
  10415. <p>Called when an admin user requests the shutdown of a room. The module must return a
  10416. boolean indicating whether the shutdown can go through. If the callback returns <code>False</code>,
  10417. the shutdown will not proceed and the caller will see a <code>M_FORBIDDEN</code> error.</p>
  10418. <p>If multiple modules implement this callback, they will be considered in order. If a
  10419. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10420. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10421. any of the subsequent implementations of this callback.</p>
  10422. <h3 id="check_can_deactivate_user"><a class="header" href="#check_can_deactivate_user"><code>check_can_deactivate_user</code></a></h3>
  10423. <p><em>First introduced in Synapse v1.55.0</em></p>
  10424. <pre><code class="language-python">async def check_can_deactivate_user(
  10425. user_id: str, by_admin: bool,
  10426. ) -&gt; bool:
  10427. </code></pre>
  10428. <p>Called when the deactivation of a user is requested. User deactivation can be
  10429. performed by an admin or the user themselves, so developers are encouraged to check the
  10430. requester when implementing this callback. The module must return a
  10431. boolean indicating whether the deactivation can go through. If the callback returns <code>False</code>,
  10432. the deactivation will not proceed and the caller will see a <code>M_FORBIDDEN</code> error.</p>
  10433. <p>The module is passed two parameters, <code>user_id</code> which is the ID of the user being deactivated, and <code>by_admin</code> which is <code>True</code> if the request is made by a serve admin, and <code>False</code> otherwise.</p>
  10434. <p>If multiple modules implement this callback, they will be considered in order. If a
  10435. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10436. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10437. any of the subsequent implementations of this callback.</p>
  10438. <h3 id="on_profile_update"><a class="header" href="#on_profile_update"><code>on_profile_update</code></a></h3>
  10439. <p><em>First introduced in Synapse v1.54.0</em></p>
  10440. <pre><code class="language-python">async def on_profile_update(
  10441. user_id: str,
  10442. new_profile: &quot;synapse.module_api.ProfileInfo&quot;,
  10443. by_admin: bool,
  10444. deactivation: bool,
  10445. ) -&gt; None:
  10446. </code></pre>
  10447. <p>Called after updating a local user's profile. The update can be triggered either by the
  10448. user themselves or a server admin. The update can also be triggered by a user being
  10449. deactivated (in which case their display name is set to an empty string (<code>&quot;&quot;</code>) and the
  10450. avatar URL is set to <code>None</code>). The module is passed the Matrix ID of the user whose profile
  10451. has been updated, their new profile, as well as a <code>by_admin</code> boolean that is <code>True</code> if the
  10452. update was triggered by a server admin (and <code>False</code> otherwise), and a <code>deactivated</code>
  10453. boolean that is <code>True</code> if the update is a result of the user being deactivated.</p>
  10454. <p>Note that the <code>by_admin</code> boolean is also <code>True</code> if the profile change happens as a result
  10455. of the user logging in through Single Sign-On, or if a server admin updates their own
  10456. profile.</p>
  10457. <p>Per-room profile changes do not trigger this callback to be called. Synapse administrators
  10458. wishing this callback to be called on every profile change are encouraged to disable
  10459. per-room profiles globally using the <code>allow_per_room_profiles</code> configuration setting in
  10460. Synapse's configuration file.
  10461. This callback is not called when registering a user, even when setting it through the
  10462. <a href="https://matrix-org.github.io/synapse/latest/modules/password_auth_provider_callbacks.html#get_displayname_for_registration"><code>get_displayname_for_registration</code></a>
  10463. module callback.</p>
  10464. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10465. <h3 id="on_user_deactivation_status_changed"><a class="header" href="#on_user_deactivation_status_changed"><code>on_user_deactivation_status_changed</code></a></h3>
  10466. <p><em>First introduced in Synapse v1.54.0</em></p>
  10467. <pre><code class="language-python">async def on_user_deactivation_status_changed(
  10468. user_id: str, deactivated: bool, by_admin: bool
  10469. ) -&gt; None:
  10470. </code></pre>
  10471. <p>Called after deactivating a local user, or reactivating them through the admin API. The
  10472. deactivation can be triggered either by the user themselves or a server admin. The module
  10473. is passed the Matrix ID of the user whose status is changed, as well as a <code>deactivated</code>
  10474. boolean that is <code>True</code> if the user is being deactivated and <code>False</code> if they're being
  10475. reactivated, and a <code>by_admin</code> boolean that is <code>True</code> if the deactivation was triggered by
  10476. a server admin (and <code>False</code> otherwise). This latter <code>by_admin</code> boolean is always <code>True</code>
  10477. if the user is being reactivated, as this operation can only be performed through the
  10478. admin API.</p>
  10479. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10480. <h3 id="on_threepid_bind"><a class="header" href="#on_threepid_bind"><code>on_threepid_bind</code></a></h3>
  10481. <p><em>First introduced in Synapse v1.56.0</em></p>
  10482. <p><strong><span style="color:red">
  10483. This callback is deprecated in favour of the <code>on_add_user_third_party_identifier</code> callback, which
  10484. features the same functionality. The only difference is in name.
  10485. </span></strong></p>
  10486. <pre><code class="language-python">async def on_threepid_bind(user_id: str, medium: str, address: str) -&gt; None:
  10487. </code></pre>
  10488. <p>Called after creating an association between a local user and a third-party identifier
  10489. (email address, phone number). The module is given the Matrix ID of the user the
  10490. association is for, as well as the medium (<code>email</code> or <code>msisdn</code>) and address of the
  10491. third-party identifier.</p>
  10492. <p>Note that this callback is <em>not</em> called after a successful association on an <em>identity
  10493. server</em>.</p>
  10494. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10495. <h3 id="on_add_user_third_party_identifier"><a class="header" href="#on_add_user_third_party_identifier"><code>on_add_user_third_party_identifier</code></a></h3>
  10496. <p><em>First introduced in Synapse v1.79.0</em></p>
  10497. <pre><code class="language-python">async def on_add_user_third_party_identifier(user_id: str, medium: str, address: str) -&gt; None:
  10498. </code></pre>
  10499. <p>Called after successfully creating an association between a user and a third-party identifier
  10500. (email address, phone number). The module is given the Matrix ID of the user the
  10501. association is for, as well as the medium (<code>email</code> or <code>msisdn</code>) and address of the
  10502. third-party identifier (i.e. an email address).</p>
  10503. <p>Note that this callback is <em>not</em> called if a user attempts to bind their third-party identifier
  10504. to an identity server (via a call to <a href="https://spec.matrix.org/v1.5/client-server-api/#post_matrixclientv3account3pidbind"><code>POST /_matrix/client/v3/account/3pid/bind</code></a>).</p>
  10505. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10506. <h3 id="on_remove_user_third_party_identifier"><a class="header" href="#on_remove_user_third_party_identifier"><code>on_remove_user_third_party_identifier</code></a></h3>
  10507. <p><em>First introduced in Synapse v1.79.0</em></p>
  10508. <pre><code class="language-python">async def on_remove_user_third_party_identifier(user_id: str, medium: str, address: str) -&gt; None:
  10509. </code></pre>
  10510. <p>Called after successfully removing an association between a user and a third-party identifier
  10511. (email address, phone number). The module is given the Matrix ID of the user the
  10512. association is for, as well as the medium (<code>email</code> or <code>msisdn</code>) and address of the
  10513. third-party identifier (i.e. an email address).</p>
  10514. <p>Note that this callback is <em>not</em> called if a user attempts to unbind their third-party
  10515. identifier from an identity server (via a call to <a href="https://spec.matrix.org/v1.5/client-server-api/#post_matrixclientv3account3pidunbind"><code>POST /_matrix/client/v3/account/3pid/unbind</code></a>).</p>
  10516. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10517. <h2 id="example-1"><a class="header" href="#example-1">Example</a></h2>
  10518. <p>The example below is a module that implements the third-party rules callback
  10519. <code>check_event_allowed</code> to censor incoming messages as dictated by a third-party service.</p>
  10520. <pre><code class="language-python">from typing import Optional, Tuple
  10521. from synapse.module_api import ModuleApi
  10522. _DEFAULT_CENSOR_ENDPOINT = &quot;https://my-internal-service.local/censor-event&quot;
  10523. class EventCensorer:
  10524. def __init__(self, config: dict, api: ModuleApi):
  10525. self.api = api
  10526. self._endpoint = config.get(&quot;endpoint&quot;, _DEFAULT_CENSOR_ENDPOINT)
  10527. self.api.register_third_party_rules_callbacks(
  10528. check_event_allowed=self.check_event_allowed,
  10529. )
  10530. async def check_event_allowed(
  10531. self,
  10532. event: &quot;synapse.events.EventBase&quot;,
  10533. state_events: &quot;synapse.types.StateMap&quot;,
  10534. ) -&gt; Tuple[bool, Optional[dict]]:
  10535. event_dict = event.get_dict()
  10536. new_event_content = await self.api.http_client.post_json_get_json(
  10537. uri=self._endpoint, post_json=event_dict,
  10538. )
  10539. event_dict[&quot;content&quot;] = new_event_content
  10540. return event_dict
  10541. </code></pre>
  10542. <div style="break-before: page; page-break-before: always;"></div><h1 id="presence-router-callbacks"><a class="header" href="#presence-router-callbacks">Presence router callbacks</a></h1>
  10543. <p>Presence router callbacks allow module developers to define additional users
  10544. which receive presence updates from local users. The additional users
  10545. can be local or remote.</p>
  10546. <p>For example, it could be used to direct all of <code>@alice:example.com</code> (a local user)'s
  10547. presence updates to <code>@bob:matrix.org</code> (a remote user), even though they don't share a
  10548. room. (Note that those presence updates might not make it to <code>@bob:matrix.org</code>'s client
  10549. unless a similar presence router is running on that homeserver.)</p>
  10550. <p>Presence router callbacks can be registered using the module API's
  10551. <code>register_presence_router_callbacks</code> method.</p>
  10552. <h2 id="callbacks-2"><a class="header" href="#callbacks-2">Callbacks</a></h2>
  10553. <p>The available presence router callbacks are:</p>
  10554. <h3 id="get_users_for_states"><a class="header" href="#get_users_for_states"><code>get_users_for_states</code></a></h3>
  10555. <p><em>First introduced in Synapse v1.42.0</em></p>
  10556. <pre><code class="language-python">async def get_users_for_states(
  10557. state_updates: Iterable[&quot;synapse.api.UserPresenceState&quot;],
  10558. ) -&gt; Dict[str, Set[&quot;synapse.api.UserPresenceState&quot;]]
  10559. </code></pre>
  10560. <p><strong>Requires</strong> <code>get_interested_users</code> to also be registered</p>
  10561. <p>Called when processing updates to the presence state of one or more users. This callback can
  10562. be used to instruct the server to forward that presence state to specific users. The module
  10563. must return a dictionary that maps from Matrix user IDs (which can be local or remote) to the
  10564. <code>UserPresenceState</code> changes that they should be forwarded.</p>
  10565. <p>Synapse will then attempt to send the specified presence updates to each user when possible.</p>
  10566. <p>If multiple modules implement this callback, Synapse merges all the dictionaries returned
  10567. by the callbacks. If multiple callbacks return a dictionary containing the same key,
  10568. Synapse concatenates the sets associated with this key from each dictionary. </p>
  10569. <h3 id="get_interested_users"><a class="header" href="#get_interested_users"><code>get_interested_users</code></a></h3>
  10570. <p><em>First introduced in Synapse v1.42.0</em></p>
  10571. <pre><code class="language-python">async def get_interested_users(
  10572. user_id: str
  10573. ) -&gt; Union[Set[str], &quot;synapse.module_api.PRESENCE_ALL_USERS&quot;]
  10574. </code></pre>
  10575. <p><strong>Requires</strong> <code>get_users_for_states</code> to also be registered</p>
  10576. <p>Called when determining which users someone should be able to see the presence state of. This
  10577. callback should return complementary results to <code>get_users_for_state</code> or the presence information
  10578. may not be properly forwarded.</p>
  10579. <p>The callback is given the Matrix user ID for a local user that is requesting presence data and
  10580. should return the Matrix user IDs of the users whose presence state they are allowed to
  10581. query. The returned users can be local or remote. </p>
  10582. <p>Alternatively the callback can return <code>synapse.module_api.PRESENCE_ALL_USERS</code>
  10583. to indicate that the user should receive updates from all known users.</p>
  10584. <p>If multiple modules implement this callback, they will be considered in order. Synapse
  10585. calls each callback one by one, and use a concatenation of all the <code>set</code>s returned by the
  10586. callbacks. If one callback returns <code>synapse.module_api.PRESENCE_ALL_USERS</code>, Synapse uses
  10587. this value instead. If this happens, Synapse does not call any of the subsequent
  10588. implementations of this callback.</p>
  10589. <h2 id="example-2"><a class="header" href="#example-2">Example</a></h2>
  10590. <p>The example below is a module that implements both presence router callbacks, and ensures
  10591. that <code>@alice:example.org</code> receives all presence updates from <code>@bob:example.com</code> and
  10592. <code>@charlie:somewhere.org</code>, regardless of whether Alice shares a room with any of them.</p>
  10593. <pre><code class="language-python">from typing import Dict, Iterable, Set, Union
  10594. from synapse.module_api import ModuleApi
  10595. class CustomPresenceRouter:
  10596. def __init__(self, config: dict, api: ModuleApi):
  10597. self.api = api
  10598. self.api.register_presence_router_callbacks(
  10599. get_users_for_states=self.get_users_for_states,
  10600. get_interested_users=self.get_interested_users,
  10601. )
  10602. async def get_users_for_states(
  10603. self,
  10604. state_updates: Iterable[&quot;synapse.api.UserPresenceState&quot;],
  10605. ) -&gt; Dict[str, Set[&quot;synapse.api.UserPresenceState&quot;]]:
  10606. res = {}
  10607. for update in state_updates:
  10608. if (
  10609. update.user_id == &quot;@bob:example.com&quot;
  10610. or update.user_id == &quot;@charlie:somewhere.org&quot;
  10611. ):
  10612. res.setdefault(&quot;@alice:example.com&quot;, set()).add(update)
  10613. return res
  10614. async def get_interested_users(
  10615. self,
  10616. user_id: str,
  10617. ) -&gt; Union[Set[str], &quot;synapse.module_api.PRESENCE_ALL_USERS&quot;]:
  10618. if user_id == &quot;@alice:example.com&quot;:
  10619. return {&quot;@bob:example.com&quot;, &quot;@charlie:somewhere.org&quot;}
  10620. return set()
  10621. </code></pre>
  10622. <div style="break-before: page; page-break-before: always;"></div><h1 id="account-validity-callbacks"><a class="header" href="#account-validity-callbacks">Account validity callbacks</a></h1>
  10623. <p>Account validity callbacks allow module developers to add extra steps to verify the
  10624. validity on an account, i.e. see if a user can be granted access to their account on the
  10625. Synapse instance. Account validity callbacks can be registered using the module API's
  10626. <code>register_account_validity_callbacks</code> method.</p>
  10627. <p>The available account validity callbacks are:</p>
  10628. <h3 id="is_user_expired"><a class="header" href="#is_user_expired"><code>is_user_expired</code></a></h3>
  10629. <p><em>First introduced in Synapse v1.39.0</em></p>
  10630. <pre><code class="language-python">async def is_user_expired(user: str) -&gt; Optional[bool]
  10631. </code></pre>
  10632. <p>Called when processing any authenticated request (except for logout requests). The module
  10633. can return a <code>bool</code> to indicate whether the user has expired and should be locked out of
  10634. their account, or <code>None</code> if the module wasn't able to figure it out. The user is
  10635. represented by their Matrix user ID (e.g. <code>@alice:example.com</code>).</p>
  10636. <p>If the module returns <code>True</code>, the current request will be denied with the error code
  10637. <code>ORG_MATRIX_EXPIRED_ACCOUNT</code> and the HTTP status code 403. Note that this doesn't
  10638. invalidate the user's access token.</p>
  10639. <p>If multiple modules implement this callback, they will be considered in order. If a
  10640. callback returns <code>None</code>, Synapse falls through to the next one. The value of the first
  10641. callback that does not return <code>None</code> will be used. If this happens, Synapse will not call
  10642. any of the subsequent implementations of this callback.</p>
  10643. <h3 id="on_user_registration"><a class="header" href="#on_user_registration"><code>on_user_registration</code></a></h3>
  10644. <p><em>First introduced in Synapse v1.39.0</em></p>
  10645. <pre><code class="language-python">async def on_user_registration(user: str) -&gt; None
  10646. </code></pre>
  10647. <p>Called after successfully registering a user, in case the module needs to perform extra
  10648. operations to keep track of them. (e.g. add them to a database table). The user is
  10649. represented by their Matrix user ID.</p>
  10650. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10651. <h3 id="on_user_login"><a class="header" href="#on_user_login"><code>on_user_login</code></a></h3>
  10652. <p><em>First introduced in Synapse v1.98.0</em></p>
  10653. <pre><code class="language-python">async def on_user_login(user_id: str, auth_provider_type: str, auth_provider_id: str) -&gt; None
  10654. </code></pre>
  10655. <p>Called after successfully login or registration of a user for cases when module needs to perform extra operations after auth.
  10656. represented by their Matrix user ID.</p>
  10657. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10658. <div style="break-before: page; page-break-before: always;"></div><h1 id="password-auth-provider-callbacks"><a class="header" href="#password-auth-provider-callbacks">Password auth provider callbacks</a></h1>
  10659. <p>Password auth providers offer a way for server administrators to integrate
  10660. their Synapse installation with an external authentication system. The callbacks can be
  10661. registered by using the Module API's <code>register_password_auth_provider_callbacks</code> method.</p>
  10662. <h2 id="callbacks-3"><a class="header" href="#callbacks-3">Callbacks</a></h2>
  10663. <h3 id="auth_checkers"><a class="header" href="#auth_checkers"><code>auth_checkers</code></a></h3>
  10664. <p><em>First introduced in Synapse v1.46.0</em></p>
  10665. <pre><code class="language-python">auth_checkers: Dict[Tuple[str, Tuple[str, ...]], Callable]
  10666. </code></pre>
  10667. <p>A dict mapping from tuples of a login type identifier (such as <code>m.login.password</code>) and a
  10668. tuple of field names (such as <code>(&quot;password&quot;, &quot;secret_thing&quot;)</code>) to authentication checking
  10669. callbacks, which should be of the following form:</p>
  10670. <pre><code class="language-python">async def check_auth(
  10671. user: str,
  10672. login_type: str,
  10673. login_dict: &quot;synapse.module_api.JsonDict&quot;,
  10674. ) -&gt; Optional[
  10675. Tuple[
  10676. str,
  10677. Optional[Callable[[&quot;synapse.module_api.LoginResponse&quot;], Awaitable[None]]]
  10678. ]
  10679. ]
  10680. </code></pre>
  10681. <p>The login type and field names should be provided by the user in the
  10682. request to the <code>/login</code> API. <a href="https://matrix.org/docs/spec/client_server/latest#authentication-types">The Matrix specification</a>
  10683. defines some types, however user defined ones are also allowed.</p>
  10684. <p>The callback is passed the <code>user</code> field provided by the client (which might not be in
  10685. <code>@username:server</code> form), the login type, and a dictionary of login secrets passed by
  10686. the client.</p>
  10687. <p>If the authentication is successful, the module must return the user's Matrix ID (e.g.
  10688. <code>@alice:example.com</code>) and optionally a callback to be called with the response to the
  10689. <code>/login</code> request. If the module doesn't wish to return a callback, it must return <code>None</code>
  10690. instead.</p>
  10691. <p>If the authentication is unsuccessful, the module must return <code>None</code>.</p>
  10692. <p>Note that the user is not automatically registered, the <code>register_user(..)</code> method of
  10693. the <a href="modules/writing_a_module.html">module API</a> can be used to lazily create users.</p>
  10694. <p>If multiple modules register an auth checker for the same login type but with different
  10695. fields, Synapse will refuse to start.</p>
  10696. <p>If multiple modules register an auth checker for the same login type with the same fields,
  10697. then the callbacks will be executed in order, until one returns a Matrix User ID (and
  10698. optionally a callback). In that case, the return value of that callback will be accepted
  10699. and subsequent callbacks will not be fired. If every callback returns <code>None</code>, then the
  10700. authentication fails.</p>
  10701. <h3 id="check_3pid_auth"><a class="header" href="#check_3pid_auth"><code>check_3pid_auth</code></a></h3>
  10702. <p><em>First introduced in Synapse v1.46.0</em></p>
  10703. <pre><code class="language-python">async def check_3pid_auth(
  10704. medium: str,
  10705. address: str,
  10706. password: str,
  10707. ) -&gt; Optional[
  10708. Tuple[
  10709. str,
  10710. Optional[Callable[[&quot;synapse.module_api.LoginResponse&quot;], Awaitable[None]]]
  10711. ]
  10712. ]
  10713. </code></pre>
  10714. <p>Called when a user attempts to register or log in with a third party identifier,
  10715. such as email. It is passed the medium (eg. <code>email</code>), an address (eg. <code>jdoe@example.com</code>)
  10716. and the user's password.</p>
  10717. <p>If the authentication is successful, the module must return the user's Matrix ID (e.g.
  10718. <code>@alice:example.com</code>) and optionally a callback to be called with the response to the <code>/login</code> request.
  10719. If the module doesn't wish to return a callback, it must return None instead.</p>
  10720. <p>If the authentication is unsuccessful, the module must return <code>None</code>.</p>
  10721. <p>If multiple modules implement this callback, they will be considered in order. If a
  10722. callback returns <code>None</code>, Synapse falls through to the next one. The value of the first
  10723. callback that does not return <code>None</code> will be used. If this happens, Synapse will not call
  10724. any of the subsequent implementations of this callback. If every callback returns <code>None</code>,
  10725. the authentication is denied.</p>
  10726. <h3 id="on_logged_out"><a class="header" href="#on_logged_out"><code>on_logged_out</code></a></h3>
  10727. <p><em>First introduced in Synapse v1.46.0</em></p>
  10728. <pre><code class="language-python">async def on_logged_out(
  10729. user_id: str,
  10730. device_id: Optional[str],
  10731. access_token: str
  10732. ) -&gt; None
  10733. </code></pre>
  10734. <p>Called during a logout request for a user. It is passed the qualified user ID, the ID of the
  10735. deactivated device (if any: access tokens are occasionally created without an associated
  10736. device ID), and the (now deactivated) access token.</p>
  10737. <p>Deleting the related pushers is done after calling <code>on_logged_out</code>, so you can rely on them
  10738. to still be present.</p>
  10739. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10740. <h3 id="get_username_for_registration"><a class="header" href="#get_username_for_registration"><code>get_username_for_registration</code></a></h3>
  10741. <p><em>First introduced in Synapse v1.52.0</em></p>
  10742. <pre><code class="language-python">async def get_username_for_registration(
  10743. uia_results: Dict[str, Any],
  10744. params: Dict[str, Any],
  10745. ) -&gt; Optional[str]
  10746. </code></pre>
  10747. <p>Called when registering a new user. The module can return a username to set for the user
  10748. being registered by returning it as a string, or <code>None</code> if it doesn't wish to force a
  10749. username for this user. If a username is returned, it will be used as the local part of a
  10750. user's full Matrix ID (e.g. it's <code>alice</code> in <code>@alice:example.com</code>).</p>
  10751. <p>This callback is called once <a href="https://spec.matrix.org/latest/client-server-api/#user-interactive-authentication-api">User-Interactive Authentication</a>
  10752. has been completed by the user. It is not called when registering a user via SSO. It is
  10753. passed two dictionaries, which include the information that the user has provided during
  10754. the registration process.</p>
  10755. <p>The first dictionary contains the results of the <a href="https://spec.matrix.org/latest/client-server-api/#user-interactive-authentication-api">User-Interactive Authentication</a>
  10756. flow followed by the user. Its keys are the identifiers of every step involved in the flow,
  10757. associated with either a boolean value indicating whether the step was correctly completed,
  10758. or additional information (e.g. email address, phone number...). A list of most existing
  10759. identifiers can be found in the <a href="https://spec.matrix.org/v1.1/client-server-api/#authentication-types">Matrix specification</a>.
  10760. Here's an example featuring all currently supported keys:</p>
  10761. <pre><code class="language-python">{
  10762. &quot;m.login.dummy&quot;: True, # Dummy authentication
  10763. &quot;m.login.terms&quot;: True, # User has accepted the terms of service for the homeserver
  10764. &quot;m.login.recaptcha&quot;: True, # User has completed the recaptcha challenge
  10765. &quot;m.login.email.identity&quot;: { # User has provided and verified an email address
  10766. &quot;medium&quot;: &quot;email&quot;,
  10767. &quot;address&quot;: &quot;alice@example.com&quot;,
  10768. &quot;validated_at&quot;: 1642701357084,
  10769. },
  10770. &quot;m.login.msisdn&quot;: { # User has provided and verified a phone number
  10771. &quot;medium&quot;: &quot;msisdn&quot;,
  10772. &quot;address&quot;: &quot;33123456789&quot;,
  10773. &quot;validated_at&quot;: 1642701357084,
  10774. },
  10775. &quot;m.login.registration_token&quot;: &quot;sometoken&quot;, # User has registered through a registration token
  10776. }
  10777. </code></pre>
  10778. <p>The second dictionary contains the parameters provided by the user's client in the request
  10779. to <code>/_matrix/client/v3/register</code>. See the <a href="https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3register">Matrix specification</a>
  10780. for a complete list of these parameters.</p>
  10781. <p>If the module cannot, or does not wish to, generate a username for this user, it must
  10782. return <code>None</code>.</p>
  10783. <p>If multiple modules implement this callback, they will be considered in order. If a
  10784. callback returns <code>None</code>, Synapse falls through to the next one. The value of the first
  10785. callback that does not return <code>None</code> will be used. If this happens, Synapse will not call
  10786. any of the subsequent implementations of this callback. If every callback returns <code>None</code>,
  10787. the username provided by the user is used, if any (otherwise one is automatically
  10788. generated).</p>
  10789. <h3 id="get_displayname_for_registration"><a class="header" href="#get_displayname_for_registration"><code>get_displayname_for_registration</code></a></h3>
  10790. <p><em>First introduced in Synapse v1.54.0</em></p>
  10791. <pre><code class="language-python">async def get_displayname_for_registration(
  10792. uia_results: Dict[str, Any],
  10793. params: Dict[str, Any],
  10794. ) -&gt; Optional[str]
  10795. </code></pre>
  10796. <p>Called when registering a new user. The module can return a display name to set for the
  10797. user being registered by returning it as a string, or <code>None</code> if it doesn't wish to force a
  10798. display name for this user.</p>
  10799. <p>This callback is called once <a href="https://spec.matrix.org/latest/client-server-api/#user-interactive-authentication-api">User-Interactive Authentication</a>
  10800. has been completed by the user. It is not called when registering a user via SSO. It is
  10801. passed two dictionaries, which include the information that the user has provided during
  10802. the registration process. These dictionaries are identical to the ones passed to
  10803. <a href="modules/password_auth_provider_callbacks.html#get_username_for_registration"><code>get_username_for_registration</code></a>, so refer to the
  10804. documentation of this callback for more information about them.</p>
  10805. <p>If multiple modules implement this callback, they will be considered in order. If a
  10806. callback returns <code>None</code>, Synapse falls through to the next one. The value of the first
  10807. callback that does not return <code>None</code> will be used. If this happens, Synapse will not call
  10808. any of the subsequent implementations of this callback. If every callback returns <code>None</code>,
  10809. the username will be used (e.g. <code>alice</code> if the user being registered is <code>@alice:example.com</code>).</p>
  10810. <h2 id="is_3pid_allowed"><a class="header" href="#is_3pid_allowed"><code>is_3pid_allowed</code></a></h2>
  10811. <p><em>First introduced in Synapse v1.53.0</em></p>
  10812. <pre><code class="language-python">async def is_3pid_allowed(self, medium: str, address: str, registration: bool) -&gt; bool
  10813. </code></pre>
  10814. <p>Called when attempting to bind a third-party identifier (i.e. an email address or a phone
  10815. number). The module is given the medium of the third-party identifier (which is <code>email</code> if
  10816. the identifier is an email address, or <code>msisdn</code> if the identifier is a phone number) and
  10817. its address, as well as a boolean indicating whether the attempt to bind is happening as
  10818. part of registering a new user. The module must return a boolean indicating whether the
  10819. identifier can be allowed to be bound to an account on the local homeserver.</p>
  10820. <p>If multiple modules implement this callback, they will be considered in order. If a
  10821. callback returns <code>True</code>, Synapse falls through to the next one. The value of the first
  10822. callback that does not return <code>True</code> will be used. If this happens, Synapse will not call
  10823. any of the subsequent implementations of this callback.</p>
  10824. <h2 id="example-3"><a class="header" href="#example-3">Example</a></h2>
  10825. <p>The example module below implements authentication checkers for two different login types: </p>
  10826. <ul>
  10827. <li><code>my.login.type</code>
  10828. <ul>
  10829. <li>Expects a <code>my_field</code> field to be sent to <code>/login</code></li>
  10830. <li>Is checked by the method: <code>self.check_my_login</code></li>
  10831. </ul>
  10832. </li>
  10833. <li><code>m.login.password</code> (defined in <a href="https://matrix.org/docs/spec/client_server/latest#password-based">the spec</a>)
  10834. <ul>
  10835. <li>Expects a <code>password</code> field to be sent to <code>/login</code></li>
  10836. <li>Is checked by the method: <code>self.check_pass</code></li>
  10837. </ul>
  10838. </li>
  10839. </ul>
  10840. <pre><code class="language-python">from typing import Awaitable, Callable, Optional, Tuple
  10841. import synapse
  10842. from synapse import module_api
  10843. class MyAuthProvider:
  10844. def __init__(self, config: dict, api: module_api):
  10845. self.api = api
  10846. self.credentials = {
  10847. &quot;bob&quot;: &quot;building&quot;,
  10848. &quot;@scoop:matrix.org&quot;: &quot;digging&quot;,
  10849. }
  10850. api.register_password_auth_provider_callbacks(
  10851. auth_checkers={
  10852. (&quot;my.login_type&quot;, (&quot;my_field&quot;,)): self.check_my_login,
  10853. (&quot;m.login.password&quot;, (&quot;password&quot;,)): self.check_pass,
  10854. },
  10855. )
  10856. async def check_my_login(
  10857. self,
  10858. username: str,
  10859. login_type: str,
  10860. login_dict: &quot;synapse.module_api.JsonDict&quot;,
  10861. ) -&gt; Optional[
  10862. Tuple[
  10863. str,
  10864. Optional[Callable[[&quot;synapse.module_api.LoginResponse&quot;], Awaitable[None]]],
  10865. ]
  10866. ]:
  10867. if login_type != &quot;my.login_type&quot;:
  10868. return None
  10869. if self.credentials.get(username) == login_dict.get(&quot;my_field&quot;):
  10870. return (self.api.get_qualified_user_id(username), None)
  10871. async def check_pass(
  10872. self,
  10873. username: str,
  10874. login_type: str,
  10875. login_dict: &quot;synapse.module_api.JsonDict&quot;,
  10876. ) -&gt; Optional[
  10877. Tuple[
  10878. str,
  10879. Optional[Callable[[&quot;synapse.module_api.LoginResponse&quot;], Awaitable[None]]],
  10880. ]
  10881. ]:
  10882. if login_type != &quot;m.login.password&quot;:
  10883. return None
  10884. if self.credentials.get(username) == login_dict.get(&quot;password&quot;):
  10885. return (self.api.get_qualified_user_id(username), None)
  10886. </code></pre>
  10887. <div style="break-before: page; page-break-before: always;"></div><h1 id="background-update-controller-callbacks"><a class="header" href="#background-update-controller-callbacks">Background update controller callbacks</a></h1>
  10888. <p>Background update controller callbacks allow module developers to control (e.g. rate-limit)
  10889. how database background updates are run. A database background update is an operation
  10890. Synapse runs on its database in the background after it starts. It's usually used to run
  10891. database operations that would take too long if they were run at the same time as schema
  10892. updates (which are run on startup) and delay Synapse's startup too much: populating a
  10893. table with a big amount of data, adding an index on a big table, deleting superfluous data,
  10894. etc.</p>
  10895. <p>Background update controller callbacks can be registered using the module API's
  10896. <code>register_background_update_controller_callbacks</code> method. Only the first module (in order
  10897. of appearance in Synapse's configuration file) calling this method can register background
  10898. update controller callbacks, subsequent calls are ignored.</p>
  10899. <p>The available background update controller callbacks are:</p>
  10900. <h3 id="on_update"><a class="header" href="#on_update"><code>on_update</code></a></h3>
  10901. <p><em>First introduced in Synapse v1.49.0</em></p>
  10902. <pre><code class="language-python">def on_update(update_name: str, database_name: str, one_shot: bool) -&gt; AsyncContextManager[int]
  10903. </code></pre>
  10904. <p>Called when about to do an iteration of a background update. The module is given the name
  10905. of the update, the name of the database, and a flag to indicate whether the background
  10906. update will happen in one go and may take a long time (e.g. creating indices). If this last
  10907. argument is set to <code>False</code>, the update will be run in batches.</p>
  10908. <p>The module must return an async context manager. It will be entered before Synapse runs a
  10909. background update; this should return the desired duration of the iteration, in
  10910. milliseconds.</p>
  10911. <p>The context manager will be exited when the iteration completes. Note that the duration
  10912. returned by the context manager is a target, and an iteration may take substantially longer
  10913. or shorter. If the <code>one_shot</code> flag is set to <code>True</code>, the duration returned is ignored.</p>
  10914. <p><strong>Note</strong>: Unlike most module callbacks in Synapse, this one is <em>synchronous</em>. This is
  10915. because asynchronous operations are expected to be run by the async context manager.</p>
  10916. <p>This callback is required when registering any other background update controller callback.</p>
  10917. <h3 id="default_batch_size"><a class="header" href="#default_batch_size"><code>default_batch_size</code></a></h3>
  10918. <p><em>First introduced in Synapse v1.49.0</em></p>
  10919. <pre><code class="language-python">async def default_batch_size(update_name: str, database_name: str) -&gt; int
  10920. </code></pre>
  10921. <p>Called before the first iteration of a background update, with the name of the update and
  10922. of the database. The module must return the number of elements to process in this first
  10923. iteration.</p>
  10924. <p>If this callback is not defined, Synapse will use a default value of 100.</p>
  10925. <h3 id="min_batch_size"><a class="header" href="#min_batch_size"><code>min_batch_size</code></a></h3>
  10926. <p><em>First introduced in Synapse v1.49.0</em></p>
  10927. <pre><code class="language-python">async def min_batch_size(update_name: str, database_name: str) -&gt; int
  10928. </code></pre>
  10929. <p>Called before running a new batch for a background update, with the name of the update and
  10930. of the database. The module must return an integer representing the minimum number of
  10931. elements to process in this iteration. This number must be at least 1, and is used to
  10932. ensure that progress is always made.</p>
  10933. <p>If this callback is not defined, Synapse will use a default value of 100.</p>
  10934. <div style="break-before: page; page-break-before: always;"></div><h1 id="account-data-callbacks"><a class="header" href="#account-data-callbacks">Account data callbacks</a></h1>
  10935. <p>Account data callbacks allow module developers to react to changes of the account data
  10936. of local users. Account data callbacks can be registered using the module API's
  10937. <code>register_account_data_callbacks</code> method.</p>
  10938. <h2 id="callbacks-4"><a class="header" href="#callbacks-4">Callbacks</a></h2>
  10939. <p>The available account data callbacks are:</p>
  10940. <h3 id="on_account_data_updated"><a class="header" href="#on_account_data_updated"><code>on_account_data_updated</code></a></h3>
  10941. <p><em>First introduced in Synapse v1.57.0</em></p>
  10942. <pre><code class="language-python">async def on_account_data_updated(
  10943. user_id: str,
  10944. room_id: Optional[str],
  10945. account_data_type: str,
  10946. content: &quot;synapse.module_api.JsonDict&quot;,
  10947. ) -&gt; None:
  10948. </code></pre>
  10949. <p>Called after user's account data has been updated. The module is given the
  10950. Matrix ID of the user whose account data is changing, the room ID the data is associated
  10951. with, the type associated with the change, as well as the new content. If the account
  10952. data is not associated with a specific room, then the room ID is <code>None</code>.</p>
  10953. <p>This callback is triggered when new account data is added or when the data associated with
  10954. a given type (and optionally room) changes. This includes deletion, since in Matrix,
  10955. deleting account data consists of replacing the data associated with a given type
  10956. (and optionally room) with an empty dictionary (<code>{}</code>).</p>
  10957. <p>Note that this doesn't trigger when changing the tags associated with a room, as these are
  10958. processed separately by Synapse.</p>
  10959. <p>If multiple modules implement this callback, Synapse runs them all in order.</p>
  10960. <h2 id="example-4"><a class="header" href="#example-4">Example</a></h2>
  10961. <p>The example below is a module that implements the <code>on_account_data_updated</code> callback, and
  10962. sends an event to an audit room when a user changes their account data.</p>
  10963. <pre><code class="language-python">import json
  10964. import attr
  10965. from typing import Any, Dict, Optional
  10966. from synapse.module_api import JsonDict, ModuleApi
  10967. from synapse.module_api.errors import ConfigError
  10968. @attr.s(auto_attribs=True)
  10969. class CustomAccountDataConfig:
  10970. audit_room: str
  10971. sender: str
  10972. class CustomAccountDataModule:
  10973. def __init__(self, config: CustomAccountDataConfig, api: ModuleApi):
  10974. self.api = api
  10975. self.config = config
  10976. self.api.register_account_data_callbacks(
  10977. on_account_data_updated=self.log_new_account_data,
  10978. )
  10979. @staticmethod
  10980. def parse_config(config: Dict[str, Any]) -&gt; CustomAccountDataConfig:
  10981. def check_in_config(param: str):
  10982. if param not in config:
  10983. raise ConfigError(f&quot;'{param}' is required&quot;)
  10984. check_in_config(&quot;audit_room&quot;)
  10985. check_in_config(&quot;sender&quot;)
  10986. return CustomAccountDataConfig(
  10987. audit_room=config[&quot;audit_room&quot;],
  10988. sender=config[&quot;sender&quot;],
  10989. )
  10990. async def log_new_account_data(
  10991. self,
  10992. user_id: str,
  10993. room_id: Optional[str],
  10994. account_data_type: str,
  10995. content: JsonDict,
  10996. ) -&gt; None:
  10997. content_raw = json.dumps(content)
  10998. msg_content = f&quot;{user_id} has changed their account data for type {account_data_type} to: {content_raw}&quot;
  10999. if room_id is not None:
  11000. msg_content += f&quot; (in room {room_id})&quot;
  11001. await self.api.create_and_send_event_into_room(
  11002. {
  11003. &quot;room_id&quot;: self.config.audit_room,
  11004. &quot;sender&quot;: self.config.sender,
  11005. &quot;type&quot;: &quot;m.room.message&quot;,
  11006. &quot;content&quot;: {
  11007. &quot;msgtype&quot;: &quot;m.text&quot;,
  11008. &quot;body&quot;: msg_content
  11009. }
  11010. }
  11011. )
  11012. </code></pre>
  11013. <div style="break-before: page; page-break-before: always;"></div><h1 id="add-extra-fields-to-client-events-unsigned-section-callbacks"><a class="header" href="#add-extra-fields-to-client-events-unsigned-section-callbacks">Add extra fields to client events unsigned section callbacks</a></h1>
  11014. <p><em>First introduced in Synapse v1.96.0</em></p>
  11015. <p>This callback allows modules to add extra fields to the unsigned section of
  11016. events when they get sent down to clients.</p>
  11017. <p>These get called <em>every</em> time an event is to be sent to clients, so care should
  11018. be taken to ensure with respect to performance.</p>
  11019. <h3 id="api"><a class="header" href="#api">API</a></h3>
  11020. <p>To register the callback, use
  11021. <code>register_add_extra_fields_to_unsigned_client_event_callbacks</code> on the
  11022. <code>ModuleApi</code>.</p>
  11023. <p>The callback should be of the form</p>
  11024. <pre><code class="language-python">async def add_field_to_unsigned(
  11025. event: EventBase,
  11026. ) -&gt; JsonDict:
  11027. </code></pre>
  11028. <p>where the extra fields to add to the event's unsigned section is returned.
  11029. (Modules must not attempt to modify the <code>event</code> directly).</p>
  11030. <p>This cannot be used to alter the &quot;core&quot; fields in the unsigned section emitted
  11031. by Synapse itself.</p>
  11032. <p>If multiple such callbacks try to add the same field to an event's unsigned
  11033. section, the last-registered callback wins.</p>
  11034. <div style="break-before: page; page-break-before: always;"></div><h1 id="porting-an-existing-module-that-uses-the-old-interface"><a class="header" href="#porting-an-existing-module-that-uses-the-old-interface">Porting an existing module that uses the old interface</a></h1>
  11035. <p>In order to port a module that uses Synapse's old module interface, its author needs to:</p>
  11036. <ul>
  11037. <li>ensure the module's callbacks are all asynchronous.</li>
  11038. <li>register their callbacks using one or more of the <code>register_[...]_callbacks</code> methods
  11039. from the <code>ModuleApi</code> class in the module's <code>__init__</code> method (see <a href="modules/writing_a_module.html#registering-a-callback">this section</a>
  11040. for more info).</li>
  11041. </ul>
  11042. <p>Additionally, if the module is packaged with an additional web resource, the module
  11043. should register this resource in its <code>__init__</code> method using the <code>register_web_resource</code>
  11044. method from the <code>ModuleApi</code> class (see <a href="modules/writing_a_module.html#registering-a-web-resource">this section</a> for
  11045. more info).</p>
  11046. <p>There is no longer a <code>get_db_schema_files</code> callback provided for password auth provider modules. Any
  11047. changes to the database should now be made by the module using the module API class.</p>
  11048. <p>The module's author should also update any example in the module's configuration to only
  11049. use the new <code>modules</code> section in Synapse's configuration file (see <a href="modules/index.html#using-modules">this section</a>
  11050. for more info).</p>
  11051. <div style="break-before: page; page-break-before: always;"></div><h1 id="scaling-synapse-via-workers"><a class="header" href="#scaling-synapse-via-workers">Scaling synapse via workers</a></h1>
  11052. <p>For small instances it is recommended to run Synapse in the default monolith mode.
  11053. For larger instances where performance is a concern it can be helpful to split
  11054. out functionality into multiple separate python processes. These processes are
  11055. called 'workers', and are (eventually) intended to scale horizontally
  11056. independently.</p>
  11057. <p>Synapse's worker support is under active development and subject to change as
  11058. we attempt to rapidly scale ever larger Synapse instances. However we are
  11059. documenting it here to help admins needing a highly scalable Synapse instance
  11060. similar to the one running <code>matrix.org</code>.</p>
  11061. <p>All processes continue to share the same database instance, and as such,
  11062. workers only work with PostgreSQL-based Synapse deployments. SQLite should only
  11063. be used for demo purposes and any admin considering workers should already be
  11064. running PostgreSQL.</p>
  11065. <p>See also <a href="https://matrix.org/blog/2020/11/03/how-we-fixed-synapses-scalability">Matrix.org blog post</a>
  11066. for a higher level overview.</p>
  11067. <h2 id="main-processworker-communication"><a class="header" href="#main-processworker-communication">Main process/worker communication</a></h2>
  11068. <p>The processes communicate with each other via a Synapse-specific protocol called
  11069. 'replication' (analogous to MySQL- or Postgres-style database replication) which
  11070. feeds streams of newly written data between processes so they can be kept in
  11071. sync with the database state.</p>
  11072. <p>When configured to do so, Synapse uses a
  11073. <a href="https://redis.io/docs/manual/pubsub/">Redis pub/sub channel</a> to send the replication
  11074. stream between all configured Synapse processes. Additionally, processes may
  11075. make HTTP requests to each other, primarily for operations which need to wait
  11076. for a reply ─ such as sending an event.</p>
  11077. <p>All the workers and the main process connect to Redis, which relays replication
  11078. commands between processes.</p>
  11079. <p>If Redis support is enabled Synapse will use it as a shared cache, as well as a
  11080. pub/sub mechanism.</p>
  11081. <p>See the <a href="workers.html#architectural-diagram">Architectural diagram</a> section at the end for
  11082. a visualisation of what this looks like.</p>
  11083. <h2 id="setting-up-workers"><a class="header" href="#setting-up-workers">Setting up workers</a></h2>
  11084. <p>A Redis server is required to manage the communication between the processes.
  11085. The Redis server should be installed following the normal procedure for your
  11086. distribution (e.g. <code>apt install redis-server</code> on Debian). It is safe to use an
  11087. existing Redis deployment if you have one.</p>
  11088. <p>Once installed, check that Redis is running and accessible from the host running
  11089. Synapse, for example by executing <code>echo PING | nc -q1 localhost 6379</code> and seeing
  11090. a response of <code>+PONG</code>.</p>
  11091. <p>The appropriate dependencies must also be installed for Synapse. If using a
  11092. virtualenv, these can be installed with:</p>
  11093. <pre><code class="language-sh">pip install &quot;matrix-synapse[redis]&quot;
  11094. </code></pre>
  11095. <p>Note that these dependencies are included when synapse is installed with <code>pip install matrix-synapse[all]</code>. They are also included in the debian packages from
  11096. <code>matrix.org</code> and in the docker images at
  11097. https://hub.docker.com/r/matrixdotorg/synapse/.</p>
  11098. <p>To make effective use of the workers, you will need to configure an HTTP
  11099. reverse-proxy such as nginx or haproxy, which will direct incoming requests to
  11100. the correct worker, or to the main synapse instance. See
  11101. <a href="reverse_proxy.html">the reverse proxy documentation</a> for information on setting up a reverse
  11102. proxy.</p>
  11103. <p>When using workers, each worker process has its own configuration file which
  11104. contains settings specific to that worker, such as the HTTP listener that it
  11105. provides (if any), logging configuration, etc.</p>
  11106. <p>Normally, the worker processes are configured to read from a shared
  11107. configuration file as well as the worker-specific configuration files. This
  11108. makes it easier to keep common configuration settings synchronised across all
  11109. the processes.</p>
  11110. <p>The main process is somewhat special in this respect: it does not normally
  11111. need its own configuration file and can take all of its configuration from the
  11112. shared configuration file.</p>
  11113. <h3 id="shared-configuration"><a class="header" href="#shared-configuration">Shared configuration</a></h3>
  11114. <p>Normally, only a few changes are needed to make an existing configuration
  11115. file suitable for use with workers:</p>
  11116. <ul>
  11117. <li>First, you need to enable an
  11118. <a href="usage/configuration/config_documentation.html#listeners">&quot;HTTP replication listener&quot;</a>
  11119. for the main process</li>
  11120. <li>Secondly, you need to enable
  11121. <a href="usage/configuration/config_documentation.html#redis">redis-based replication</a></li>
  11122. <li>You will need to add an <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a>
  11123. with the <code>main</code> process defined, as well as the relevant connection information from
  11124. it's HTTP <code>replication</code> listener (defined in step 1 above).
  11125. <ul>
  11126. <li>Note that the <code>host</code> defined is the address the worker needs to look for the <code>main</code>
  11127. process at, not necessarily the same address that is bound to.</li>
  11128. <li>If you are using Unix sockets for the <code>replication</code> resource, make sure to
  11129. use a <code>path</code> to the socket file instead of a <code>port</code>.</li>
  11130. </ul>
  11131. </li>
  11132. <li>Optionally, a <a href="usage/configuration/config_documentation.html#worker_replication_secret">shared secret</a>
  11133. can be used to authenticate HTTP traffic between workers. For example:</li>
  11134. </ul>
  11135. <pre><code class="language-yaml"># extend the existing `listeners` section. This defines the ports that the
  11136. # main process will listen on.
  11137. listeners:
  11138. # The HTTP replication port
  11139. - port: 9093
  11140. bind_address: '127.0.0.1'
  11141. type: http
  11142. resources:
  11143. - names: [replication]
  11144. # Add a random shared secret to authenticate traffic.
  11145. worker_replication_secret: &quot;&quot;
  11146. redis:
  11147. enabled: true
  11148. instance_map:
  11149. main:
  11150. host: 'localhost'
  11151. port: 9093
  11152. </code></pre>
  11153. <p>See the <a href="usage/configuration/config_documentation.html">configuration manual</a>
  11154. for the full documentation of each option.</p>
  11155. <p>Under <strong>no circumstances</strong> should the replication listener be exposed to the
  11156. public internet; replication traffic is:</p>
  11157. <ul>
  11158. <li>always unencrypted</li>
  11159. <li>unauthenticated, unless <a href="usage/configuration/config_documentation.html#worker_replication_secret"><code>worker_replication_secret</code></a>
  11160. is configured</li>
  11161. </ul>
  11162. <h3 id="worker-configuration"><a class="header" href="#worker-configuration">Worker configuration</a></h3>
  11163. <p>In the config file for each worker, you must specify:</p>
  11164. <ul>
  11165. <li>The type of worker (<a href="usage/configuration/config_documentation.html#worker_app"><code>worker_app</code></a>).
  11166. The currently available worker applications are listed <a href="workers.html#available-worker-applications">below</a>.</li>
  11167. <li>A unique name for the worker (<a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a>).</li>
  11168. <li>If handling HTTP requests, a <a href="usage/configuration/config_documentation.html#worker_listeners"><code>worker_listeners</code></a> option
  11169. with an <code>http</code> listener.</li>
  11170. <li><strong>Synapse 1.72 and older:</strong> if handling the <code>^/_matrix/client/v3/keys/upload</code> endpoint, the HTTP URI for
  11171. the main process (<code>worker_main_http_uri</code>). This config option is no longer required and is ignored when running Synapse 1.73 and newer.</li>
  11172. </ul>
  11173. <p>For example:</p>
  11174. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  11175. worker_name: generic_worker1
  11176. worker_listeners:
  11177. - type: http
  11178. port: 8083
  11179. x_forwarded: true
  11180. resources:
  11181. - names: [client, federation]
  11182. worker_log_config: /etc/matrix-synapse/generic-worker-log.yaml
  11183. </code></pre>
  11184. <p>...is a full configuration for a generic worker instance, which will expose a
  11185. plain HTTP endpoint on port 8083 separately serving various endpoints, e.g.
  11186. <code>/sync</code>, which are listed below.</p>
  11187. <p>Obviously you should configure your reverse-proxy to route the relevant
  11188. endpoints to the worker (<code>localhost:8083</code> in the above example).</p>
  11189. <h3 id="running-synapse-with-workers"><a class="header" href="#running-synapse-with-workers">Running Synapse with workers</a></h3>
  11190. <p>Finally, you need to start your worker processes. This can be done with either
  11191. <code>synctl</code> or your distribution's preferred service manager such as <code>systemd</code>. We
  11192. recommend the use of <code>systemd</code> where available: for information on setting up
  11193. <code>systemd</code> to start synapse workers, see
  11194. <a href="systemd-with-workers/">Systemd with Workers</a>. To use <code>synctl</code>, see
  11195. <a href="synctl_workers.html">Using synctl with Workers</a>.</p>
  11196. <h2 id="start-synapse-with-poetry"><a class="header" href="#start-synapse-with-poetry">Start Synapse with Poetry</a></h2>
  11197. <p>The following applies to Synapse installations that have been installed from source using <code>poetry</code>.</p>
  11198. <p>You can start the main Synapse process with Poetry by running the following command:</p>
  11199. <pre><code class="language-console">poetry run synapse_homeserver --config-file [your homeserver.yaml]
  11200. </code></pre>
  11201. <p>For worker setups, you can run the following command</p>
  11202. <pre><code class="language-console">poetry run synapse_worker --config-file [your homeserver.yaml] --config-file [your worker.yaml]
  11203. </code></pre>
  11204. <h2 id="available-worker-applications"><a class="header" href="#available-worker-applications">Available worker applications</a></h2>
  11205. <h3 id="synapseappgeneric_worker"><a class="header" href="#synapseappgeneric_worker"><code>synapse.app.generic_worker</code></a></h3>
  11206. <p>This worker can handle API requests matching the following regular expressions.
  11207. These endpoints can be routed to any worker. If a worker is set up to handle a
  11208. stream then, for maximum efficiency, additional endpoints should be routed to that
  11209. worker: refer to the <a href="workers.html#stream-writers">stream writers</a> section below for further
  11210. information.</p>
  11211. <pre><code># Sync requests
  11212. ^/_matrix/client/(r0|v3)/sync$
  11213. ^/_matrix/client/(api/v1|r0|v3)/events$
  11214. ^/_matrix/client/(api/v1|r0|v3)/initialSync$
  11215. ^/_matrix/client/(api/v1|r0|v3)/rooms/[^/]+/initialSync$
  11216. # Federation requests
  11217. ^/_matrix/federation/v1/event/
  11218. ^/_matrix/federation/v1/state/
  11219. ^/_matrix/federation/v1/state_ids/
  11220. ^/_matrix/federation/v1/backfill/
  11221. ^/_matrix/federation/v1/get_missing_events/
  11222. ^/_matrix/federation/v1/publicRooms
  11223. ^/_matrix/federation/v1/query/
  11224. ^/_matrix/federation/v1/make_join/
  11225. ^/_matrix/federation/v1/make_leave/
  11226. ^/_matrix/federation/(v1|v2)/send_join/
  11227. ^/_matrix/federation/(v1|v2)/send_leave/
  11228. ^/_matrix/federation/(v1|v2)/invite/
  11229. ^/_matrix/federation/v1/event_auth/
  11230. ^/_matrix/federation/v1/timestamp_to_event/
  11231. ^/_matrix/federation/v1/exchange_third_party_invite/
  11232. ^/_matrix/federation/v1/user/devices/
  11233. ^/_matrix/key/v2/query
  11234. ^/_matrix/federation/v1/hierarchy/
  11235. # Inbound federation transaction request
  11236. ^/_matrix/federation/v1/send/
  11237. # Client API requests
  11238. ^/_matrix/client/(api/v1|r0|v3|unstable)/createRoom$
  11239. ^/_matrix/client/(api/v1|r0|v3|unstable)/publicRooms$
  11240. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/joined_members$
  11241. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/context/.*$
  11242. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/members$
  11243. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/state$
  11244. ^/_matrix/client/v1/rooms/.*/hierarchy$
  11245. ^/_matrix/client/(v1|unstable)/rooms/.*/relations/
  11246. ^/_matrix/client/v1/rooms/.*/threads$
  11247. ^/_matrix/client/unstable/im.nheko.summary/rooms/.*/summary$
  11248. ^/_matrix/client/(r0|v3|unstable)/account/3pid$
  11249. ^/_matrix/client/(r0|v3|unstable)/account/whoami$
  11250. ^/_matrix/client/(r0|v3|unstable)/devices$
  11251. ^/_matrix/client/versions$
  11252. ^/_matrix/client/(api/v1|r0|v3|unstable)/voip/turnServer$
  11253. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/event/
  11254. ^/_matrix/client/(api/v1|r0|v3|unstable)/joined_rooms$
  11255. ^/_matrix/client/v1/rooms/.*/timestamp_to_event$
  11256. ^/_matrix/client/(api/v1|r0|v3|unstable/.*)/rooms/.*/aliases
  11257. ^/_matrix/client/(api/v1|r0|v3|unstable)/search$
  11258. ^/_matrix/client/(r0|v3|unstable)/user/.*/filter(/|$)
  11259. ^/_matrix/client/(api/v1|r0|v3|unstable)/directory/room/.*$
  11260. ^/_matrix/client/(r0|v3|unstable)/capabilities$
  11261. ^/_matrix/client/(r0|v3|unstable)/notifications$
  11262. # Encryption requests
  11263. ^/_matrix/client/(r0|v3|unstable)/keys/query$
  11264. ^/_matrix/client/(r0|v3|unstable)/keys/changes$
  11265. ^/_matrix/client/(r0|v3|unstable)/keys/claim$
  11266. ^/_matrix/client/(r0|v3|unstable)/room_keys/
  11267. ^/_matrix/client/(r0|v3|unstable)/keys/upload/
  11268. # Registration/login requests
  11269. ^/_matrix/client/(api/v1|r0|v3|unstable)/login$
  11270. ^/_matrix/client/(r0|v3|unstable)/register$
  11271. ^/_matrix/client/(r0|v3|unstable)/register/available$
  11272. ^/_matrix/client/v1/register/m.login.registration_token/validity$
  11273. ^/_matrix/client/(r0|v3|unstable)/password_policy$
  11274. # Event sending requests
  11275. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/redact
  11276. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/send
  11277. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/state/
  11278. ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/(join|invite|leave|ban|unban|kick)$
  11279. ^/_matrix/client/(api/v1|r0|v3|unstable)/join/
  11280. ^/_matrix/client/(api/v1|r0|v3|unstable)/knock/
  11281. ^/_matrix/client/(api/v1|r0|v3|unstable)/profile/
  11282. # Account data requests
  11283. ^/_matrix/client/(r0|v3|unstable)/.*/tags
  11284. ^/_matrix/client/(r0|v3|unstable)/.*/account_data
  11285. # Receipts requests
  11286. ^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt
  11287. ^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers
  11288. # Presence requests
  11289. ^/_matrix/client/(api/v1|r0|v3|unstable)/presence/
  11290. # User directory search requests
  11291. ^/_matrix/client/(r0|v3|unstable)/user_directory/search$
  11292. </code></pre>
  11293. <p>Additionally, the following REST endpoints can be handled for GET requests:</p>
  11294. <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/pushrules/
  11295. </code></pre>
  11296. <p>Pagination requests can also be handled, but all requests for a given
  11297. room must be routed to the same instance. Additionally, care must be taken to
  11298. ensure that the purge history admin API is not used while pagination requests
  11299. for the room are in flight:</p>
  11300. <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/messages$
  11301. </code></pre>
  11302. <p>Additionally, the following endpoints should be included if Synapse is configured
  11303. to use SSO (you only need to include the ones for whichever SSO provider you're
  11304. using):</p>
  11305. <pre><code># for all SSO providers
  11306. ^/_matrix/client/(api/v1|r0|v3|unstable)/login/sso/redirect
  11307. ^/_synapse/client/pick_idp$
  11308. ^/_synapse/client/pick_username
  11309. ^/_synapse/client/new_user_consent$
  11310. ^/_synapse/client/sso_register$
  11311. # OpenID Connect requests.
  11312. ^/_synapse/client/oidc/callback$
  11313. # SAML requests.
  11314. ^/_synapse/client/saml2/authn_response$
  11315. # CAS requests.
  11316. ^/_matrix/client/(api/v1|r0|v3|unstable)/login/cas/ticket$
  11317. </code></pre>
  11318. <p>Ensure that all SSO logins go to a single process.
  11319. For multiple workers not handling the SSO endpoints properly, see
  11320. <a href="https://github.com/matrix-org/synapse/issues/7530">#7530</a> and
  11321. <a href="https://github.com/matrix-org/synapse/issues/9427">#9427</a>.</p>
  11322. <p>Note that a <a href="usage/configuration/config_documentation.html#listeners">HTTP listener</a>
  11323. with <code>client</code> and <code>federation</code> <code>resources</code> must be configured in the
  11324. <a href="usage/configuration/config_documentation.html#worker_listeners"><code>worker_listeners</code></a>
  11325. option in the worker config.</p>
  11326. <h4 id="load-balancing"><a class="header" href="#load-balancing">Load balancing</a></h4>
  11327. <p>It is possible to run multiple instances of this worker app, with incoming requests
  11328. being load-balanced between them by the reverse-proxy. However, different endpoints
  11329. have different characteristics and so admins
  11330. may wish to run multiple groups of workers handling different endpoints so that
  11331. load balancing can be done in different ways.</p>
  11332. <p>For <code>/sync</code> and <code>/initialSync</code> requests it will be more efficient if all
  11333. requests from a particular user are routed to a single instance. This can
  11334. be done in reverse proxy by extracting username part from the users access token.</p>
  11335. <p>Admins may additionally wish to separate out <code>/sync</code>
  11336. requests that have a <code>since</code> query parameter from those that don't (and
  11337. <code>/initialSync</code>), as requests that don't are known as &quot;initial sync&quot; that happens
  11338. when a user logs in on a new device and can be <em>very</em> resource intensive, so
  11339. isolating these requests will stop them from interfering with other users ongoing
  11340. syncs.</p>
  11341. <p>Example <code>nginx</code> configuration snippet that handles the cases above. This is just an
  11342. example and probably requires some changes according to your particular setup:</p>
  11343. <pre><code class="language-nginx"># Choose sync worker based on the existence of &quot;since&quot; query parameter
  11344. map $arg_since $sync {
  11345. default synapse_sync;
  11346. '' synapse_initial_sync;
  11347. }
  11348. # Extract username from access token passed as URL parameter
  11349. map $arg_access_token $accesstoken_from_urlparam {
  11350. # Defaults to just passing back the whole accesstoken
  11351. default $arg_access_token;
  11352. # Try to extract username part from accesstoken URL parameter
  11353. &quot;~syt_(?&lt;username&gt;.*?)_.*&quot; $username;
  11354. }
  11355. # Extract username from access token passed as authorization header
  11356. map $http_authorization $mxid_localpart {
  11357. # Defaults to just passing back the whole accesstoken
  11358. default $http_authorization;
  11359. # Try to extract username part from accesstoken header
  11360. &quot;~Bearer syt_(?&lt;username&gt;.*?)_.*&quot; $username;
  11361. # if no authorization-header exist, try mapper for URL parameter &quot;access_token&quot;
  11362. &quot;&quot; $accesstoken_from_urlparam;
  11363. }
  11364. upstream synapse_initial_sync {
  11365. # Use the username mapper result for hash key
  11366. hash $mxid_localpart consistent;
  11367. server 127.0.0.1:8016;
  11368. server 127.0.0.1:8036;
  11369. }
  11370. upstream synapse_sync {
  11371. # Use the username mapper result for hash key
  11372. hash $mxid_localpart consistent;
  11373. server 127.0.0.1:8013;
  11374. server 127.0.0.1:8037;
  11375. server 127.0.0.1:8038;
  11376. server 127.0.0.1:8039;
  11377. }
  11378. # Sync initial/normal
  11379. location ~ ^/_matrix/client/(r0|v3)/sync$ {
  11380. proxy_pass http://$sync;
  11381. }
  11382. # Normal sync
  11383. location ~ ^/_matrix/client/(api/v1|r0|v3)/events$ {
  11384. proxy_pass http://synapse_sync;
  11385. }
  11386. # Initial_sync
  11387. location ~ ^/_matrix/client/(api/v1|r0|v3)/initialSync$ {
  11388. proxy_pass http://synapse_initial_sync;
  11389. }
  11390. location ~ ^/_matrix/client/(api/v1|r0|v3)/rooms/[^/]+/initialSync$ {
  11391. proxy_pass http://synapse_initial_sync;
  11392. }
  11393. </code></pre>
  11394. <p>Federation and client requests can be balanced via simple round robin.</p>
  11395. <p>The inbound federation transaction request <code>^/_matrix/federation/v1/send/</code>
  11396. should be balanced by source IP so that transactions from the same remote server
  11397. go to the same process.</p>
  11398. <p>Registration/login requests can be handled separately purely to help ensure that
  11399. unexpected load doesn't affect new logins and sign ups.</p>
  11400. <p>Finally, event sending requests can be balanced by the room ID in the URI (or
  11401. the full URI, or even just round robin), the room ID is the path component after
  11402. <code>/rooms/</code>. If there is a large bridge connected that is sending or may send lots
  11403. of events, then a dedicated set of workers can be provisioned to limit the
  11404. effects of bursts of events from that bridge on events sent by normal users.</p>
  11405. <h4 id="stream-writers"><a class="header" href="#stream-writers">Stream writers</a></h4>
  11406. <p>Additionally, the writing of specific streams (such as events) can be moved off
  11407. of the main process to a particular worker.</p>
  11408. <p>To enable this, the worker must have:</p>
  11409. <ul>
  11410. <li>An <a href="usage/configuration/config_documentation.html#listeners">HTTP <code>replication</code> listener</a> configured,</li>
  11411. <li>Have a <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a>
  11412. and be listed in the <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a>
  11413. config. </li>
  11414. <li>Have the main process declared on the <a href="usage/configuration/config_documentation.html#instance_map"><code>instance_map</code></a> as well.</li>
  11415. </ul>
  11416. <p>Note: The same worker can handle multiple streams, but unless otherwise documented,
  11417. each stream can only have a single writer.</p>
  11418. <p>For example, to move event persistence off to a dedicated worker, the shared
  11419. configuration would include:</p>
  11420. <pre><code class="language-yaml">instance_map:
  11421. main:
  11422. host: localhost
  11423. port: 8030
  11424. event_persister1:
  11425. host: localhost
  11426. port: 8034
  11427. stream_writers:
  11428. events: event_persister1
  11429. </code></pre>
  11430. <p>An example for a stream writer instance:</p>
  11431. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  11432. worker_name: event_persister1
  11433. worker_listeners:
  11434. - type: http
  11435. port: 8034
  11436. resources:
  11437. - names: [replication]
  11438. # Enable listener if this stream writer handles endpoints for the `typing` or
  11439. # `to_device` streams. Uses a different port to the `replication` listener to
  11440. # avoid exposing the `replication` listener publicly.
  11441. #
  11442. #- type: http
  11443. # port: 8035
  11444. # x_forwarded: true
  11445. # resources:
  11446. # - names: [client]
  11447. worker_log_config: /etc/matrix-synapse/event-persister-log.yaml
  11448. </code></pre>
  11449. <p>Some of the streams have associated endpoints which, for maximum efficiency, should
  11450. be routed to the workers handling that stream. See below for the currently supported
  11451. streams and the endpoints associated with them:</p>
  11452. <h5 id="the-events-stream"><a class="header" href="#the-events-stream">The <code>events</code> stream</a></h5>
  11453. <p>The <code>events</code> stream experimentally supports having multiple writer workers, where load
  11454. is sharded between them by room ID. Each writer is called an <em>event persister</em>. They are
  11455. responsible for</p>
  11456. <ul>
  11457. <li>receiving new events,</li>
  11458. <li>linking them to those already in the room <a href="development/room-dag-concepts.html">DAG</a>,</li>
  11459. <li>persisting them to the DB, and finally</li>
  11460. <li>updating the events stream.</li>
  11461. </ul>
  11462. <p>Because load is sharded in this way, you <em>must</em> restart all worker instances when
  11463. adding or removing event persisters.</p>
  11464. <p>An <code>event_persister</code> should not be mistaken for an <code>event_creator</code>.
  11465. An <code>event_creator</code> listens for requests from clients to create new events and does
  11466. so. It will then pass those events over HTTP replication to any configured event
  11467. persisters (or the main process if none are configured).</p>
  11468. <p>Note that <code>event_creator</code>s and <code>event_persister</code>s are implemented using the same
  11469. <a href="workers.html#synapseappgeneric_worker"><code>synapse.app.generic_worker</code></a>.</p>
  11470. <p>An example <a href="usage/configuration/config_documentation.html#stream_writers"><code>stream_writers</code></a>
  11471. configuration with multiple writers:</p>
  11472. <pre><code class="language-yaml">stream_writers:
  11473. events:
  11474. - event_persister1
  11475. - event_persister2
  11476. </code></pre>
  11477. <h5 id="the-typing-stream"><a class="header" href="#the-typing-stream">The <code>typing</code> stream</a></h5>
  11478. <p>The following endpoints should be routed directly to the worker configured as
  11479. the stream writer for the <code>typing</code> stream:</p>
  11480. <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/typing
  11481. </code></pre>
  11482. <h5 id="the-to_device-stream"><a class="header" href="#the-to_device-stream">The <code>to_device</code> stream</a></h5>
  11483. <p>The following endpoints should be routed directly to the worker configured as
  11484. the stream writer for the <code>to_device</code> stream:</p>
  11485. <pre><code>^/_matrix/client/(r0|v3|unstable)/sendToDevice/
  11486. </code></pre>
  11487. <h5 id="the-account_data-stream"><a class="header" href="#the-account_data-stream">The <code>account_data</code> stream</a></h5>
  11488. <p>The following endpoints should be routed directly to the worker configured as
  11489. the stream writer for the <code>account_data</code> stream:</p>
  11490. <pre><code>^/_matrix/client/(r0|v3|unstable)/.*/tags
  11491. ^/_matrix/client/(r0|v3|unstable)/.*/account_data
  11492. </code></pre>
  11493. <h5 id="the-receipts-stream"><a class="header" href="#the-receipts-stream">The <code>receipts</code> stream</a></h5>
  11494. <p>The following endpoints should be routed directly to the worker configured as
  11495. the stream writer for the <code>receipts</code> stream:</p>
  11496. <pre><code>^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt
  11497. ^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers
  11498. </code></pre>
  11499. <h5 id="the-presence-stream"><a class="header" href="#the-presence-stream">The <code>presence</code> stream</a></h5>
  11500. <p>The following endpoints should be routed directly to the worker configured as
  11501. the stream writer for the <code>presence</code> stream:</p>
  11502. <pre><code>^/_matrix/client/(api/v1|r0|v3|unstable)/presence/
  11503. </code></pre>
  11504. <h4 id="restrict-outbound-federation-traffic-to-a-specific-set-of-workers"><a class="header" href="#restrict-outbound-federation-traffic-to-a-specific-set-of-workers">Restrict outbound federation traffic to a specific set of workers</a></h4>
  11505. <p>The
  11506. <a href="usage/configuration/config_documentation.html#outbound_federation_restricted_to"><code>outbound_federation_restricted_to</code></a>
  11507. configuration is useful to make sure outbound federation traffic only goes through a
  11508. specified subset of workers. This allows you to set more strict access controls (like a
  11509. firewall) for all workers and only allow the <code>federation_sender</code>'s to contact the
  11510. outside world.</p>
  11511. <pre><code class="language-yaml">instance_map:
  11512. main:
  11513. host: localhost
  11514. port: 8030
  11515. federation_sender1:
  11516. host: localhost
  11517. port: 8034
  11518. outbound_federation_restricted_to:
  11519. - federation_sender1
  11520. worker_replication_secret: &quot;secret_secret&quot;
  11521. </code></pre>
  11522. <h4 id="background-tasks"><a class="header" href="#background-tasks">Background tasks</a></h4>
  11523. <p>There is also support for moving background tasks to a separate
  11524. worker. Background tasks are run periodically or started via replication. Exactly
  11525. which tasks are configured to run depends on your Synapse configuration (e.g. if
  11526. stats is enabled). This worker doesn't handle any REST endpoints itself.</p>
  11527. <p>To enable this, the worker must have a unique
  11528. <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a>
  11529. and can be configured to run background tasks. For example, to move background tasks
  11530. to a dedicated worker, the shared configuration would include:</p>
  11531. <pre><code class="language-yaml">run_background_tasks_on: background_worker
  11532. </code></pre>
  11533. <p>You might also wish to investigate the
  11534. <a href="workers.html#updating-the-user-directory"><code>update_user_directory_from_worker</code></a> and
  11535. <a href="workers.html#synapseappmedia_repository"><code>media_instance_running_background_jobs</code></a> settings.</p>
  11536. <p>An example for a dedicated background worker instance:</p>
  11537. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  11538. worker_name: background_worker
  11539. worker_log_config: /etc/matrix-synapse/background-worker-log.yaml
  11540. </code></pre>
  11541. <h4 id="updating-the-user-directory"><a class="header" href="#updating-the-user-directory">Updating the User Directory</a></h4>
  11542. <p>You can designate one generic worker to update the user directory.</p>
  11543. <p>Specify its name in the <a href="usage/configuration/config_documentation.html#update_user_directory_from_worker">shared configuration</a>
  11544. as follows:</p>
  11545. <pre><code class="language-yaml">update_user_directory_from_worker: worker_name
  11546. </code></pre>
  11547. <p>This work cannot be load-balanced; please ensure the main process is restarted
  11548. after setting this option in the shared configuration!</p>
  11549. <p>User directory updates allow REST endpoints matching the following regular
  11550. expressions to work:</p>
  11551. <pre><code>^/_matrix/client/(r0|v3|unstable)/user_directory/search$
  11552. </code></pre>
  11553. <p>The above endpoints can be routed to any worker, though you may choose to route
  11554. it to the chosen user directory worker.</p>
  11555. <p>This style of configuration supersedes the legacy <code>synapse.app.user_dir</code>
  11556. worker application type.</p>
  11557. <h4 id="notifying-application-services"><a class="header" href="#notifying-application-services">Notifying Application Services</a></h4>
  11558. <p>You can designate one generic worker to send output traffic to Application Services.
  11559. Doesn't handle any REST endpoints itself, but you should specify its name in the
  11560. <a href="usage/configuration/config_documentation.html#notify_appservices_from_worker">shared configuration</a>
  11561. as follows:</p>
  11562. <pre><code class="language-yaml">notify_appservices_from_worker: worker_name
  11563. </code></pre>
  11564. <p>This work cannot be load-balanced; please ensure the main process is restarted
  11565. after setting this option in the shared configuration!</p>
  11566. <p>This style of configuration supersedes the legacy <code>synapse.app.appservice</code>
  11567. worker application type.</p>
  11568. <h4 id="push-notifications"><a class="header" href="#push-notifications">Push Notifications</a></h4>
  11569. <p>You can designate generic worker to sending push notifications to
  11570. a <a href="https://spec.matrix.org/v1.5/push-gateway-api/">push gateway</a> such as
  11571. <a href="https://github.com/matrix-org/sygnal">sygnal</a> and email.</p>
  11572. <p>This will stop the main process sending push notifications.</p>
  11573. <p>The workers responsible for sending push notifications can be defined using the
  11574. <a href="usage/configuration/config_documentation.html#pusher_instances"><code>pusher_instances</code></a>
  11575. option. For example:</p>
  11576. <pre><code class="language-yaml">pusher_instances:
  11577. - pusher_worker1
  11578. - pusher_worker2
  11579. </code></pre>
  11580. <p>Multiple workers can be added to this map, in which case the work is balanced
  11581. across them. Ensure the main process and all pusher workers are restarted after changing
  11582. this option.</p>
  11583. <p>These workers don't need to accept incoming HTTP requests to send push notifications,
  11584. so no additional reverse proxy configuration is required for pusher workers.</p>
  11585. <p>This style of configuration supersedes the legacy <code>synapse.app.pusher</code>
  11586. worker application type.</p>
  11587. <h3 id="synapseapppusher"><a class="header" href="#synapseapppusher"><code>synapse.app.pusher</code></a></h3>
  11588. <p>It is likely this option will be deprecated in the future and is not recommended for new
  11589. installations. Instead, <a href="workers.html#push-notifications">use <code>synapse.app.generic_worker</code> with the <code>pusher_instances</code></a>.</p>
  11590. <p>Handles sending push notifications to sygnal and email. Doesn't handle any
  11591. REST endpoints itself, but you should set
  11592. <a href="usage/configuration/config_documentation.html#start_pushers"><code>start_pushers: false</code></a> in the
  11593. shared configuration file to stop the main synapse sending push notifications.</p>
  11594. <p>To run multiple instances at once the
  11595. <a href="usage/configuration/config_documentation.html#pusher_instances"><code>pusher_instances</code></a>
  11596. option should list all pusher instances by their
  11597. <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a>, e.g.:</p>
  11598. <pre><code class="language-yaml">start_pushers: false
  11599. pusher_instances:
  11600. - pusher_worker1
  11601. - pusher_worker2
  11602. </code></pre>
  11603. <p>An example for a pusher instance:</p>
  11604. <pre><code class="language-yaml">worker_app: synapse.app.pusher
  11605. worker_name: pusher_worker1
  11606. worker_log_config: /etc/matrix-synapse/pusher-worker-log.yaml
  11607. </code></pre>
  11608. <h3 id="synapseappappservice"><a class="header" href="#synapseappappservice"><code>synapse.app.appservice</code></a></h3>
  11609. <p><strong>Deprecated as of Synapse v1.59.</strong> <a href="workers.html#notifying-application-services">Use <code>synapse.app.generic_worker</code> with the
  11610. <code>notify_appservices_from_worker</code> option instead.</a></p>
  11611. <p>Handles sending output traffic to Application Services. Doesn't handle any
  11612. REST endpoints itself, but you should set <code>notify_appservices: False</code> in the
  11613. shared configuration file to stop the main synapse sending appservice notifications.</p>
  11614. <p>Note this worker cannot be load-balanced: only one instance should be active.</p>
  11615. <h3 id="synapseappfederation_sender"><a class="header" href="#synapseappfederation_sender"><code>synapse.app.federation_sender</code></a></h3>
  11616. <p>It is likely this option will be deprecated in the future and not recommended for
  11617. new installations. Instead, <a href="usage/configuration/config_documentation.html#federation_sender_instances">use <code>synapse.app.generic_worker</code> with the <code>federation_sender_instances</code></a>.</p>
  11618. <p>Handles sending federation traffic to other servers. Doesn't handle any
  11619. REST endpoints itself, but you should set
  11620. <a href="usage/configuration/config_documentation.html#send_federation"><code>send_federation: false</code></a>
  11621. in the shared configuration file to stop the main synapse sending this traffic.</p>
  11622. <p>If running multiple federation senders then you must list each
  11623. instance in the
  11624. <a href="usage/configuration/config_documentation.html#federation_sender_instances"><code>federation_sender_instances</code></a>
  11625. option by their
  11626. <a href="usage/configuration/config_documentation.html#worker_name"><code>worker_name</code></a>.
  11627. All instances must be stopped and started when adding or removing instances.
  11628. For example:</p>
  11629. <pre><code class="language-yaml">send_federation: false
  11630. federation_sender_instances:
  11631. - federation_sender1
  11632. - federation_sender2
  11633. </code></pre>
  11634. <p>An example for a federation sender instance:</p>
  11635. <pre><code class="language-yaml">worker_app: synapse.app.federation_sender
  11636. worker_name: federation_sender1
  11637. worker_log_config: /etc/matrix-synapse/federation-sender-log.yaml
  11638. </code></pre>
  11639. <h3 id="synapseappmedia_repository"><a class="header" href="#synapseappmedia_repository"><code>synapse.app.media_repository</code></a></h3>
  11640. <p>Handles the media repository. It can handle all endpoints starting with:</p>
  11641. <pre><code>/_matrix/media/
  11642. </code></pre>
  11643. <p>... and the following regular expressions matching media-specific administration APIs:</p>
  11644. <pre><code>^/_synapse/admin/v1/purge_media_cache$
  11645. ^/_synapse/admin/v1/room/.*/media.*$
  11646. ^/_synapse/admin/v1/user/.*/media.*$
  11647. ^/_synapse/admin/v1/media/.*$
  11648. ^/_synapse/admin/v1/quarantine_media/.*$
  11649. ^/_synapse/admin/v1/users/.*/media$
  11650. </code></pre>
  11651. <p>You should also set
  11652. <a href="usage/configuration/config_documentation.html#enable_media_repo"><code>enable_media_repo: False</code></a>
  11653. in the shared configuration
  11654. file to stop the main synapse running background jobs related to managing the
  11655. media repository. Note that doing so will prevent the main process from being
  11656. able to handle the above endpoints.</p>
  11657. <p>In the <code>media_repository</code> worker configuration file, configure the
  11658. <a href="usage/configuration/config_documentation.html#listeners">HTTP listener</a> to
  11659. expose the <code>media</code> resource. For example:</p>
  11660. <pre><code class="language-yaml">worker_app: synapse.app.media_repository
  11661. worker_name: media_worker
  11662. worker_listeners:
  11663. - type: http
  11664. port: 8085
  11665. x_forwarded: true
  11666. resources:
  11667. - names: [media]
  11668. worker_log_config: /etc/matrix-synapse/media-worker-log.yaml
  11669. </code></pre>
  11670. <p>Note that if running multiple media repositories they must be on the same server
  11671. and you must specify a single instance to run the background tasks in the
  11672. <a href="usage/configuration/config_documentation.html#media_instance_running_background_jobs">shared configuration</a>,
  11673. e.g.:</p>
  11674. <pre><code class="language-yaml">media_instance_running_background_jobs: &quot;media-repository-1&quot;
  11675. </code></pre>
  11676. <p>Note that if a reverse proxy is used , then <code>/_matrix/media/</code> must be routed for both inbound client and federation requests (if they are handled separately).</p>
  11677. <h3 id="synapseappuser_dir"><a class="header" href="#synapseappuser_dir"><code>synapse.app.user_dir</code></a></h3>
  11678. <p><strong>Deprecated as of Synapse v1.59.</strong> <a href="workers.html#updating-the-user-directory">Use <code>synapse.app.generic_worker</code> with the
  11679. <code>update_user_directory_from_worker</code> option instead.</a></p>
  11680. <p>Handles searches in the user directory. It can handle REST endpoints matching
  11681. the following regular expressions:</p>
  11682. <pre><code>^/_matrix/client/(r0|v3|unstable)/user_directory/search$
  11683. </code></pre>
  11684. <p>When using this worker you must also set <code>update_user_directory: false</code> in the
  11685. shared configuration file to stop the main synapse running background
  11686. jobs related to updating the user directory.</p>
  11687. <p>Above endpoint is not <em>required</em> to be routed to this worker. By default,
  11688. <code>update_user_directory</code> is set to <code>true</code>, which means the main process
  11689. will handle updates. All workers configured with <code>client</code> can handle the above
  11690. endpoint as long as either this worker or the main process are configured to
  11691. handle it, and are online.</p>
  11692. <p>If <code>update_user_directory</code> is set to <code>false</code>, and this worker is not running,
  11693. the above endpoint may give outdated results.</p>
  11694. <h3 id="historical-apps"><a class="header" href="#historical-apps">Historical apps</a></h3>
  11695. <p>The following used to be separate worker application types, but are now
  11696. equivalent to <code>synapse.app.generic_worker</code>:</p>
  11697. <ul>
  11698. <li><code>synapse.app.client_reader</code></li>
  11699. <li><code>synapse.app.event_creator</code></li>
  11700. <li><code>synapse.app.federation_reader</code></li>
  11701. <li><code>synapse.app.federation_sender</code></li>
  11702. <li><code>synapse.app.frontend_proxy</code></li>
  11703. <li><code>synapse.app.pusher</code></li>
  11704. <li><code>synapse.app.synchrotron</code></li>
  11705. </ul>
  11706. <h2 id="migration-from-old-config"><a class="header" href="#migration-from-old-config">Migration from old config</a></h2>
  11707. <p>A main change that has occurred is the merging of worker apps into
  11708. <code>synapse.app.generic_worker</code>. This change is backwards compatible and so no
  11709. changes to the config are required.</p>
  11710. <p>To migrate apps to use <code>synapse.app.generic_worker</code> simply update the
  11711. <code>worker_app</code> option in the worker configs, and where worker are started (e.g.
  11712. in systemd service files, but not required for synctl).</p>
  11713. <h2 id="architectural-diagram"><a class="header" href="#architectural-diagram">Architectural diagram</a></h2>
  11714. <p>The following shows an example setup using Redis and a reverse proxy:</p>
  11715. <pre><code> Clients &amp; Federation
  11716. |
  11717. v
  11718. +-----------+
  11719. | |
  11720. | Reverse |
  11721. | Proxy |
  11722. | |
  11723. +-----------+
  11724. | | |
  11725. | | | HTTP requests
  11726. +-------------------+ | +-----------+
  11727. | +---+ |
  11728. | | |
  11729. v v v
  11730. +--------------+ +--------------+ +--------------+ +--------------+
  11731. | Main | | Generic | | Generic | | Event |
  11732. | Process | | Worker 1 | | Worker 2 | | Persister |
  11733. +--------------+ +--------------+ +--------------+ +--------------+
  11734. ^ ^ | ^ | | ^ | | ^ ^
  11735. | | | | | | | | | | |
  11736. | | | | | HTTP | | | | | |
  11737. | +----------+&lt;--|---|---------+&lt;--|---|---------+ | |
  11738. | | +-------------|--&gt;+-------------+ |
  11739. | | | |
  11740. | | | |
  11741. v v v v
  11742. ======================================================================
  11743. Redis pub/sub channel
  11744. </code></pre>
  11745. <div style="break-before: page; page-break-before: always;"></div><h3 id="using-synctl-with-workers"><a class="header" href="#using-synctl-with-workers">Using synctl with workers</a></h3>
  11746. <p>If you want to use <code>synctl</code> to manage your synapse processes, you will need to
  11747. create an an additional configuration file for the main synapse process. That
  11748. configuration should look like this:</p>
  11749. <pre><code class="language-yaml">worker_app: synapse.app.homeserver
  11750. </code></pre>
  11751. <p>Additionally, each worker app must be configured with the name of a &quot;pid file&quot;,
  11752. to which it will write its process ID when it starts. For example, for a
  11753. synchrotron, you might write:</p>
  11754. <pre><code class="language-yaml">worker_pid_file: /home/matrix/synapse/worker1.pid
  11755. </code></pre>
  11756. <p>Finally, to actually run your worker-based synapse, you must pass synctl the <code>-a</code>
  11757. commandline option to tell it to operate on all the worker configurations found
  11758. in the given directory, e.g.:</p>
  11759. <pre><code class="language-sh">synctl -a $CONFIG/workers start
  11760. </code></pre>
  11761. <p>Currently one should always restart all workers when restarting or upgrading
  11762. synapse, unless you explicitly know it's safe not to. For instance, restarting
  11763. synapse without restarting all the synchrotrons may result in broken typing
  11764. notifications.</p>
  11765. <p>To manipulate a specific worker, you pass the -w option to synctl:</p>
  11766. <pre><code class="language-sh">synctl -w $CONFIG/workers/worker1.yaml restart
  11767. </code></pre>
  11768. <div style="break-before: page; page-break-before: always;"></div><h1 id="setting-up-synapse-with-workers-and-systemd"><a class="header" href="#setting-up-synapse-with-workers-and-systemd">Setting up Synapse with Workers and Systemd</a></h1>
  11769. <p>This is a setup for managing synapse with systemd, including support for
  11770. managing workers. It provides a <code>matrix-synapse</code> service for the master, as
  11771. well as a <code>matrix-synapse-worker@</code> service template for any workers you
  11772. require. Additionally, to group the required services, it sets up a
  11773. <code>matrix-synapse.target</code>.</p>
  11774. <p>See the folder <a href="https://github.com/matrix-org/synapse/tree/develop/docs/systemd-with-workers/system/">system</a>
  11775. for the systemd unit files.</p>
  11776. <p>The folder <a href="https://github.com/matrix-org/synapse/tree/develop/docs/systemd-with-workers/workers/">workers</a>
  11777. contains an example configuration for the <code>generic_worker</code> worker.</p>
  11778. <h2 id="synapse-configuration-files"><a class="header" href="#synapse-configuration-files">Synapse configuration files</a></h2>
  11779. <p>See <a href="systemd-with-workers/../workers.html">the worker documentation</a> for information on how to set up the
  11780. configuration files and reverse-proxy correctly.
  11781. Below is a sample <code>generic_worker</code> worker configuration file.</p>
  11782. <pre><code class="language-yaml">worker_app: synapse.app.generic_worker
  11783. worker_name: generic_worker1
  11784. worker_listeners:
  11785. - type: http
  11786. port: 8083
  11787. x_forwarded: true
  11788. resources:
  11789. - names: [client, federation]
  11790. worker_log_config: /etc/matrix-synapse/generic-worker-log.yaml
  11791. </code></pre>
  11792. <p>Systemd manages daemonization itself, so ensure that none of the configuration
  11793. files set either <code>daemonize</code> or <code>worker_daemonize</code>.</p>
  11794. <p>The config files of all workers are expected to be located in
  11795. <code>/etc/matrix-synapse/workers</code>. If you want to use a different location, edit
  11796. the provided <code>*.service</code> files accordingly.</p>
  11797. <p>There is no need for a separate configuration file for the master process.</p>
  11798. <h2 id="set-up"><a class="header" href="#set-up">Set up</a></h2>
  11799. <ol>
  11800. <li>Adjust synapse configuration files as above.</li>
  11801. <li>Copy the <code>*.service</code> and <code>*.target</code> files in <a href="https://github.com/matrix-org/synapse/tree/develop/docs/systemd-with-workers/system/">system</a>
  11802. to <code>/etc/systemd/system</code>.</li>
  11803. <li>Run <code>systemctl daemon-reload</code> to tell systemd to load the new unit files.</li>
  11804. <li>Run <code>systemctl enable matrix-synapse.service</code>. This will configure the
  11805. synapse master process to be started as part of the <code>matrix-synapse.target</code>
  11806. target.</li>
  11807. <li>For each worker process to be enabled, run <code>systemctl enable matrix-synapse-worker@&lt;worker_name&gt;.service</code>. For each <code>&lt;worker_name&gt;</code>, there
  11808. should be a corresponding configuration file.
  11809. <code>/etc/matrix-synapse/workers/&lt;worker_name&gt;.yaml</code>.</li>
  11810. <li>Start all the synapse processes with <code>systemctl start matrix-synapse.target</code>.</li>
  11811. <li>Tell systemd to start synapse on boot with <code>systemctl enable matrix-synapse.target</code>.</li>
  11812. </ol>
  11813. <h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
  11814. <p>Once the services are correctly set up, you can use the following commands
  11815. to manage your synapse installation:</p>
  11816. <pre><code class="language-sh"># Restart Synapse master and all workers
  11817. systemctl restart matrix-synapse.target
  11818. # Stop Synapse and all workers
  11819. systemctl stop matrix-synapse.target
  11820. # Restart the master alone
  11821. systemctl start matrix-synapse.service
  11822. # Restart a specific worker (eg. generic_worker); the master is
  11823. # unaffected by this.
  11824. systemctl restart matrix-synapse-worker@generic_worker.service
  11825. # Add a new worker (assuming all configs are set up already)
  11826. systemctl enable matrix-synapse-worker@federation_writer.service
  11827. systemctl restart matrix-synapse.target
  11828. </code></pre>
  11829. <h2 id="hardening"><a class="header" href="#hardening">Hardening</a></h2>
  11830. <p><strong>Optional:</strong> If further hardening is desired, the file
  11831. <code>override-hardened.conf</code> may be copied from
  11832. <a href="https://github.com/matrix-org/synapse/tree/develop/contrib/systemd/">contrib/systemd/override-hardened.conf</a>
  11833. in this repository to the location
  11834. <code>/etc/systemd/system/matrix-synapse.service.d/override-hardened.conf</code> (the
  11835. directory may have to be created). It enables certain sandboxing features in
  11836. systemd to further secure the synapse service. You may read the comments to
  11837. understand what the override file is doing. The same file will need to be copied to
  11838. <code>/etc/systemd/system/matrix-synapse-worker@.service.d/override-hardened-worker.conf</code>
  11839. (this directory may also have to be created) in order to apply the same
  11840. hardening options to any worker processes.</p>
  11841. <p>Once these files have been copied to their appropriate locations, simply reload
  11842. systemd's manager config files and restart all Synapse services to apply the hardening options. They will automatically
  11843. be applied at every restart as long as the override files are present at the
  11844. specified locations.</p>
  11845. <pre><code class="language-sh">systemctl daemon-reload
  11846. # Restart services
  11847. systemctl restart matrix-synapse.target
  11848. </code></pre>
  11849. <p>In order to see their effect, you may run <code>systemd-analyze security matrix-synapse.service</code> before and after applying the hardening options to see
  11850. the changes being applied at a glance.</p>
  11851. <div style="break-before: page; page-break-before: always;"></div><h1 id="administration"><a class="header" href="#administration">Administration</a></h1>
  11852. <p>This section contains information on managing your Synapse homeserver. This includes:</p>
  11853. <ul>
  11854. <li>Managing users, rooms and media via the Admin API.</li>
  11855. <li>Setting up metrics and monitoring to give you insight into your homeserver's health.</li>
  11856. <li>Configuring structured logging.</li>
  11857. </ul>
  11858. <div style="break-before: page; page-break-before: always;"></div><h1 id="the-admin-api"><a class="header" href="#the-admin-api">The Admin API</a></h1>
  11859. <h2 id="authenticate-as-a-server-admin"><a class="header" href="#authenticate-as-a-server-admin">Authenticate as a server admin</a></h2>
  11860. <p>Many of the API calls in the admin api will require an <code>access_token</code> for a
  11861. server admin. (Note that a server admin is distinct from a room admin.)</p>
  11862. <p>An existing user can be marked as a server admin by updating the database directly.</p>
  11863. <p>Check your <a href="usage/administration/admin_api/../../configuration/config_documentation.html#database">database settings</a> in the configuration file, connect to the correct database using either <code>psql [database name]</code> (if using PostgreSQL) or <code>sqlite3 path/to/your/database.db</code> (if using SQLite) and elevate the user <code>@foo:bar.com</code> to administrator.</p>
  11864. <pre><code class="language-sql">UPDATE users SET admin = 1 WHERE name = '@foo:bar.com';
  11865. </code></pre>
  11866. <p>A new server admin user can also be created using the <code>register_new_matrix_user</code>
  11867. command. This is a script that is distributed as part of synapse. It is possibly
  11868. already on your <code>$PATH</code> depending on how Synapse was installed.</p>
  11869. <p>Finding your user's <code>access_token</code> is client-dependent, but will usually be shown in the client's settings.</p>
  11870. <h2 id="making-an-admin-api-request"><a class="header" href="#making-an-admin-api-request">Making an Admin API request</a></h2>
  11871. <p>For security reasons, we <a href="usage/administration/admin_api/../../../reverse_proxy.html#synapse-administration-endpoints">recommend</a>
  11872. that the Admin API (<code>/_synapse/admin/...</code>) should be hidden from public view using a
  11873. reverse proxy. This means you should typically query the Admin API from a terminal on
  11874. the machine which runs Synapse.</p>
  11875. <p>Once you have your <code>access_token</code>, you will need to authenticate each request to an Admin API endpoint by
  11876. providing the token as either a query parameter or a request header. To add it as a request header in cURL:</p>
  11877. <pre><code class="language-sh">curl --header &quot;Authorization: Bearer &lt;access_token&gt;&quot; &lt;the_rest_of_your_API_request&gt;
  11878. </code></pre>
  11879. <p>For example, suppose we want to
  11880. <a href="usage/administration/admin_api/../../../admin_api/user_admin_api.html#query-user-account">query the account</a> of the user
  11881. <code>@foo:bar.com</code>. We need an admin access token (e.g.
  11882. <code>syt_AjfVef2_L33JNpafeif_0feKJfeaf0CQpoZk</code>), and we need to know which port
  11883. Synapse's <a href="usage/administration/admin_api/../../configuration/config_documentation.html#listeners"><code>client</code> listener</a> is listening
  11884. on (e.g. <code>8008</code>). Then we can use the following command to request the account
  11885. information from the Admin API.</p>
  11886. <pre><code class="language-sh">curl --header &quot;Authorization: Bearer syt_AjfVef2_L33JNpafeif_0feKJfeaf0CQpoZk&quot; -X GET http://127.0.0.1:8008/_synapse/admin/v2/users/@foo:bar.com
  11887. </code></pre>
  11888. <p>For more details on access tokens in Matrix, please refer to the complete
  11889. <a href="https://matrix.org/docs/spec/client_server/r0.6.1#using-access-tokens">matrix spec documentation</a>.</p>
  11890. <div style="break-before: page; page-break-before: always;"></div><h1 id="account-validity-api"><a class="header" href="#account-validity-api">Account validity API</a></h1>
  11891. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  11892. <p>This API allows a server administrator to manage the validity of an account. To
  11893. use it, you must enable the account validity feature (under
  11894. <code>account_validity</code>) in Synapse's configuration.</p>
  11895. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  11896. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  11897. <h2 id="renew-account"><a class="header" href="#renew-account">Renew account</a></h2>
  11898. <p>This API extends the validity of an account by as much time as configured in the
  11899. <code>period</code> parameter from the <code>account_validity</code> configuration.</p>
  11900. <p>The API is:</p>
  11901. <pre><code>POST /_synapse/admin/v1/account_validity/validity
  11902. </code></pre>
  11903. <p>with the following body:</p>
  11904. <pre><code class="language-json">{
  11905. &quot;user_id&quot;: &quot;&lt;user ID for the account to renew&gt;&quot;,
  11906. &quot;expiration_ts&quot;: 0,
  11907. &quot;enable_renewal_emails&quot;: true
  11908. }
  11909. </code></pre>
  11910. <p><code>expiration_ts</code> is an optional parameter and overrides the expiration date,
  11911. which otherwise defaults to now + validity period.</p>
  11912. <p><code>enable_renewal_emails</code> is also an optional parameter and enables/disables
  11913. sending renewal emails to the user. Defaults to true.</p>
  11914. <p>The API returns with the new expiration date for this account, as a timestamp in
  11915. milliseconds since epoch:</p>
  11916. <pre><code class="language-json">{
  11917. &quot;expiration_ts&quot;: 0
  11918. }
  11919. </code></pre>
  11920. <div style="break-before: page; page-break-before: always;"></div><h1 id="background-updates-api"><a class="header" href="#background-updates-api">Background Updates API</a></h1>
  11921. <p>This API allows a server administrator to manage the background updates being
  11922. run against the database.</p>
  11923. <h2 id="status"><a class="header" href="#status">Status</a></h2>
  11924. <p>This API gets the current status of the background updates.</p>
  11925. <p>The API is:</p>
  11926. <pre><code>GET /_synapse/admin/v1/background_updates/status
  11927. </code></pre>
  11928. <p>Returning:</p>
  11929. <pre><code class="language-json">{
  11930. &quot;enabled&quot;: true,
  11931. &quot;current_updates&quot;: {
  11932. &quot;&lt;db_name&gt;&quot;: {
  11933. &quot;name&quot;: &quot;&lt;background_update_name&gt;&quot;,
  11934. &quot;total_item_count&quot;: 50,
  11935. &quot;total_duration_ms&quot;: 10000.0,
  11936. &quot;average_items_per_ms&quot;: 2.2,
  11937. },
  11938. }
  11939. }
  11940. </code></pre>
  11941. <p><code>enabled</code> whether the background updates are enabled or disabled.</p>
  11942. <p><code>db_name</code> the database name (usually Synapse is configured with a single database named 'master').</p>
  11943. <p>For each update:</p>
  11944. <p><code>name</code> the name of the update.
  11945. <code>total_item_count</code> total number of &quot;items&quot; processed (the meaning of 'items' depends on the update in question).
  11946. <code>total_duration_ms</code> how long the background process has been running, not including time spent sleeping.
  11947. <code>average_items_per_ms</code> how many items are processed per millisecond based on an exponential average.</p>
  11948. <h2 id="enabled"><a class="header" href="#enabled">Enabled</a></h2>
  11949. <p>This API allow pausing background updates.</p>
  11950. <p>Background updates should <em>not</em> be paused for significant periods of time, as
  11951. this can affect the performance of Synapse.</p>
  11952. <p><em>Note</em>: This won't persist over restarts.</p>
  11953. <p><em>Note</em>: This won't cancel any update query that is currently running. This is
  11954. usually fine since most queries are short lived, except for <code>CREATE INDEX</code>
  11955. background updates which won't be cancelled once started.</p>
  11956. <p>The API is:</p>
  11957. <pre><code>POST /_synapse/admin/v1/background_updates/enabled
  11958. </code></pre>
  11959. <p>with the following body:</p>
  11960. <pre><code class="language-json">{
  11961. &quot;enabled&quot;: false
  11962. }
  11963. </code></pre>
  11964. <p><code>enabled</code> sets whether the background updates are enabled or disabled.</p>
  11965. <p>The API returns the <code>enabled</code> param.</p>
  11966. <pre><code class="language-json">{
  11967. &quot;enabled&quot;: false
  11968. }
  11969. </code></pre>
  11970. <p>There is also a <code>GET</code> version which returns the <code>enabled</code> state.</p>
  11971. <h2 id="run"><a class="header" href="#run">Run</a></h2>
  11972. <p>This API schedules a specific background update to run. The job starts immediately after calling the API.</p>
  11973. <p>The API is:</p>
  11974. <pre><code>POST /_synapse/admin/v1/background_updates/start_job
  11975. </code></pre>
  11976. <p>with the following body:</p>
  11977. <pre><code class="language-json">{
  11978. &quot;job_name&quot;: &quot;populate_stats_process_rooms&quot;
  11979. }
  11980. </code></pre>
  11981. <p>The following JSON body parameters are available:</p>
  11982. <ul>
  11983. <li><code>job_name</code> - A string which job to run. Valid values are:
  11984. <ul>
  11985. <li><code>populate_stats_process_rooms</code> - Recalculate the stats for all rooms.</li>
  11986. <li><code>regenerate_directory</code> - Recalculate the <a href="usage/administration/admin_api/../../../user_directory.html">user directory</a> if it is stale or out of sync.</li>
  11987. </ul>
  11988. </li>
  11989. </ul>
  11990. <div style="break-before: page; page-break-before: always;"></div><h1 id="show-reported-events"><a class="header" href="#show-reported-events">Show reported events</a></h1>
  11991. <p>This API returns information about reported events.</p>
  11992. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  11993. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  11994. <p>The api is:</p>
  11995. <pre><code>GET /_synapse/admin/v1/event_reports?from=0&amp;limit=10
  11996. </code></pre>
  11997. <p>It returns a JSON body like the following:</p>
  11998. <pre><code class="language-json">{
  11999. &quot;event_reports&quot;: [
  12000. {
  12001. &quot;event_id&quot;: &quot;$bNUFCwGzWca1meCGkjp-zwslF-GfVcXukvRLI1_FaVY&quot;,
  12002. &quot;id&quot;: 2,
  12003. &quot;reason&quot;: &quot;foo&quot;,
  12004. &quot;score&quot;: -100,
  12005. &quot;received_ts&quot;: 1570897107409,
  12006. &quot;canonical_alias&quot;: &quot;#alias1:matrix.org&quot;,
  12007. &quot;room_id&quot;: &quot;!ERAgBpSOcCCuTJqQPk:matrix.org&quot;,
  12008. &quot;name&quot;: &quot;Matrix HQ&quot;,
  12009. &quot;sender&quot;: &quot;@foobar:matrix.org&quot;,
  12010. &quot;user_id&quot;: &quot;@foo:matrix.org&quot;
  12011. },
  12012. {
  12013. &quot;event_id&quot;: &quot;$3IcdZsDaN_En-S1DF4EMCy3v4gNRKeOJs8W5qTOKj4I&quot;,
  12014. &quot;id&quot;: 3,
  12015. &quot;reason&quot;: &quot;bar&quot;,
  12016. &quot;score&quot;: -100,
  12017. &quot;received_ts&quot;: 1598889612059,
  12018. &quot;canonical_alias&quot;: &quot;#alias2:matrix.org&quot;,
  12019. &quot;room_id&quot;: &quot;!eGvUQuTCkHGVwNMOjv:matrix.org&quot;,
  12020. &quot;name&quot;: &quot;Your room name here&quot;,
  12021. &quot;sender&quot;: &quot;@foobar:matrix.org&quot;,
  12022. &quot;user_id&quot;: &quot;@bar:matrix.org&quot;
  12023. }
  12024. ],
  12025. &quot;next_token&quot;: 2,
  12026. &quot;total&quot;: 4
  12027. }
  12028. </code></pre>
  12029. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint again with <code>from</code>
  12030. set to the value of <code>next_token</code>. This will return a new page.</p>
  12031. <p>If the endpoint does not return a <code>next_token</code> then there are no more reports to
  12032. paginate through.</p>
  12033. <p><strong>URL parameters:</strong></p>
  12034. <ul>
  12035. <li><code>limit</code>: integer - Is optional but is used for pagination, denoting the maximum number
  12036. of items to return in this call. Defaults to <code>100</code>.</li>
  12037. <li><code>from</code>: integer - Is optional but used for pagination, denoting the offset in the
  12038. returned results. This should be treated as an opaque value and not explicitly set to
  12039. anything other than the return value of <code>next_token</code> from a previous call. Defaults to <code>0</code>.</li>
  12040. <li><code>dir</code>: string - Direction of event report order. Whether to fetch the most recent
  12041. first (<code>b</code>) or the oldest first (<code>f</code>). Defaults to <code>b</code>.</li>
  12042. <li><code>user_id</code>: string - Is optional and filters to only return users with user IDs that
  12043. contain this value. This is the user who reported the event and wrote the reason.</li>
  12044. <li><code>room_id</code>: string - Is optional and filters to only return rooms with room IDs that
  12045. contain this value.</li>
  12046. </ul>
  12047. <p><strong>Response</strong></p>
  12048. <p>The following fields are returned in the JSON response body:</p>
  12049. <ul>
  12050. <li><code>id</code>: integer - ID of event report.</li>
  12051. <li><code>received_ts</code>: integer - The timestamp (in milliseconds since the unix epoch) when this
  12052. report was sent.</li>
  12053. <li><code>room_id</code>: string - The ID of the room in which the event being reported is located.</li>
  12054. <li><code>name</code>: string - The name of the room.</li>
  12055. <li><code>event_id</code>: string - The ID of the reported event.</li>
  12056. <li><code>user_id</code>: string - This is the user who reported the event and wrote the reason.</li>
  12057. <li><code>reason</code>: string - Comment made by the <code>user_id</code> in this report. May be blank or <code>null</code>.</li>
  12058. <li><code>score</code>: integer - Content is reported based upon a negative score, where -100 is
  12059. &quot;most offensive&quot; and 0 is &quot;inoffensive&quot;. May be <code>null</code>.</li>
  12060. <li><code>sender</code>: string - This is the ID of the user who sent the original message/event that
  12061. was reported.</li>
  12062. <li><code>canonical_alias</code>: string - The canonical alias of the room. <code>null</code> if the room does not
  12063. have a canonical alias set.</li>
  12064. <li><code>next_token</code>: integer - Indication for pagination. See above.</li>
  12065. <li><code>total</code>: integer - Total number of event reports related to the query
  12066. (<code>user_id</code> and <code>room_id</code>).</li>
  12067. </ul>
  12068. <h1 id="show-details-of-a-specific-event-report"><a class="header" href="#show-details-of-a-specific-event-report">Show details of a specific event report</a></h1>
  12069. <p>This API returns information about a specific event report.</p>
  12070. <p>The api is:</p>
  12071. <pre><code>GET /_synapse/admin/v1/event_reports/&lt;report_id&gt;
  12072. </code></pre>
  12073. <p>It returns a JSON body like the following:</p>
  12074. <pre><code class="language-json">{
  12075. &quot;event_id&quot;: &quot;$bNUFCwGzWca1meCGkjp-zwslF-GfVcXukvRLI1_FaVY&quot;,
  12076. &quot;event_json&quot;: {
  12077. &quot;auth_events&quot;: [
  12078. &quot;$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M&quot;,
  12079. &quot;$oggsNXxzPFRE3y53SUNd7nsj69-QzKv03a1RucHu-ws&quot;
  12080. ],
  12081. &quot;content&quot;: {
  12082. &quot;body&quot;: &quot;matrix.org: This Week in Matrix&quot;,
  12083. &quot;format&quot;: &quot;org.matrix.custom.html&quot;,
  12084. &quot;formatted_body&quot;: &quot;&lt;strong&gt;matrix.org&lt;/strong&gt;:&lt;br&gt;&lt;a href=\&quot;https://matrix.org/blog/\&quot;&gt;&lt;strong&gt;This Week in Matrix&lt;/strong&gt;&lt;/a&gt;&quot;,
  12085. &quot;msgtype&quot;: &quot;m.notice&quot;
  12086. },
  12087. &quot;depth&quot;: 546,
  12088. &quot;hashes&quot;: {
  12089. &quot;sha256&quot;: &quot;xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw&quot;
  12090. },
  12091. &quot;origin&quot;: &quot;matrix.org&quot;,
  12092. &quot;origin_server_ts&quot;: 1592291711430,
  12093. &quot;prev_events&quot;: [
  12094. &quot;$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M&quot;
  12095. ],
  12096. &quot;prev_state&quot;: [],
  12097. &quot;room_id&quot;: &quot;!ERAgBpSOcCCuTJqQPk:matrix.org&quot;,
  12098. &quot;sender&quot;: &quot;@foobar:matrix.org&quot;,
  12099. &quot;signatures&quot;: {
  12100. &quot;matrix.org&quot;: {
  12101. &quot;ed25519:a_JaEG&quot;: &quot;cs+OUKW/iHx5pEidbWxh0UiNNHwe46Ai9LwNz+Ah16aWDNszVIe2gaAcVZfvNsBhakQTew51tlKmL2kspXk/Dg&quot;
  12102. }
  12103. },
  12104. &quot;type&quot;: &quot;m.room.message&quot;,
  12105. &quot;unsigned&quot;: {
  12106. &quot;age_ts&quot;: 1592291711430
  12107. }
  12108. },
  12109. &quot;id&quot;: &lt;report_id&gt;,
  12110. &quot;reason&quot;: &quot;foo&quot;,
  12111. &quot;score&quot;: -100,
  12112. &quot;received_ts&quot;: 1570897107409,
  12113. &quot;canonical_alias&quot;: &quot;#alias1:matrix.org&quot;,
  12114. &quot;room_id&quot;: &quot;!ERAgBpSOcCCuTJqQPk:matrix.org&quot;,
  12115. &quot;name&quot;: &quot;Matrix HQ&quot;,
  12116. &quot;sender&quot;: &quot;@foobar:matrix.org&quot;,
  12117. &quot;user_id&quot;: &quot;@foo:matrix.org&quot;
  12118. }
  12119. </code></pre>
  12120. <p><strong>URL parameters:</strong></p>
  12121. <ul>
  12122. <li><code>report_id</code>: string - The ID of the event report.</li>
  12123. </ul>
  12124. <p><strong>Response</strong></p>
  12125. <p>The following fields are returned in the JSON response body:</p>
  12126. <ul>
  12127. <li><code>id</code>: integer - ID of event report.</li>
  12128. <li><code>received_ts</code>: integer - The timestamp (in milliseconds since the unix epoch) when this
  12129. report was sent.</li>
  12130. <li><code>room_id</code>: string - The ID of the room in which the event being reported is located.</li>
  12131. <li><code>name</code>: string - The name of the room.</li>
  12132. <li><code>event_id</code>: string - The ID of the reported event.</li>
  12133. <li><code>user_id</code>: string - This is the user who reported the event and wrote the reason.</li>
  12134. <li><code>reason</code>: string - Comment made by the <code>user_id</code> in this report. May be blank.</li>
  12135. <li><code>score</code>: integer - Content is reported based upon a negative score, where -100 is
  12136. &quot;most offensive&quot; and 0 is &quot;inoffensive&quot;.</li>
  12137. <li><code>sender</code>: string - This is the ID of the user who sent the original message/event that
  12138. was reported.</li>
  12139. <li><code>canonical_alias</code>: string - The canonical alias of the room. <code>null</code> if the room does not
  12140. have a canonical alias set.</li>
  12141. <li><code>event_json</code>: object - Details of the original event that was reported.</li>
  12142. </ul>
  12143. <h1 id="delete-a-specific-event-report"><a class="header" href="#delete-a-specific-event-report">Delete a specific event report</a></h1>
  12144. <p>This API deletes a specific event report. If the request is successful, the response body
  12145. will be an empty JSON object.</p>
  12146. <p>The api is:</p>
  12147. <pre><code>DELETE /_synapse/admin/v1/event_reports/&lt;report_id&gt;
  12148. </code></pre>
  12149. <p><strong>URL parameters:</strong></p>
  12150. <ul>
  12151. <li><code>report_id</code>: string - The ID of the event report.</li>
  12152. </ul>
  12153. <div style="break-before: page; page-break-before: always;"></div><h1 id="experimental-features-api"><a class="header" href="#experimental-features-api">Experimental Features API</a></h1>
  12154. <p>This API allows a server administrator to enable or disable some experimental features on a per-user
  12155. basis. The currently supported features are: </p>
  12156. <ul>
  12157. <li><a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3026">MSC3026</a>: busy
  12158. presence state enabled</li>
  12159. <li><a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3881">MSC3881</a>: enable remotely toggling push notifications
  12160. for another client </li>
  12161. <li><a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3967">MSC3967</a>: do not require
  12162. UIA when first uploading cross-signing keys. </li>
  12163. </ul>
  12164. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  12165. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  12166. <h2 id="enablingdisabling-features"><a class="header" href="#enablingdisabling-features">Enabling/Disabling Features</a></h2>
  12167. <p>This API allows a server administrator to enable experimental features for a given user. The request must
  12168. provide a body containing the user id and listing the features to enable/disable in the following format:</p>
  12169. <pre><code class="language-json">{
  12170. &quot;features&quot;: {
  12171. &quot;msc3026&quot;:true,
  12172. &quot;msc3881&quot;:true
  12173. }
  12174. }
  12175. </code></pre>
  12176. <p>where true is used to enable the feature, and false is used to disable the feature.</p>
  12177. <p>The API is:</p>
  12178. <pre><code>PUT /_synapse/admin/v1/experimental_features/&lt;user_id&gt;
  12179. </code></pre>
  12180. <h2 id="listing-enabled-features"><a class="header" href="#listing-enabled-features">Listing Enabled Features</a></h2>
  12181. <p>To list which features are enabled/disabled for a given user send a request to the following API:</p>
  12182. <pre><code>GET /_synapse/admin/v1/experimental_features/&lt;user_id&gt;
  12183. </code></pre>
  12184. <p>It will return a list of possible features and indicate whether they are enabled or disabled for the
  12185. user like so:</p>
  12186. <pre><code class="language-json">{
  12187. &quot;features&quot;: {
  12188. &quot;msc3026&quot;: true,
  12189. &quot;msc3881&quot;: false,
  12190. &quot;msc3967&quot;: false
  12191. }
  12192. }
  12193. </code></pre>
  12194. <div style="break-before: page; page-break-before: always;"></div><h1 id="querying-media"><a class="header" href="#querying-media">Querying media</a></h1>
  12195. <p>These APIs allow extracting media information from the homeserver.</p>
  12196. <p>Details about the format of the <code>media_id</code> and storage of the media in the file system
  12197. are documented under <a href="admin_api/../media_repository.html">media repository</a>.</p>
  12198. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  12199. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  12200. <h2 id="list-all-media-in-a-room"><a class="header" href="#list-all-media-in-a-room">List all media in a room</a></h2>
  12201. <p>This API gets a list of known media in a room.
  12202. However, it only shows media from unencrypted events or rooms.</p>
  12203. <p>The API is:</p>
  12204. <pre><code>GET /_synapse/admin/v1/room/&lt;room_id&gt;/media
  12205. </code></pre>
  12206. <p>The API returns a JSON body like the following:</p>
  12207. <pre><code class="language-json">{
  12208. &quot;local&quot;: [
  12209. &quot;mxc://localhost/xwvutsrqponmlkjihgfedcba&quot;,
  12210. &quot;mxc://localhost/abcdefghijklmnopqrstuvwx&quot;
  12211. ],
  12212. &quot;remote&quot;: [
  12213. &quot;mxc://matrix.org/xwvutsrqponmlkjihgfedcba&quot;,
  12214. &quot;mxc://matrix.org/abcdefghijklmnopqrstuvwx&quot;
  12215. ]
  12216. }
  12217. </code></pre>
  12218. <h2 id="list-all-media-uploaded-by-a-user"><a class="header" href="#list-all-media-uploaded-by-a-user">List all media uploaded by a user</a></h2>
  12219. <p>Listing all media that has been uploaded by a local user can be achieved through
  12220. the use of the
  12221. <a href="admin_api/user_admin_api.html#list-media-uploaded-by-a-user">List media uploaded by a user</a>
  12222. Admin API.</p>
  12223. <h1 id="quarantine-media"><a class="header" href="#quarantine-media">Quarantine media</a></h1>
  12224. <p>Quarantining media means that it is marked as inaccessible by users. It applies
  12225. to any local media, and any locally-cached copies of remote media.</p>
  12226. <p>The media file itself (and any thumbnails) is not deleted from the server.</p>
  12227. <h2 id="quarantining-media-by-id"><a class="header" href="#quarantining-media-by-id">Quarantining media by ID</a></h2>
  12228. <p>This API quarantines a single piece of local or remote media.</p>
  12229. <p>Request:</p>
  12230. <pre><code>POST /_synapse/admin/v1/media/quarantine/&lt;server_name&gt;/&lt;media_id&gt;
  12231. {}
  12232. </code></pre>
  12233. <p>Where <code>server_name</code> is in the form of <code>example.org</code>, and <code>media_id</code> is in the
  12234. form of <code>abcdefg12345...</code>.</p>
  12235. <p>Response:</p>
  12236. <pre><code class="language-json">{}
  12237. </code></pre>
  12238. <h2 id="remove-media-from-quarantine-by-id"><a class="header" href="#remove-media-from-quarantine-by-id">Remove media from quarantine by ID</a></h2>
  12239. <p>This API removes a single piece of local or remote media from quarantine.</p>
  12240. <p>Request:</p>
  12241. <pre><code>POST /_synapse/admin/v1/media/unquarantine/&lt;server_name&gt;/&lt;media_id&gt;
  12242. {}
  12243. </code></pre>
  12244. <p>Where <code>server_name</code> is in the form of <code>example.org</code>, and <code>media_id</code> is in the
  12245. form of <code>abcdefg12345...</code>.</p>
  12246. <p>Response:</p>
  12247. <pre><code class="language-json">{}
  12248. </code></pre>
  12249. <h2 id="quarantining-media-in-a-room"><a class="header" href="#quarantining-media-in-a-room">Quarantining media in a room</a></h2>
  12250. <p>This API quarantines all local and remote media in a room.</p>
  12251. <p>Request:</p>
  12252. <pre><code>POST /_synapse/admin/v1/room/&lt;room_id&gt;/media/quarantine
  12253. {}
  12254. </code></pre>
  12255. <p>Where <code>room_id</code> is in the form of <code>!roomid12345:example.org</code>.</p>
  12256. <p>Response:</p>
  12257. <pre><code class="language-json">{
  12258. &quot;num_quarantined&quot;: 10
  12259. }
  12260. </code></pre>
  12261. <p>The following fields are returned in the JSON response body:</p>
  12262. <ul>
  12263. <li><code>num_quarantined</code>: integer - The number of media items successfully quarantined</li>
  12264. </ul>
  12265. <p>Note that there is a legacy endpoint, <code>POST /_synapse/admin/v1/quarantine_media/&lt;room_id&gt;</code>, that operates the same.
  12266. However, it is deprecated and may be removed in a future release.</p>
  12267. <h2 id="quarantining-all-media-of-a-user"><a class="header" href="#quarantining-all-media-of-a-user">Quarantining all media of a user</a></h2>
  12268. <p>This API quarantines all <em>local</em> media that a <em>local</em> user has uploaded. That is to say, if
  12269. you would like to quarantine media uploaded by a user on a remote homeserver, you should
  12270. instead use one of the other APIs.</p>
  12271. <p>Request:</p>
  12272. <pre><code>POST /_synapse/admin/v1/user/&lt;user_id&gt;/media/quarantine
  12273. {}
  12274. </code></pre>
  12275. <p>URL Parameters</p>
  12276. <ul>
  12277. <li><code>user_id</code>: string - User ID in the form of <code>@bob:example.org</code></li>
  12278. </ul>
  12279. <p>Response:</p>
  12280. <pre><code class="language-json">{
  12281. &quot;num_quarantined&quot;: 10
  12282. }
  12283. </code></pre>
  12284. <p>The following fields are returned in the JSON response body:</p>
  12285. <ul>
  12286. <li><code>num_quarantined</code>: integer - The number of media items successfully quarantined</li>
  12287. </ul>
  12288. <h2 id="protecting-media-from-being-quarantined"><a class="header" href="#protecting-media-from-being-quarantined">Protecting media from being quarantined</a></h2>
  12289. <p>This API protects a single piece of local media from being quarantined using the
  12290. above APIs. This is useful for sticker packs and other shared media which you do
  12291. not want to get quarantined, especially when
  12292. <a href="admin_api/media_admin_api.html#quarantining-media-in-a-room">quarantining media in a room</a>.</p>
  12293. <p>Request:</p>
  12294. <pre><code>POST /_synapse/admin/v1/media/protect/&lt;media_id&gt;
  12295. {}
  12296. </code></pre>
  12297. <p>Where <code>media_id</code> is in the form of <code>abcdefg12345...</code>.</p>
  12298. <p>Response:</p>
  12299. <pre><code class="language-json">{}
  12300. </code></pre>
  12301. <h2 id="unprotecting-media-from-being-quarantined"><a class="header" href="#unprotecting-media-from-being-quarantined">Unprotecting media from being quarantined</a></h2>
  12302. <p>This API reverts the protection of a media.</p>
  12303. <p>Request:</p>
  12304. <pre><code>POST /_synapse/admin/v1/media/unprotect/&lt;media_id&gt;
  12305. {}
  12306. </code></pre>
  12307. <p>Where <code>media_id</code> is in the form of <code>abcdefg12345...</code>.</p>
  12308. <p>Response:</p>
  12309. <pre><code class="language-json">{}
  12310. </code></pre>
  12311. <h1 id="delete-local-media"><a class="header" href="#delete-local-media">Delete local media</a></h1>
  12312. <p>This API deletes the <em>local</em> media from the disk of your own server.
  12313. This includes any local thumbnails and copies of media downloaded from
  12314. remote homeservers.
  12315. This API will not affect media that has been uploaded to external
  12316. media repositories (e.g https://github.com/turt2live/matrix-media-repo/).
  12317. See also <a href="admin_api/media_admin_api.html#purge-remote-media-api">Purge Remote Media API</a>.</p>
  12318. <h2 id="delete-a-specific-local-media"><a class="header" href="#delete-a-specific-local-media">Delete a specific local media</a></h2>
  12319. <p>Delete a specific <code>media_id</code>.</p>
  12320. <p>Request:</p>
  12321. <pre><code>DELETE /_synapse/admin/v1/media/&lt;server_name&gt;/&lt;media_id&gt;
  12322. {}
  12323. </code></pre>
  12324. <p>URL Parameters</p>
  12325. <ul>
  12326. <li><code>server_name</code>: string - The name of your local server (e.g <code>matrix.org</code>)</li>
  12327. <li><code>media_id</code>: string - The ID of the media (e.g <code>abcdefghijklmnopqrstuvwx</code>)</li>
  12328. </ul>
  12329. <p>Response:</p>
  12330. <pre><code class="language-json">{
  12331. &quot;deleted_media&quot;: [
  12332. &quot;abcdefghijklmnopqrstuvwx&quot;
  12333. ],
  12334. &quot;total&quot;: 1
  12335. }
  12336. </code></pre>
  12337. <p>The following fields are returned in the JSON response body:</p>
  12338. <ul>
  12339. <li><code>deleted_media</code>: an array of strings - List of deleted <code>media_id</code></li>
  12340. <li><code>total</code>: integer - Total number of deleted <code>media_id</code></li>
  12341. </ul>
  12342. <h2 id="delete-local-media-by-date-or-size"><a class="header" href="#delete-local-media-by-date-or-size">Delete local media by date or size</a></h2>
  12343. <p>Request:</p>
  12344. <pre><code>POST /_synapse/admin/v1/media/delete?before_ts=&lt;before_ts&gt;
  12345. {}
  12346. </code></pre>
  12347. <p><em>Deprecated in Synapse v1.78.0:</em> This API is available at the deprecated endpoint:</p>
  12348. <pre><code>POST /_synapse/admin/v1/media/&lt;server_name&gt;/delete?before_ts=&lt;before_ts&gt;
  12349. {}
  12350. </code></pre>
  12351. <p>URL Parameters</p>
  12352. <ul>
  12353. <li><code>server_name</code>: string - The name of your local server (e.g <code>matrix.org</code>). <em>Deprecated in Synapse v1.78.0.</em></li>
  12354. <li><code>before_ts</code>: string representing a positive integer - Unix timestamp in milliseconds.
  12355. Files that were last used before this timestamp will be deleted. It is the timestamp of
  12356. last access, not the timestamp when the file was created.</li>
  12357. <li><code>size_gt</code>: Optional - string representing a positive integer - Size of the media in bytes.
  12358. Files that are larger will be deleted. Defaults to <code>0</code>.</li>
  12359. <li><code>keep_profiles</code>: Optional - string representing a boolean - Switch to also delete files
  12360. that are still used in image data (e.g user profile, room avatar).
  12361. If <code>false</code> these files will be deleted. Defaults to <code>true</code>.</li>
  12362. </ul>
  12363. <p>Response:</p>
  12364. <pre><code class="language-json">{
  12365. &quot;deleted_media&quot;: [
  12366. &quot;abcdefghijklmnopqrstuvwx&quot;,
  12367. &quot;abcdefghijklmnopqrstuvwz&quot;
  12368. ],
  12369. &quot;total&quot;: 2
  12370. }
  12371. </code></pre>
  12372. <p>The following fields are returned in the JSON response body:</p>
  12373. <ul>
  12374. <li><code>deleted_media</code>: an array of strings - List of deleted <code>media_id</code></li>
  12375. <li><code>total</code>: integer - Total number of deleted <code>media_id</code></li>
  12376. </ul>
  12377. <h2 id="delete-media-uploaded-by-a-user"><a class="header" href="#delete-media-uploaded-by-a-user">Delete media uploaded by a user</a></h2>
  12378. <p>You can find details of how to delete multiple media uploaded by a user in
  12379. <a href="admin_api/user_admin_api.html#delete-media-uploaded-by-a-user">User Admin API</a>.</p>
  12380. <h1 id="purge-remote-media-api"><a class="header" href="#purge-remote-media-api">Purge Remote Media API</a></h1>
  12381. <p>The purge remote media API allows server admins to purge old cached remote media.</p>
  12382. <p>The API is:</p>
  12383. <pre><code>POST /_synapse/admin/v1/purge_media_cache?before_ts=&lt;unix_timestamp_in_ms&gt;
  12384. {}
  12385. </code></pre>
  12386. <p>URL Parameters</p>
  12387. <ul>
  12388. <li><code>before_ts</code>: string representing a positive integer - Unix timestamp in milliseconds.
  12389. All cached media that was last accessed before this timestamp will be removed.</li>
  12390. </ul>
  12391. <p>Response:</p>
  12392. <pre><code class="language-json">{
  12393. &quot;deleted&quot;: 10
  12394. }
  12395. </code></pre>
  12396. <p>The following fields are returned in the JSON response body:</p>
  12397. <ul>
  12398. <li><code>deleted</code>: integer - The number of media items successfully deleted</li>
  12399. </ul>
  12400. <p>If the user re-requests purged remote media, synapse will re-request the media
  12401. from the originating server.</p>
  12402. <div style="break-before: page; page-break-before: always;"></div><h1 id="purge-history-api"><a class="header" href="#purge-history-api">Purge History API</a></h1>
  12403. <p>The purge history API allows server admins to purge historic events from their
  12404. database, reclaiming disk space.</p>
  12405. <p>Depending on the amount of history being purged a call to the API may take
  12406. several minutes or longer. During this period users will not be able to
  12407. paginate further back in the room from the point being purged from.</p>
  12408. <p>Note that Synapse requires at least one message in each room, so it will never
  12409. delete the last message in a room.</p>
  12410. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  12411. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  12412. <p>The API is:</p>
  12413. <pre><code>POST /_synapse/admin/v1/purge_history/&lt;room_id&gt;[/&lt;event_id&gt;]
  12414. </code></pre>
  12415. <p>By default, events sent by local users are not deleted, as they may represent
  12416. the only copies of this content in existence. (Events sent by remote users are
  12417. deleted.)</p>
  12418. <p>Room state data (such as joins, leaves, topic) is always preserved.</p>
  12419. <p>To delete local message events as well, set <code>delete_local_events</code> in the body:</p>
  12420. <pre><code class="language-json">{
  12421. &quot;delete_local_events&quot;: true
  12422. }
  12423. </code></pre>
  12424. <p>The caller must specify the point in the room to purge up to. This can be
  12425. specified by including an event_id in the URI, or by setting a
  12426. <code>purge_up_to_event_id</code> or <code>purge_up_to_ts</code> in the request body. If an event
  12427. id is given, that event (and others at the same graph depth) will be retained.
  12428. If <code>purge_up_to_ts</code> is given, it should be a timestamp since the unix epoch,
  12429. in milliseconds.</p>
  12430. <p>The API starts the purge running, and returns immediately with a JSON body with
  12431. a purge id:</p>
  12432. <pre><code class="language-json">{
  12433. &quot;purge_id&quot;: &quot;&lt;opaque id&gt;&quot;
  12434. }
  12435. </code></pre>
  12436. <h2 id="purge-status-query"><a class="header" href="#purge-status-query">Purge status query</a></h2>
  12437. <p>It is possible to poll for updates on recent purges with a second API;</p>
  12438. <pre><code>GET /_synapse/admin/v1/purge_history_status/&lt;purge_id&gt;
  12439. </code></pre>
  12440. <p>This API returns a JSON body like the following:</p>
  12441. <pre><code class="language-json">{
  12442. &quot;status&quot;: &quot;active&quot;
  12443. }
  12444. </code></pre>
  12445. <p>The status will be one of <code>active</code>, <code>complete</code>, or <code>failed</code>.</p>
  12446. <p>If <code>status</code> is <code>failed</code> there will be a string <code>error</code> with the error message.</p>
  12447. <h2 id="reclaim-disk-space-postgres"><a class="header" href="#reclaim-disk-space-postgres">Reclaim disk space (Postgres)</a></h2>
  12448. <p>To reclaim the disk space and return it to the operating system, you need to run
  12449. <code>VACUUM FULL;</code> on the database.</p>
  12450. <p><a href="https://www.postgresql.org/docs/current/sql-vacuum.html">https://www.postgresql.org/docs/current/sql-vacuum.html</a></p>
  12451. <div style="break-before: page; page-break-before: always;"></div><h1 id="shared-secret-registration"><a class="header" href="#shared-secret-registration">Shared-Secret Registration</a></h1>
  12452. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  12453. <p>This API allows for the creation of users in an administrative and
  12454. non-interactive way. This is generally used for bootstrapping a Synapse
  12455. instance with administrator accounts.</p>
  12456. <p>To authenticate yourself to the server, you will need both the shared secret
  12457. (<a href="admin_api/../usage/configuration/config_documentation.html#registration_shared_secret"><code>registration_shared_secret</code></a>
  12458. in the homeserver configuration), and a one-time nonce. If the registration
  12459. shared secret is not configured, this API is not enabled.</p>
  12460. <p>To fetch the nonce, you need to request one from the API:</p>
  12461. <pre><code>&gt; GET /_synapse/admin/v1/register
  12462. &lt; {&quot;nonce&quot;: &quot;thisisanonce&quot;}
  12463. </code></pre>
  12464. <p>Once you have the nonce, you can make a <code>POST</code> to the same URL with a JSON
  12465. body containing the nonce, username, password, whether they are an admin
  12466. (optional, False by default), and a HMAC digest of the content. Also you can
  12467. set the displayname (optional, <code>username</code> by default).</p>
  12468. <p>As an example:</p>
  12469. <pre><code>&gt; POST /_synapse/admin/v1/register
  12470. &gt; {
  12471. &quot;nonce&quot;: &quot;thisisanonce&quot;,
  12472. &quot;username&quot;: &quot;pepper_roni&quot;,
  12473. &quot;displayname&quot;: &quot;Pepper Roni&quot;,
  12474. &quot;password&quot;: &quot;pizza&quot;,
  12475. &quot;admin&quot;: true,
  12476. &quot;mac&quot;: &quot;mac_digest_here&quot;
  12477. }
  12478. &lt; {
  12479. &quot;access_token&quot;: &quot;token_here&quot;,
  12480. &quot;user_id&quot;: &quot;@pepper_roni:localhost&quot;,
  12481. &quot;home_server&quot;: &quot;test&quot;,
  12482. &quot;device_id&quot;: &quot;device_id_here&quot;
  12483. }
  12484. </code></pre>
  12485. <p>The MAC is the hex digest output of the HMAC-SHA1 algorithm, with the key being
  12486. the shared secret and the content being the nonce, user, password, either the
  12487. string &quot;admin&quot; or &quot;notadmin&quot;, and optionally the user_type
  12488. each separated by NULs.</p>
  12489. <p>Here is an easy way to generate the HMAC digest if you have Bash and OpenSSL:</p>
  12490. <pre><code class="language-bash"># Update these values and then paste this code block into a bash terminal
  12491. nonce='thisisanonce'
  12492. username='pepper_roni'
  12493. password='pizza'
  12494. admin='admin'
  12495. secret='shared_secret'
  12496. printf '%s\0%s\0%s\0%s' &quot;$nonce&quot; &quot;$username&quot; &quot;$password&quot; &quot;$admin&quot; |
  12497. openssl sha1 -hmac &quot;$secret&quot; |
  12498. awk '{print $2}'
  12499. </code></pre>
  12500. <p>For an example of generation in Python:</p>
  12501. <pre><code class="language-python">import hmac, hashlib
  12502. def generate_mac(nonce, user, password, admin=False, user_type=None):
  12503. mac = hmac.new(
  12504. key=shared_secret,
  12505. digestmod=hashlib.sha1,
  12506. )
  12507. mac.update(nonce.encode('utf8'))
  12508. mac.update(b&quot;\x00&quot;)
  12509. mac.update(user.encode('utf8'))
  12510. mac.update(b&quot;\x00&quot;)
  12511. mac.update(password.encode('utf8'))
  12512. mac.update(b&quot;\x00&quot;)
  12513. mac.update(b&quot;admin&quot; if admin else b&quot;notadmin&quot;)
  12514. if user_type:
  12515. mac.update(b&quot;\x00&quot;)
  12516. mac.update(user_type.encode('utf8'))
  12517. return mac.hexdigest()
  12518. </code></pre>
  12519. <div style="break-before: page; page-break-before: always;"></div><h1 id="registration-tokens"><a class="header" href="#registration-tokens">Registration Tokens</a></h1>
  12520. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  12521. <p>This API allows you to manage tokens which can be used to authenticate
  12522. registration requests, as proposed in
  12523. <a href="https://github.com/matrix-org/matrix-doc/blob/main/proposals/3231-token-authenticated-registration.md">MSC3231</a>
  12524. and stabilised in version 1.2 of the Matrix specification.
  12525. To use it, you will need to enable the <code>registration_requires_token</code> config
  12526. option, and authenticate by providing an <code>access_token</code> for a server admin:
  12527. see <a href="usage/administration/admin_api/../admin_api/">Admin API</a>.</p>
  12528. <h2 id="registration-token-objects"><a class="header" href="#registration-token-objects">Registration token objects</a></h2>
  12529. <p>Most endpoints make use of JSON objects that contain details about tokens.
  12530. These objects have the following fields:</p>
  12531. <ul>
  12532. <li><code>token</code>: The token which can be used to authenticate registration.</li>
  12533. <li><code>uses_allowed</code>: The number of times the token can be used to complete a
  12534. registration before it becomes invalid.</li>
  12535. <li><code>pending</code>: The number of pending uses the token has. When someone uses
  12536. the token to authenticate themselves, the pending counter is incremented
  12537. so that the token is not used more than the permitted number of times.
  12538. When the person completes registration the pending counter is decremented,
  12539. and the completed counter is incremented.</li>
  12540. <li><code>completed</code>: The number of times the token has been used to successfully
  12541. complete a registration.</li>
  12542. <li><code>expiry_time</code>: The latest time the token is valid. Given as the number of
  12543. milliseconds since 1970-01-01 00:00:00 UTC (the start of the Unix epoch).
  12544. To convert this into a human-readable form you can remove the milliseconds
  12545. and use the <code>date</code> command. For example, <code>date -d '@1625394937'</code>.</li>
  12546. </ul>
  12547. <h2 id="list-all-tokens"><a class="header" href="#list-all-tokens">List all tokens</a></h2>
  12548. <p>Lists all tokens and details about them. If the request is successful, the top
  12549. level JSON object will have a <code>registration_tokens</code> key which is an array of
  12550. registration token objects.</p>
  12551. <pre><code>GET /_synapse/admin/v1/registration_tokens
  12552. </code></pre>
  12553. <p>Optional query parameters:</p>
  12554. <ul>
  12555. <li><code>valid</code>: <code>true</code> or <code>false</code>. If <code>true</code>, only valid tokens are returned.
  12556. If <code>false</code>, only tokens that have expired or have had all uses exhausted are
  12557. returned. If omitted, all tokens are returned regardless of validity.</li>
  12558. </ul>
  12559. <p>Example:</p>
  12560. <pre><code>GET /_synapse/admin/v1/registration_tokens
  12561. </code></pre>
  12562. <pre><code>200 OK
  12563. {
  12564. &quot;registration_tokens&quot;: [
  12565. {
  12566. &quot;token&quot;: &quot;abcd&quot;,
  12567. &quot;uses_allowed&quot;: 3,
  12568. &quot;pending&quot;: 0,
  12569. &quot;completed&quot;: 1,
  12570. &quot;expiry_time&quot;: null
  12571. },
  12572. {
  12573. &quot;token&quot;: &quot;pqrs&quot;,
  12574. &quot;uses_allowed&quot;: 2,
  12575. &quot;pending&quot;: 1,
  12576. &quot;completed&quot;: 1,
  12577. &quot;expiry_time&quot;: null
  12578. },
  12579. {
  12580. &quot;token&quot;: &quot;wxyz&quot;,
  12581. &quot;uses_allowed&quot;: null,
  12582. &quot;pending&quot;: 0,
  12583. &quot;completed&quot;: 9,
  12584. &quot;expiry_time&quot;: 1625394937000 // 2021-07-04 10:35:37 UTC
  12585. }
  12586. ]
  12587. }
  12588. </code></pre>
  12589. <p>Example using the <code>valid</code> query parameter:</p>
  12590. <pre><code>GET /_synapse/admin/v1/registration_tokens?valid=false
  12591. </code></pre>
  12592. <pre><code>200 OK
  12593. {
  12594. &quot;registration_tokens&quot;: [
  12595. {
  12596. &quot;token&quot;: &quot;pqrs&quot;,
  12597. &quot;uses_allowed&quot;: 2,
  12598. &quot;pending&quot;: 1,
  12599. &quot;completed&quot;: 1,
  12600. &quot;expiry_time&quot;: null
  12601. },
  12602. {
  12603. &quot;token&quot;: &quot;wxyz&quot;,
  12604. &quot;uses_allowed&quot;: null,
  12605. &quot;pending&quot;: 0,
  12606. &quot;completed&quot;: 9,
  12607. &quot;expiry_time&quot;: 1625394937000 // 2021-07-04 10:35:37 UTC
  12608. }
  12609. ]
  12610. }
  12611. </code></pre>
  12612. <h2 id="get-one-token"><a class="header" href="#get-one-token">Get one token</a></h2>
  12613. <p>Get details about a single token. If the request is successful, the response
  12614. body will be a registration token object.</p>
  12615. <pre><code>GET /_synapse/admin/v1/registration_tokens/&lt;token&gt;
  12616. </code></pre>
  12617. <p>Path parameters:</p>
  12618. <ul>
  12619. <li><code>token</code>: The registration token to return details of.</li>
  12620. </ul>
  12621. <p>Example:</p>
  12622. <pre><code>GET /_synapse/admin/v1/registration_tokens/abcd
  12623. </code></pre>
  12624. <pre><code>200 OK
  12625. {
  12626. &quot;token&quot;: &quot;abcd&quot;,
  12627. &quot;uses_allowed&quot;: 3,
  12628. &quot;pending&quot;: 0,
  12629. &quot;completed&quot;: 1,
  12630. &quot;expiry_time&quot;: null
  12631. }
  12632. </code></pre>
  12633. <h2 id="create-token"><a class="header" href="#create-token">Create token</a></h2>
  12634. <p>Create a new registration token. If the request is successful, the newly created
  12635. token will be returned as a registration token object in the response body.</p>
  12636. <pre><code>POST /_synapse/admin/v1/registration_tokens/new
  12637. </code></pre>
  12638. <p>The request body must be a JSON object and can contain the following fields:</p>
  12639. <ul>
  12640. <li><code>token</code>: The registration token. A string of no more than 64 characters that
  12641. consists only of characters matched by the regex <code>[A-Za-z0-9._~-]</code>.
  12642. Default: randomly generated.</li>
  12643. <li><code>uses_allowed</code>: The integer number of times the token can be used to complete
  12644. a registration before it becomes invalid.
  12645. Default: <code>null</code> (unlimited uses).</li>
  12646. <li><code>expiry_time</code>: The latest time the token is valid. Given as the number of
  12647. milliseconds since 1970-01-01 00:00:00 UTC (the start of the Unix epoch).
  12648. You could use, for example, <code>date '+%s000' -d 'tomorrow'</code>.
  12649. Default: <code>null</code> (token does not expire).</li>
  12650. <li><code>length</code>: The length of the token randomly generated if <code>token</code> is not
  12651. specified. Must be between 1 and 64 inclusive. Default: <code>16</code>.</li>
  12652. </ul>
  12653. <p>If a field is omitted the default is used.</p>
  12654. <p>Example using defaults:</p>
  12655. <pre><code>POST /_synapse/admin/v1/registration_tokens/new
  12656. {}
  12657. </code></pre>
  12658. <pre><code>200 OK
  12659. {
  12660. &quot;token&quot;: &quot;0M-9jbkf2t_Tgiw1&quot;,
  12661. &quot;uses_allowed&quot;: null,
  12662. &quot;pending&quot;: 0,
  12663. &quot;completed&quot;: 0,
  12664. &quot;expiry_time&quot;: null
  12665. }
  12666. </code></pre>
  12667. <p>Example specifying some fields:</p>
  12668. <pre><code>POST /_synapse/admin/v1/registration_tokens/new
  12669. {
  12670. &quot;token&quot;: &quot;defg&quot;,
  12671. &quot;uses_allowed&quot;: 1
  12672. }
  12673. </code></pre>
  12674. <pre><code>200 OK
  12675. {
  12676. &quot;token&quot;: &quot;defg&quot;,
  12677. &quot;uses_allowed&quot;: 1,
  12678. &quot;pending&quot;: 0,
  12679. &quot;completed&quot;: 0,
  12680. &quot;expiry_time&quot;: null
  12681. }
  12682. </code></pre>
  12683. <h2 id="update-token"><a class="header" href="#update-token">Update token</a></h2>
  12684. <p>Update the number of allowed uses or expiry time of a token. If the request is
  12685. successful, the updated token will be returned as a registration token object
  12686. in the response body.</p>
  12687. <pre><code>PUT /_synapse/admin/v1/registration_tokens/&lt;token&gt;
  12688. </code></pre>
  12689. <p>Path parameters:</p>
  12690. <ul>
  12691. <li><code>token</code>: The registration token to update.</li>
  12692. </ul>
  12693. <p>The request body must be a JSON object and can contain the following fields:</p>
  12694. <ul>
  12695. <li><code>uses_allowed</code>: The integer number of times the token can be used to complete
  12696. a registration before it becomes invalid. By setting <code>uses_allowed</code> to <code>0</code>
  12697. the token can be easily made invalid without deleting it.
  12698. If <code>null</code> the token will have an unlimited number of uses.</li>
  12699. <li><code>expiry_time</code>: The latest time the token is valid. Given as the number of
  12700. milliseconds since 1970-01-01 00:00:00 UTC (the start of the Unix epoch).
  12701. If <code>null</code> the token will not expire.</li>
  12702. </ul>
  12703. <p>If a field is omitted its value is not modified.</p>
  12704. <p>Example:</p>
  12705. <pre><code>PUT /_synapse/admin/v1/registration_tokens/defg
  12706. {
  12707. &quot;expiry_time&quot;: 4781243146000 // 2121-07-06 11:05:46 UTC
  12708. }
  12709. </code></pre>
  12710. <pre><code>200 OK
  12711. {
  12712. &quot;token&quot;: &quot;defg&quot;,
  12713. &quot;uses_allowed&quot;: 1,
  12714. &quot;pending&quot;: 0,
  12715. &quot;completed&quot;: 0,
  12716. &quot;expiry_time&quot;: 4781243146000
  12717. }
  12718. </code></pre>
  12719. <h2 id="delete-token"><a class="header" href="#delete-token">Delete token</a></h2>
  12720. <p>Delete a registration token. If the request is successful, the response body
  12721. will be an empty JSON object.</p>
  12722. <pre><code>DELETE /_synapse/admin/v1/registration_tokens/&lt;token&gt;
  12723. </code></pre>
  12724. <p>Path parameters:</p>
  12725. <ul>
  12726. <li><code>token</code>: The registration token to delete.</li>
  12727. </ul>
  12728. <p>Example:</p>
  12729. <pre><code>DELETE /_synapse/admin/v1/registration_tokens/wxyz
  12730. </code></pre>
  12731. <pre><code>200 OK
  12732. {}
  12733. </code></pre>
  12734. <h2 id="errors"><a class="header" href="#errors">Errors</a></h2>
  12735. <p>If a request fails a &quot;standard error response&quot; will be returned as defined in
  12736. the <a href="https://matrix.org/docs/spec/client_server/r0.6.1#api-standards">Matrix Client-Server API specification</a>.</p>
  12737. <p>For example, if the token specified in a path parameter does not exist a
  12738. <code>404 Not Found</code> error will be returned.</p>
  12739. <pre><code>GET /_synapse/admin/v1/registration_tokens/1234
  12740. </code></pre>
  12741. <pre><code>404 Not Found
  12742. {
  12743. &quot;errcode&quot;: &quot;M_NOT_FOUND&quot;,
  12744. &quot;error&quot;: &quot;No such registration token: 1234&quot;
  12745. }
  12746. </code></pre>
  12747. <div style="break-before: page; page-break-before: always;"></div><h1 id="edit-room-membership-api"><a class="header" href="#edit-room-membership-api">Edit Room Membership API</a></h1>
  12748. <p>This API allows an administrator to join an user account with a given <code>user_id</code>
  12749. to a room with a given <code>room_id_or_alias</code>. You can only modify the membership of
  12750. local users. The server administrator must be in the room and have permission to
  12751. invite users.</p>
  12752. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  12753. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  12754. <h2 id="parameters"><a class="header" href="#parameters">Parameters</a></h2>
  12755. <p>The following parameters are available:</p>
  12756. <ul>
  12757. <li><code>user_id</code> - Fully qualified user: for example, <code>@user:server.com</code>.</li>
  12758. <li><code>room_id_or_alias</code> - The room identifier or alias to join: for example,
  12759. <code>!636q39766251:server.com</code>.</li>
  12760. </ul>
  12761. <h2 id="usage-1"><a class="header" href="#usage-1">Usage</a></h2>
  12762. <pre><code>POST /_synapse/admin/v1/join/&lt;room_id_or_alias&gt;
  12763. {
  12764. &quot;user_id&quot;: &quot;@user:server.com&quot;
  12765. }
  12766. </code></pre>
  12767. <p>Response:</p>
  12768. <pre><code class="language-json">{
  12769. &quot;room_id&quot;: &quot;!636q39766251:server.com&quot;
  12770. }
  12771. </code></pre>
  12772. <div style="break-before: page; page-break-before: always;"></div><h1 id="list-room-api"><a class="header" href="#list-room-api">List Room API</a></h1>
  12773. <p>The List Room admin API allows server admins to get a list of rooms on their
  12774. server. There are various parameters available that allow for filtering and
  12775. sorting the returned list. This API supports pagination.</p>
  12776. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  12777. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  12778. <p><strong>Parameters</strong></p>
  12779. <p>The following query parameters are available:</p>
  12780. <ul>
  12781. <li>
  12782. <p><code>from</code> - Offset in the returned list. Defaults to <code>0</code>.</p>
  12783. </li>
  12784. <li>
  12785. <p><code>limit</code> - Maximum amount of rooms to return. Defaults to <code>100</code>.</p>
  12786. </li>
  12787. <li>
  12788. <p><code>order_by</code> - The method in which to sort the returned list of rooms. Valid values are:</p>
  12789. <ul>
  12790. <li><code>alphabetical</code> - Same as <code>name</code>. This is deprecated.</li>
  12791. <li><code>size</code> - Same as <code>joined_members</code>. This is deprecated.</li>
  12792. <li><code>name</code> - Rooms are ordered alphabetically by room name. This is the default.</li>
  12793. <li><code>canonical_alias</code> - Rooms are ordered alphabetically by main alias address of the room.</li>
  12794. <li><code>joined_members</code> - Rooms are ordered by the number of members. Largest to smallest.</li>
  12795. <li><code>joined_local_members</code> - Rooms are ordered by the number of local members. Largest to smallest.</li>
  12796. <li><code>version</code> - Rooms are ordered by room version. Largest to smallest.</li>
  12797. <li><code>creator</code> - Rooms are ordered alphabetically by creator of the room.</li>
  12798. <li><code>encryption</code> - Rooms are ordered alphabetically by the end-to-end encryption algorithm.</li>
  12799. <li><code>federatable</code> - Rooms are ordered by whether the room is federatable.</li>
  12800. <li><code>public</code> - Rooms are ordered by visibility in room list.</li>
  12801. <li><code>join_rules</code> - Rooms are ordered alphabetically by join rules of the room.</li>
  12802. <li><code>guest_access</code> - Rooms are ordered alphabetically by guest access option of the room.</li>
  12803. <li><code>history_visibility</code> - Rooms are ordered alphabetically by visibility of history of the room.</li>
  12804. <li><code>state_events</code> - Rooms are ordered by number of state events. Largest to smallest.</li>
  12805. </ul>
  12806. </li>
  12807. <li>
  12808. <p><code>dir</code> - Direction of room order. Either <code>f</code> for forwards or <code>b</code> for backwards. Setting
  12809. this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</p>
  12810. </li>
  12811. <li>
  12812. <p><code>search_term</code> - Filter rooms by their room name, canonical alias and room id.
  12813. Specifically, rooms are selected if the search term is contained in</p>
  12814. <ul>
  12815. <li>the room's name,</li>
  12816. <li>the local part of the room's canonical alias, or</li>
  12817. <li>the complete (local and server part) room's id (case sensitive).</li>
  12818. </ul>
  12819. <p>Defaults to no filtering.</p>
  12820. </li>
  12821. </ul>
  12822. <p><strong>Response</strong></p>
  12823. <p>The following fields are possible in the JSON response body:</p>
  12824. <ul>
  12825. <li><code>rooms</code> - An array of objects, each containing information about a room.
  12826. <ul>
  12827. <li>Room objects contain the following fields:
  12828. <ul>
  12829. <li><code>room_id</code> - The ID of the room.</li>
  12830. <li><code>name</code> - The name of the room.</li>
  12831. <li><code>canonical_alias</code> - The canonical (main) alias address of the room.</li>
  12832. <li><code>joined_members</code> - How many users are currently in the room.</li>
  12833. <li><code>joined_local_members</code> - How many local users are currently in the room.</li>
  12834. <li><code>version</code> - The version of the room as a string.</li>
  12835. <li><code>creator</code> - The <code>user_id</code> of the room creator.</li>
  12836. <li><code>encryption</code> - Algorithm of end-to-end encryption of messages. Is <code>null</code> if encryption is not active.</li>
  12837. <li><code>federatable</code> - Whether users on other servers can join this room.</li>
  12838. <li><code>public</code> - Whether the room is visible in room directory.</li>
  12839. <li><code>join_rules</code> - The type of rules used for users wishing to join this room. One of: [&quot;public&quot;, &quot;knock&quot;, &quot;invite&quot;, &quot;private&quot;].</li>
  12840. <li><code>guest_access</code> - Whether guests can join the room. One of: [&quot;can_join&quot;, &quot;forbidden&quot;].</li>
  12841. <li><code>history_visibility</code> - Who can see the room history. One of: [&quot;invited&quot;, &quot;joined&quot;, &quot;shared&quot;, &quot;world_readable&quot;].</li>
  12842. <li><code>state_events</code> - Total number of state_events of a room. Complexity of the room.</li>
  12843. <li><code>room_type</code> - The type of the room taken from the room's creation event; for example &quot;m.space&quot; if the room is a space. If the room does not define a type, the value will be <code>null</code>.</li>
  12844. </ul>
  12845. </li>
  12846. </ul>
  12847. </li>
  12848. <li><code>offset</code> - The current pagination offset in rooms. This parameter should be
  12849. used instead of <code>next_token</code> for room offset as <code>next_token</code> is
  12850. not intended to be parsed.</li>
  12851. <li><code>total_rooms</code> - The total number of rooms this query can return. Using this
  12852. and <code>offset</code>, you have enough information to know the current
  12853. progression through the list.</li>
  12854. <li><code>next_batch</code> - If this field is present, we know that there are potentially
  12855. more rooms on the server that did not all fit into this response.
  12856. We can use <code>next_batch</code> to get the &quot;next page&quot; of results. To do
  12857. so, simply repeat your request, setting the <code>from</code> parameter to
  12858. the value of <code>next_batch</code>.</li>
  12859. <li><code>prev_batch</code> - If this field is present, it is possible to paginate backwards.
  12860. Use <code>prev_batch</code> for the <code>from</code> value in the next request to
  12861. get the &quot;previous page&quot; of results.</li>
  12862. </ul>
  12863. <p>The API is:</p>
  12864. <p>A standard request with no filtering:</p>
  12865. <pre><code>GET /_synapse/admin/v1/rooms
  12866. </code></pre>
  12867. <p>A response body like the following is returned:</p>
  12868. <pre><code class="language-json">{
  12869. &quot;rooms&quot;: [
  12870. {
  12871. &quot;room_id&quot;: &quot;!OGEhHVWSdvArJzumhm:matrix.org&quot;,
  12872. &quot;name&quot;: &quot;Matrix HQ&quot;,
  12873. &quot;canonical_alias&quot;: &quot;#matrix:matrix.org&quot;,
  12874. &quot;joined_members&quot;: 8326,
  12875. &quot;joined_local_members&quot;: 2,
  12876. &quot;version&quot;: &quot;1&quot;,
  12877. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  12878. &quot;encryption&quot;: null,
  12879. &quot;federatable&quot;: true,
  12880. &quot;public&quot;: true,
  12881. &quot;join_rules&quot;: &quot;invite&quot;,
  12882. &quot;guest_access&quot;: null,
  12883. &quot;history_visibility&quot;: &quot;shared&quot;,
  12884. &quot;state_events&quot;: 93534,
  12885. &quot;room_type&quot;: &quot;m.space&quot;
  12886. },
  12887. ... (8 hidden items) ...
  12888. {
  12889. &quot;room_id&quot;: &quot;!xYvNcQPhnkrdUmYczI:matrix.org&quot;,
  12890. &quot;name&quot;: &quot;This Week In Matrix (TWIM)&quot;,
  12891. &quot;canonical_alias&quot;: &quot;#twim:matrix.org&quot;,
  12892. &quot;joined_members&quot;: 314,
  12893. &quot;joined_local_members&quot;: 20,
  12894. &quot;version&quot;: &quot;4&quot;,
  12895. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  12896. &quot;encryption&quot;: &quot;m.megolm.v1.aes-sha2&quot;,
  12897. &quot;federatable&quot;: true,
  12898. &quot;public&quot;: false,
  12899. &quot;join_rules&quot;: &quot;invite&quot;,
  12900. &quot;guest_access&quot;: null,
  12901. &quot;history_visibility&quot;: &quot;shared&quot;,
  12902. &quot;state_events&quot;: 8345,
  12903. &quot;room_type&quot;: null
  12904. }
  12905. ],
  12906. &quot;offset&quot;: 0,
  12907. &quot;total_rooms&quot;: 10
  12908. }
  12909. </code></pre>
  12910. <p>Filtering by room name:</p>
  12911. <pre><code>GET /_synapse/admin/v1/rooms?search_term=TWIM
  12912. </code></pre>
  12913. <p>A response body like the following is returned:</p>
  12914. <pre><code class="language-json">{
  12915. &quot;rooms&quot;: [
  12916. {
  12917. &quot;room_id&quot;: &quot;!xYvNcQPhnkrdUmYczI:matrix.org&quot;,
  12918. &quot;name&quot;: &quot;This Week In Matrix (TWIM)&quot;,
  12919. &quot;canonical_alias&quot;: &quot;#twim:matrix.org&quot;,
  12920. &quot;joined_members&quot;: 314,
  12921. &quot;joined_local_members&quot;: 20,
  12922. &quot;version&quot;: &quot;4&quot;,
  12923. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  12924. &quot;encryption&quot;: &quot;m.megolm.v1.aes-sha2&quot;,
  12925. &quot;federatable&quot;: true,
  12926. &quot;public&quot;: false,
  12927. &quot;join_rules&quot;: &quot;invite&quot;,
  12928. &quot;guest_access&quot;: null,
  12929. &quot;history_visibility&quot;: &quot;shared&quot;,
  12930. &quot;state_events&quot;: 8,
  12931. &quot;room_type&quot;: null
  12932. }
  12933. ],
  12934. &quot;offset&quot;: 0,
  12935. &quot;total_rooms&quot;: 1
  12936. }
  12937. </code></pre>
  12938. <p>Paginating through a list of rooms:</p>
  12939. <pre><code>GET /_synapse/admin/v1/rooms?order_by=size
  12940. </code></pre>
  12941. <p>A response body like the following is returned:</p>
  12942. <pre><code class="language-json">{
  12943. &quot;rooms&quot;: [
  12944. {
  12945. &quot;room_id&quot;: &quot;!OGEhHVWSdvArJzumhm:matrix.org&quot;,
  12946. &quot;name&quot;: &quot;Matrix HQ&quot;,
  12947. &quot;canonical_alias&quot;: &quot;#matrix:matrix.org&quot;,
  12948. &quot;joined_members&quot;: 8326,
  12949. &quot;joined_local_members&quot;: 2,
  12950. &quot;version&quot;: &quot;1&quot;,
  12951. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  12952. &quot;encryption&quot;: null,
  12953. &quot;federatable&quot;: true,
  12954. &quot;public&quot;: true,
  12955. &quot;join_rules&quot;: &quot;invite&quot;,
  12956. &quot;guest_access&quot;: null,
  12957. &quot;history_visibility&quot;: &quot;shared&quot;,
  12958. &quot;state_events&quot;: 93534,
  12959. &quot;room_type&quot;: null
  12960. },
  12961. ... (98 hidden items) ...
  12962. {
  12963. &quot;room_id&quot;: &quot;!xYvNcQPhnkrdUmYczI:matrix.org&quot;,
  12964. &quot;name&quot;: &quot;This Week In Matrix (TWIM)&quot;,
  12965. &quot;canonical_alias&quot;: &quot;#twim:matrix.org&quot;,
  12966. &quot;joined_members&quot;: 314,
  12967. &quot;joined_local_members&quot;: 20,
  12968. &quot;version&quot;: &quot;4&quot;,
  12969. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  12970. &quot;encryption&quot;: &quot;m.megolm.v1.aes-sha2&quot;,
  12971. &quot;federatable&quot;: true,
  12972. &quot;public&quot;: false,
  12973. &quot;join_rules&quot;: &quot;invite&quot;,
  12974. &quot;guest_access&quot;: null,
  12975. &quot;history_visibility&quot;: &quot;shared&quot;,
  12976. &quot;state_events&quot;: 8345,
  12977. &quot;room_type&quot;: &quot;m.space&quot;
  12978. }
  12979. ],
  12980. &quot;offset&quot;: 0,
  12981. &quot;total_rooms&quot;: 150,
  12982. &quot;next_token&quot;: 100
  12983. }
  12984. </code></pre>
  12985. <p>The presence of the <code>next_token</code> parameter tells us that there are more rooms
  12986. than returned in this request, and we need to make another request to get them.
  12987. To get the next batch of room results, we repeat our request, setting the <code>from</code>
  12988. parameter to the value of <code>next_token</code>.</p>
  12989. <pre><code>GET /_synapse/admin/v1/rooms?order_by=size&amp;from=100
  12990. </code></pre>
  12991. <p>A response body like the following is returned:</p>
  12992. <pre><code class="language-json">{
  12993. &quot;rooms&quot;: [
  12994. {
  12995. &quot;room_id&quot;: &quot;!mscvqgqpHYjBGDxNym:matrix.org&quot;,
  12996. &quot;name&quot;: &quot;Music Theory&quot;,
  12997. &quot;canonical_alias&quot;: &quot;#musictheory:matrix.org&quot;,
  12998. &quot;joined_members&quot;: 127,
  12999. &quot;joined_local_members&quot;: 2,
  13000. &quot;version&quot;: &quot;1&quot;,
  13001. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  13002. &quot;encryption&quot;: null,
  13003. &quot;federatable&quot;: true,
  13004. &quot;public&quot;: true,
  13005. &quot;join_rules&quot;: &quot;invite&quot;,
  13006. &quot;guest_access&quot;: null,
  13007. &quot;history_visibility&quot;: &quot;shared&quot;,
  13008. &quot;state_events&quot;: 93534,
  13009. &quot;room_type&quot;: &quot;m.space&quot;
  13010. },
  13011. ... (48 hidden items) ...
  13012. {
  13013. &quot;room_id&quot;: &quot;!twcBhHVdZlQWuuxBhN:termina.org.uk&quot;,
  13014. &quot;name&quot;: &quot;weechat-matrix&quot;,
  13015. &quot;canonical_alias&quot;: &quot;#weechat-matrix:termina.org.uk&quot;,
  13016. &quot;joined_members&quot;: 137,
  13017. &quot;joined_local_members&quot;: 20,
  13018. &quot;version&quot;: &quot;4&quot;,
  13019. &quot;creator&quot;: &quot;@foo:termina.org.uk&quot;,
  13020. &quot;encryption&quot;: null,
  13021. &quot;federatable&quot;: true,
  13022. &quot;public&quot;: true,
  13023. &quot;join_rules&quot;: &quot;invite&quot;,
  13024. &quot;guest_access&quot;: null,
  13025. &quot;history_visibility&quot;: &quot;shared&quot;,
  13026. &quot;state_events&quot;: 8345,
  13027. &quot;room_type&quot;: null
  13028. }
  13029. ],
  13030. &quot;offset&quot;: 100,
  13031. &quot;prev_batch&quot;: 0,
  13032. &quot;total_rooms&quot;: 150
  13033. }
  13034. </code></pre>
  13035. <p>Once the <code>next_token</code> parameter is no longer present, we know we've reached the
  13036. end of the list.</p>
  13037. <h1 id="room-details-api"><a class="header" href="#room-details-api">Room Details API</a></h1>
  13038. <p>The Room Details admin API allows server admins to get all details of a room.</p>
  13039. <p>The following fields are possible in the JSON response body:</p>
  13040. <ul>
  13041. <li><code>room_id</code> - The ID of the room.</li>
  13042. <li><code>name</code> - The name of the room.</li>
  13043. <li><code>topic</code> - The topic of the room.</li>
  13044. <li><code>avatar</code> - The <code>mxc</code> URI to the avatar of the room.</li>
  13045. <li><code>canonical_alias</code> - The canonical (main) alias address of the room.</li>
  13046. <li><code>joined_members</code> - How many users are currently in the room.</li>
  13047. <li><code>joined_local_members</code> - How many local users are currently in the room.</li>
  13048. <li><code>joined_local_devices</code> - How many local devices are currently in the room.</li>
  13049. <li><code>version</code> - The version of the room as a string.</li>
  13050. <li><code>creator</code> - The <code>user_id</code> of the room creator.</li>
  13051. <li><code>encryption</code> - Algorithm of end-to-end encryption of messages. Is <code>null</code> if encryption is not active.</li>
  13052. <li><code>federatable</code> - Whether users on other servers can join this room.</li>
  13053. <li><code>public</code> - Whether the room is visible in room directory.</li>
  13054. <li><code>join_rules</code> - The type of rules used for users wishing to join this room. One of: [&quot;public&quot;, &quot;knock&quot;, &quot;invite&quot;, &quot;private&quot;].</li>
  13055. <li><code>guest_access</code> - Whether guests can join the room. One of: [&quot;can_join&quot;, &quot;forbidden&quot;].</li>
  13056. <li><code>history_visibility</code> - Who can see the room history. One of: [&quot;invited&quot;, &quot;joined&quot;, &quot;shared&quot;, &quot;world_readable&quot;].</li>
  13057. <li><code>state_events</code> - Total number of state_events of a room. Complexity of the room.</li>
  13058. <li><code>room_type</code> - The type of the room taken from the room's creation event; for example &quot;m.space&quot; if the room is a space.
  13059. If the room does not define a type, the value will be <code>null</code>.</li>
  13060. <li><code>forgotten</code> - Whether all local users have
  13061. <a href="https://spec.matrix.org/latest/client-server-api/#leaving-rooms">forgotten</a> the room.</li>
  13062. </ul>
  13063. <p>The API is:</p>
  13064. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;
  13065. </code></pre>
  13066. <p>A response body like the following is returned:</p>
  13067. <pre><code class="language-json">{
  13068. &quot;room_id&quot;: &quot;!mscvqgqpHYjBGDxNym:matrix.org&quot;,
  13069. &quot;name&quot;: &quot;Music Theory&quot;,
  13070. &quot;avatar&quot;: &quot;mxc://matrix.org/AQDaVFlbkQoErdOgqWRgiGSV&quot;,
  13071. &quot;topic&quot;: &quot;Theory, Composition, Notation, Analysis&quot;,
  13072. &quot;canonical_alias&quot;: &quot;#musictheory:matrix.org&quot;,
  13073. &quot;joined_members&quot;: 127,
  13074. &quot;joined_local_members&quot;: 2,
  13075. &quot;joined_local_devices&quot;: 2,
  13076. &quot;version&quot;: &quot;1&quot;,
  13077. &quot;creator&quot;: &quot;@foo:matrix.org&quot;,
  13078. &quot;encryption&quot;: null,
  13079. &quot;federatable&quot;: true,
  13080. &quot;public&quot;: true,
  13081. &quot;join_rules&quot;: &quot;invite&quot;,
  13082. &quot;guest_access&quot;: null,
  13083. &quot;history_visibility&quot;: &quot;shared&quot;,
  13084. &quot;state_events&quot;: 93534,
  13085. &quot;room_type&quot;: &quot;m.space&quot;,
  13086. &quot;forgotten&quot;: false
  13087. }
  13088. </code></pre>
  13089. <p><em>Changed in Synapse 1.66:</em> Added the <code>forgotten</code> key to the response body.</p>
  13090. <h1 id="room-members-api"><a class="header" href="#room-members-api">Room Members API</a></h1>
  13091. <p>The Room Members admin API allows server admins to get a list of all members of a room.</p>
  13092. <p>The response includes the following fields:</p>
  13093. <ul>
  13094. <li><code>members</code> - A list of all the members that are present in the room, represented by their ids.</li>
  13095. <li><code>total</code> - Total number of members in the room.</li>
  13096. </ul>
  13097. <p>The API is:</p>
  13098. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/members
  13099. </code></pre>
  13100. <p>A response body like the following is returned:</p>
  13101. <pre><code class="language-json">{
  13102. &quot;members&quot;: [
  13103. &quot;@foo:matrix.org&quot;,
  13104. &quot;@bar:matrix.org&quot;,
  13105. &quot;@foobar:matrix.org&quot;
  13106. ],
  13107. &quot;total&quot;: 3
  13108. }
  13109. </code></pre>
  13110. <h1 id="room-state-api"><a class="header" href="#room-state-api">Room State API</a></h1>
  13111. <p>The Room State admin API allows server admins to get a list of all state events in a room.</p>
  13112. <p>The response includes the following fields:</p>
  13113. <ul>
  13114. <li><code>state</code> - The current state of the room at the time of request.</li>
  13115. </ul>
  13116. <p>The API is:</p>
  13117. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/state
  13118. </code></pre>
  13119. <p>A response body like the following is returned:</p>
  13120. <pre><code class="language-json">{
  13121. &quot;state&quot;: [
  13122. {&quot;type&quot;: &quot;m.room.create&quot;, &quot;state_key&quot;: &quot;&quot;, &quot;etc&quot;: true},
  13123. {&quot;type&quot;: &quot;m.room.power_levels&quot;, &quot;state_key&quot;: &quot;&quot;, &quot;etc&quot;: true},
  13124. {&quot;type&quot;: &quot;m.room.name&quot;, &quot;state_key&quot;: &quot;&quot;, &quot;etc&quot;: true}
  13125. ]
  13126. }
  13127. </code></pre>
  13128. <h1 id="room-messages-api"><a class="header" href="#room-messages-api">Room Messages API</a></h1>
  13129. <p>The Room Messages admin API allows server admins to get all messages
  13130. sent to a room in a given timeframe. There are various parameters available
  13131. that allow for filtering and ordering the returned list. This API supports pagination.</p>
  13132. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  13133. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  13134. <p>This endpoint mirrors the <a href="https://spec.matrix.org/v1.1/client-server-api/#get_matrixclientv3roomsroomidmessages">Matrix Spec defined Messages API</a>.</p>
  13135. <p>The API is:</p>
  13136. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/messages
  13137. </code></pre>
  13138. <p><strong>Parameters</strong></p>
  13139. <p>The following path parameters are required:</p>
  13140. <ul>
  13141. <li><code>room_id</code> - The ID of the room you wish you fetch messages from.</li>
  13142. </ul>
  13143. <p>The following query parameters are available:</p>
  13144. <ul>
  13145. <li><code>from</code> (required) - The token to start returning events from. This token can be obtained from a prev_batch
  13146. or next_batch token returned by the /sync endpoint, or from an end token returned by a previous request to this endpoint.</li>
  13147. <li><code>to</code> - The token to stop returning events at.</li>
  13148. <li><code>limit</code> - The maximum number of events to return. Defaults to <code>10</code>.</li>
  13149. <li><code>filter</code> - A JSON RoomEventFilter to filter returned events with.</li>
  13150. <li><code>dir</code> - The direction to return events from. Either <code>f</code> for forwards or <code>b</code> for backwards. Setting
  13151. this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</li>
  13152. </ul>
  13153. <p><strong>Response</strong></p>
  13154. <p>The following fields are possible in the JSON response body:</p>
  13155. <ul>
  13156. <li><code>chunk</code> - A list of room events. The order depends on the dir parameter.
  13157. Note that an empty chunk does not necessarily imply that no more events are available. Clients should continue to paginate until no end property is returned.</li>
  13158. <li><code>end</code> - A token corresponding to the end of chunk. This token can be passed back to this endpoint to request further events.
  13159. If no further events are available, this property is omitted from the response.</li>
  13160. <li><code>start</code> - A token corresponding to the start of chunk.</li>
  13161. <li><code>state</code> - A list of state events relevant to showing the chunk.</li>
  13162. </ul>
  13163. <p><strong>Example</strong></p>
  13164. <p>For more details on each chunk, read <a href="https://spec.matrix.org/v1.1/client-server-api/#get_matrixclientv3roomsroomidmessages">the Matrix specification</a>.</p>
  13165. <pre><code class="language-json">{
  13166. &quot;chunk&quot;: [
  13167. {
  13168. &quot;content&quot;: {
  13169. &quot;body&quot;: &quot;This is an example text message&quot;,
  13170. &quot;format&quot;: &quot;org.matrix.custom.html&quot;,
  13171. &quot;formatted_body&quot;: &quot;&lt;b&gt;This is an example text message&lt;/b&gt;&quot;,
  13172. &quot;msgtype&quot;: &quot;m.text&quot;
  13173. },
  13174. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13175. &quot;origin_server_ts&quot;: 1432735824653,
  13176. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13177. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13178. &quot;type&quot;: &quot;m.room.message&quot;,
  13179. &quot;unsigned&quot;: {
  13180. &quot;age&quot;: 1234
  13181. }
  13182. },
  13183. {
  13184. &quot;content&quot;: {
  13185. &quot;name&quot;: &quot;The room name&quot;
  13186. },
  13187. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13188. &quot;origin_server_ts&quot;: 1432735824653,
  13189. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13190. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13191. &quot;state_key&quot;: &quot;&quot;,
  13192. &quot;type&quot;: &quot;m.room.name&quot;,
  13193. &quot;unsigned&quot;: {
  13194. &quot;age&quot;: 1234
  13195. }
  13196. },
  13197. {
  13198. &quot;content&quot;: {
  13199. &quot;body&quot;: &quot;Gangnam Style&quot;,
  13200. &quot;info&quot;: {
  13201. &quot;duration&quot;: 2140786,
  13202. &quot;h&quot;: 320,
  13203. &quot;mimetype&quot;: &quot;video/mp4&quot;,
  13204. &quot;size&quot;: 1563685,
  13205. &quot;thumbnail_info&quot;: {
  13206. &quot;h&quot;: 300,
  13207. &quot;mimetype&quot;: &quot;image/jpeg&quot;,
  13208. &quot;size&quot;: 46144,
  13209. &quot;w&quot;: 300
  13210. },
  13211. &quot;thumbnail_url&quot;: &quot;mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe&quot;,
  13212. &quot;w&quot;: 480
  13213. },
  13214. &quot;msgtype&quot;: &quot;m.video&quot;,
  13215. &quot;url&quot;: &quot;mxc://example.org/a526eYUSFFxlgbQYZmo442&quot;
  13216. },
  13217. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13218. &quot;origin_server_ts&quot;: 1432735824653,
  13219. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13220. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13221. &quot;type&quot;: &quot;m.room.message&quot;,
  13222. &quot;unsigned&quot;: {
  13223. &quot;age&quot;: 1234
  13224. }
  13225. }
  13226. ],
  13227. &quot;end&quot;: &quot;t47409-4357353_219380_26003_2265&quot;,
  13228. &quot;start&quot;: &quot;t47429-4392820_219380_26003_2265&quot;
  13229. }
  13230. </code></pre>
  13231. <h1 id="room-timestamp-to-event-api"><a class="header" href="#room-timestamp-to-event-api">Room Timestamp to Event API</a></h1>
  13232. <p>The Room Timestamp to Event API endpoint fetches the <code>event_id</code> of the closest event to the given
  13233. timestamp (<code>ts</code> query parameter) in the given direction (<code>dir</code> query parameter).</p>
  13234. <p>Useful for cases like jump to date so you can start paginating messages from
  13235. a given date in the archive.</p>
  13236. <p>The API is:</p>
  13237. <pre><code> GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/timestamp_to_event
  13238. </code></pre>
  13239. <p><strong>Parameters</strong></p>
  13240. <p>The following path parameters are required:</p>
  13241. <ul>
  13242. <li><code>room_id</code> - The ID of the room you wish to check.</li>
  13243. </ul>
  13244. <p>The following query parameters are available:</p>
  13245. <ul>
  13246. <li><code>ts</code> - a timestamp in milliseconds where we will find the closest event in
  13247. the given direction.</li>
  13248. <li><code>dir</code> - can be <code>f</code> or <code>b</code> to indicate forwards and backwards in time from the
  13249. given timestamp. Defaults to <code>f</code>.</li>
  13250. </ul>
  13251. <p><strong>Response</strong></p>
  13252. <ul>
  13253. <li><code>event_id</code> - The event ID closest to the given timestamp.</li>
  13254. <li><code>origin_server_ts</code> - The timestamp of the event in milliseconds since the Unix epoch.</li>
  13255. </ul>
  13256. <h1 id="block-room-api"><a class="header" href="#block-room-api">Block Room API</a></h1>
  13257. <p>The Block Room admin API allows server admins to block and unblock rooms,
  13258. and query to see if a given room is blocked.
  13259. This API can be used to pre-emptively block a room, even if it's unknown to this
  13260. homeserver. Users will be prevented from joining a blocked room.</p>
  13261. <h2 id="block-or-unblock-a-room"><a class="header" href="#block-or-unblock-a-room">Block or unblock a room</a></h2>
  13262. <p>The API is:</p>
  13263. <pre><code>PUT /_synapse/admin/v1/rooms/&lt;room_id&gt;/block
  13264. </code></pre>
  13265. <p>with a body of:</p>
  13266. <pre><code class="language-json">{
  13267. &quot;block&quot;: true
  13268. }
  13269. </code></pre>
  13270. <p>A response body like the following is returned:</p>
  13271. <pre><code class="language-json">{
  13272. &quot;block&quot;: true
  13273. }
  13274. </code></pre>
  13275. <p><strong>Parameters</strong></p>
  13276. <p>The following parameters should be set in the URL:</p>
  13277. <ul>
  13278. <li><code>room_id</code> - The ID of the room.</li>
  13279. </ul>
  13280. <p>The following JSON body parameters are available:</p>
  13281. <ul>
  13282. <li><code>block</code> - If <code>true</code> the room will be blocked and if <code>false</code> the room will be unblocked.</li>
  13283. </ul>
  13284. <p><strong>Response</strong></p>
  13285. <p>The following fields are possible in the JSON response body:</p>
  13286. <ul>
  13287. <li><code>block</code> - A boolean. <code>true</code> if the room is blocked, otherwise <code>false</code></li>
  13288. </ul>
  13289. <h2 id="get-block-status"><a class="header" href="#get-block-status">Get block status</a></h2>
  13290. <p>The API is:</p>
  13291. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/block
  13292. </code></pre>
  13293. <p>A response body like the following is returned:</p>
  13294. <pre><code class="language-json">{
  13295. &quot;block&quot;: true,
  13296. &quot;user_id&quot;: &quot;&lt;user_id&gt;&quot;
  13297. }
  13298. </code></pre>
  13299. <p><strong>Parameters</strong></p>
  13300. <p>The following parameters should be set in the URL:</p>
  13301. <ul>
  13302. <li><code>room_id</code> - The ID of the room.</li>
  13303. </ul>
  13304. <p><strong>Response</strong></p>
  13305. <p>The following fields are possible in the JSON response body:</p>
  13306. <ul>
  13307. <li><code>block</code> - A boolean. <code>true</code> if the room is blocked, otherwise <code>false</code></li>
  13308. <li><code>user_id</code> - An optional string. If the room is blocked (<code>block</code> is <code>true</code>) shows
  13309. the user who has add the room to blocking list. Otherwise it is not displayed.</li>
  13310. </ul>
  13311. <h1 id="delete-room-api"><a class="header" href="#delete-room-api">Delete Room API</a></h1>
  13312. <p>The Delete Room admin API allows server admins to remove rooms from the server
  13313. and block these rooms.</p>
  13314. <p>Shuts down a room. Moves all local users and room aliases automatically to a
  13315. new room if <code>new_room_user_id</code> is set. Otherwise local users only
  13316. leave the room without any information.</p>
  13317. <p>The new room will be created with the user specified by the <code>new_room_user_id</code> parameter
  13318. as room administrator and will contain a message explaining what happened. Users invited
  13319. to the new room will have power level <code>-10</code> by default, and thus be unable to speak.</p>
  13320. <p>If <code>block</code> is <code>true</code>, users will be prevented from joining the old room.
  13321. This option can in <a href="admin_api/rooms.html#version-1-old-version">Version 1</a> also be used to pre-emptively
  13322. block a room, even if it's unknown to this homeserver. In this case, the room will be
  13323. blocked, and no further action will be taken. If <code>block</code> is <code>false</code>, attempting to
  13324. delete an unknown room is invalid and will be rejected as a bad request.</p>
  13325. <p>This API will remove all trace of the old room from your database after removing
  13326. all local users. If <code>purge</code> is <code>true</code> (the default), all traces of the old room will
  13327. be removed from your database after removing all local users. If you do not want
  13328. this to happen, set <code>purge</code> to <code>false</code>.
  13329. Depending on the amount of history being purged, a call to the API may take
  13330. several minutes or longer.</p>
  13331. <p>The local server will only have the power to move local user and room aliases to
  13332. the new room. Users on other servers will be unaffected.</p>
  13333. <h2 id="version-1-old-version"><a class="header" href="#version-1-old-version">Version 1 (old version)</a></h2>
  13334. <p>This version works synchronously. That means you only get the response once the server has
  13335. finished the action, which may take a long time. If you request the same action
  13336. a second time, and the server has not finished the first one, the second request will block.
  13337. This is fixed in version 2 of this API. The parameters are the same in both APIs.
  13338. This API will become deprecated in the future.</p>
  13339. <p>The API is:</p>
  13340. <pre><code>DELETE /_synapse/admin/v1/rooms/&lt;room_id&gt;
  13341. </code></pre>
  13342. <p>with a body of:</p>
  13343. <pre><code class="language-json">{
  13344. &quot;new_room_user_id&quot;: &quot;@someuser:example.com&quot;,
  13345. &quot;room_name&quot;: &quot;Content Violation Notification&quot;,
  13346. &quot;message&quot;: &quot;Bad Room has been shutdown due to content violations on this server. Please review our Terms of Service.&quot;,
  13347. &quot;block&quot;: true,
  13348. &quot;purge&quot;: true
  13349. }
  13350. </code></pre>
  13351. <p>A response body like the following is returned:</p>
  13352. <pre><code class="language-json">{
  13353. &quot;kicked_users&quot;: [
  13354. &quot;@foobar:example.com&quot;
  13355. ],
  13356. &quot;failed_to_kick_users&quot;: [],
  13357. &quot;local_aliases&quot;: [
  13358. &quot;#badroom:example.com&quot;,
  13359. &quot;#evilsaloon:example.com&quot;
  13360. ],
  13361. &quot;new_room_id&quot;: &quot;!newroomid:example.com&quot;
  13362. }
  13363. </code></pre>
  13364. <p>The parameters and response values have the same format as
  13365. <a href="admin_api/rooms.html#version-2-new-version">version 2</a> of the API.</p>
  13366. <h2 id="version-2-new-version"><a class="header" href="#version-2-new-version">Version 2 (new version)</a></h2>
  13367. <p><strong>Note</strong>: This API is new, experimental and &quot;subject to change&quot;.</p>
  13368. <p>This version works asynchronously, meaning you get the response from server immediately
  13369. while the server works on that task in background. You can then request the status of the action
  13370. to check if it has completed.</p>
  13371. <p>The API is:</p>
  13372. <pre><code>DELETE /_synapse/admin/v2/rooms/&lt;room_id&gt;
  13373. </code></pre>
  13374. <p>with a body of:</p>
  13375. <pre><code class="language-json">{
  13376. &quot;new_room_user_id&quot;: &quot;@someuser:example.com&quot;,
  13377. &quot;room_name&quot;: &quot;Content Violation Notification&quot;,
  13378. &quot;message&quot;: &quot;Bad Room has been shutdown due to content violations on this server. Please review our Terms of Service.&quot;,
  13379. &quot;block&quot;: true,
  13380. &quot;purge&quot;: true
  13381. }
  13382. </code></pre>
  13383. <p>The API starts the shut down and purge running, and returns immediately with a JSON body with
  13384. a purge id:</p>
  13385. <pre><code class="language-json">{
  13386. &quot;delete_id&quot;: &quot;&lt;opaque id&gt;&quot;
  13387. }
  13388. </code></pre>
  13389. <p><strong>Parameters</strong></p>
  13390. <p>The following parameters should be set in the URL:</p>
  13391. <ul>
  13392. <li><code>room_id</code> - The ID of the room.</li>
  13393. </ul>
  13394. <p>The following JSON body parameters are available:</p>
  13395. <ul>
  13396. <li><code>new_room_user_id</code> - Optional. If set, a new room will be created with this user ID
  13397. as the creator and admin, and all users in the old room will be moved into that
  13398. room. If not set, no new room will be created and the users will just be removed
  13399. from the old room. The user ID must be on the local server, but does not necessarily
  13400. have to belong to a registered user.</li>
  13401. <li><code>room_name</code> - Optional. A string representing the name of the room that new users will be
  13402. invited to. Defaults to <code>Content Violation Notification</code></li>
  13403. <li><code>message</code> - Optional. A string containing the first message that will be sent as
  13404. <code>new_room_user_id</code> in the new room. Ideally this will clearly convey why the
  13405. original room was shut down. Defaults to <code>Sharing illegal content on this server is not permitted and rooms in violation will be blocked.</code></li>
  13406. <li><code>block</code> - Optional. If set to <code>true</code>, this room will be added to a blocking list,
  13407. preventing future attempts to join the room. Rooms can be blocked
  13408. even if they're not yet known to the homeserver (only with
  13409. <a href="admin_api/rooms.html#version-1-old-version">Version 1</a> of the API). Defaults to <code>false</code>.</li>
  13410. <li><code>purge</code> - Optional. If set to <code>true</code>, it will remove all traces of the room from your database.
  13411. Defaults to <code>true</code>.</li>
  13412. <li><code>force_purge</code> - Optional, and ignored unless <code>purge</code> is <code>true</code>. If set to <code>true</code>, it
  13413. will force a purge to go ahead even if there are local users still in the room. Do not
  13414. use this unless a regular <code>purge</code> operation fails, as it could leave those users'
  13415. clients in a confused state.</li>
  13416. </ul>
  13417. <p>The JSON body must not be empty. The body must be at least <code>{}</code>.</p>
  13418. <h2 id="status-of-deleting-rooms"><a class="header" href="#status-of-deleting-rooms">Status of deleting rooms</a></h2>
  13419. <p><strong>Note</strong>: This API is new, experimental and &quot;subject to change&quot;.</p>
  13420. <p>It is possible to query the status of the background task for deleting rooms.
  13421. The status can be queried up to 24 hours after completion of the task,
  13422. or until Synapse is restarted (whichever happens first).</p>
  13423. <h3 id="query-by-room_id"><a class="header" href="#query-by-room_id">Query by <code>room_id</code></a></h3>
  13424. <p>With this API you can get the status of all active deletion tasks, and all those completed in the last 24h,
  13425. for the given <code>room_id</code>.</p>
  13426. <p>The API is:</p>
  13427. <pre><code>GET /_synapse/admin/v2/rooms/&lt;room_id&gt;/delete_status
  13428. </code></pre>
  13429. <p>A response body like the following is returned:</p>
  13430. <pre><code class="language-json">{
  13431. &quot;results&quot;: [
  13432. {
  13433. &quot;delete_id&quot;: &quot;delete_id1&quot;,
  13434. &quot;status&quot;: &quot;failed&quot;,
  13435. &quot;error&quot;: &quot;error message&quot;,
  13436. &quot;shutdown_room&quot;: {
  13437. &quot;kicked_users&quot;: [],
  13438. &quot;failed_to_kick_users&quot;: [],
  13439. &quot;local_aliases&quot;: [],
  13440. &quot;new_room_id&quot;: null
  13441. }
  13442. }, {
  13443. &quot;delete_id&quot;: &quot;delete_id2&quot;,
  13444. &quot;status&quot;: &quot;purging&quot;,
  13445. &quot;shutdown_room&quot;: {
  13446. &quot;kicked_users&quot;: [
  13447. &quot;@foobar:example.com&quot;
  13448. ],
  13449. &quot;failed_to_kick_users&quot;: [],
  13450. &quot;local_aliases&quot;: [
  13451. &quot;#badroom:example.com&quot;,
  13452. &quot;#evilsaloon:example.com&quot;
  13453. ],
  13454. &quot;new_room_id&quot;: &quot;!newroomid:example.com&quot;
  13455. }
  13456. }
  13457. ]
  13458. }
  13459. </code></pre>
  13460. <p><strong>Parameters</strong></p>
  13461. <p>The following parameters should be set in the URL:</p>
  13462. <ul>
  13463. <li><code>room_id</code> - The ID of the room.</li>
  13464. </ul>
  13465. <h3 id="query-by-delete_id"><a class="header" href="#query-by-delete_id">Query by <code>delete_id</code></a></h3>
  13466. <p>With this API you can get the status of one specific task by <code>delete_id</code>.</p>
  13467. <p>The API is:</p>
  13468. <pre><code>GET /_synapse/admin/v2/rooms/delete_status/&lt;delete_id&gt;
  13469. </code></pre>
  13470. <p>A response body like the following is returned:</p>
  13471. <pre><code class="language-json">{
  13472. &quot;status&quot;: &quot;purging&quot;,
  13473. &quot;shutdown_room&quot;: {
  13474. &quot;kicked_users&quot;: [
  13475. &quot;@foobar:example.com&quot;
  13476. ],
  13477. &quot;failed_to_kick_users&quot;: [],
  13478. &quot;local_aliases&quot;: [
  13479. &quot;#badroom:example.com&quot;,
  13480. &quot;#evilsaloon:example.com&quot;
  13481. ],
  13482. &quot;new_room_id&quot;: &quot;!newroomid:example.com&quot;
  13483. }
  13484. }
  13485. </code></pre>
  13486. <p><strong>Parameters</strong></p>
  13487. <p>The following parameters should be set in the URL:</p>
  13488. <ul>
  13489. <li><code>delete_id</code> - The ID for this delete.</li>
  13490. </ul>
  13491. <h3 id="response"><a class="header" href="#response">Response</a></h3>
  13492. <p>The following fields are returned in the JSON response body:</p>
  13493. <ul>
  13494. <li><code>results</code> - An array of objects, each containing information about one task.
  13495. This field is omitted from the result when you query by <code>delete_id</code>.
  13496. Task objects contain the following fields:
  13497. <ul>
  13498. <li><code>delete_id</code> - The ID for this purge if you query by <code>room_id</code>.</li>
  13499. <li><code>status</code> - The status will be one of:
  13500. <ul>
  13501. <li><code>shutting_down</code> - The process is removing users from the room.</li>
  13502. <li><code>purging</code> - The process is purging the room and event data from database.</li>
  13503. <li><code>complete</code> - The process has completed successfully.</li>
  13504. <li><code>failed</code> - The process is aborted, an error has occurred.</li>
  13505. </ul>
  13506. </li>
  13507. <li><code>error</code> - A string that shows an error message if <code>status</code> is <code>failed</code>.
  13508. Otherwise this field is hidden.</li>
  13509. <li><code>shutdown_room</code> - An object containing information about the result of shutting down the room.
  13510. <em>Note:</em> The result is shown after removing the room members.
  13511. The delete process can still be running. Please pay attention to the <code>status</code>.
  13512. <ul>
  13513. <li><code>kicked_users</code> - An array of users (<code>user_id</code>) that were kicked.</li>
  13514. <li><code>failed_to_kick_users</code> - An array of users (<code>user_id</code>) that that were not kicked.</li>
  13515. <li><code>local_aliases</code> - An array of strings representing the local aliases that were
  13516. migrated from the old room to the new.</li>
  13517. <li><code>new_room_id</code> - A string representing the room ID of the new room, or <code>null</code> if
  13518. no such room was created.</li>
  13519. </ul>
  13520. </li>
  13521. </ul>
  13522. </li>
  13523. </ul>
  13524. <h2 id="undoing-room-deletions"><a class="header" href="#undoing-room-deletions">Undoing room deletions</a></h2>
  13525. <p><em>Note</em>: This guide may be outdated by the time you read it. By nature of room deletions being performed at the database level,
  13526. the structure can and does change without notice.</p>
  13527. <p>First, it's important to understand that a room deletion is very destructive. Undoing a deletion is not as simple as pretending it
  13528. never happened - work has to be done to move forward instead of resetting the past. In fact, in some cases it might not be possible
  13529. to recover at all:</p>
  13530. <ul>
  13531. <li>If the room was invite-only, your users will need to be re-invited.</li>
  13532. <li>If the room no longer has any members at all, it'll be impossible to rejoin.</li>
  13533. <li>The first user to rejoin will have to do so via an alias on a different
  13534. server (or receive an invite from a user on a different server).</li>
  13535. </ul>
  13536. <p>With all that being said, if you still want to try and recover the room:</p>
  13537. <ol>
  13538. <li>
  13539. <p>If the room was <code>block</code>ed, you must unblock it on your server. This can be
  13540. accomplished as follows:</p>
  13541. <ol>
  13542. <li>For safety reasons, shut down Synapse.</li>
  13543. <li>In the database, run <code>DELETE FROM blocked_rooms WHERE room_id = '!example:example.org';</code>
  13544. <ul>
  13545. <li>For caution: it's recommended to run this in a transaction: <code>BEGIN; DELETE ...;</code>, verify you got 1 result, then <code>COMMIT;</code>.</li>
  13546. <li>The room ID is the same one supplied to the delete room API, not the Content Violation room.</li>
  13547. </ul>
  13548. </li>
  13549. <li>Restart Synapse.</li>
  13550. </ol>
  13551. <p>This step is unnecessary if <code>block</code> was not set.</p>
  13552. </li>
  13553. <li>
  13554. <p>Any room aliases on your server that pointed to the deleted room may have
  13555. been deleted, or redirected to the Content Violation room. These will need
  13556. to be restored manually.</p>
  13557. </li>
  13558. <li>
  13559. <p>Users on your server that were in the deleted room will have been kicked
  13560. from the room. Consider whether you want to update their membership
  13561. (possibly via the <a href="admin_api/room_membership.html">Edit Room Membership API</a>) or let
  13562. them handle rejoining themselves.</p>
  13563. </li>
  13564. <li>
  13565. <p>If <code>new_room_user_id</code> was given, a 'Content Violation' will have been
  13566. created. Consider whether you want to delete that roomm.</p>
  13567. </li>
  13568. </ol>
  13569. <h1 id="make-room-admin-api"><a class="header" href="#make-room-admin-api">Make Room Admin API</a></h1>
  13570. <p>Grants another user the highest power available to a local user who is in the room.
  13571. If the user is not in the room, and it is not publicly joinable, then invite the user.</p>
  13572. <p>By default the server admin (the caller) is granted power, but another user can
  13573. optionally be specified, e.g.:</p>
  13574. <pre><code>POST /_synapse/admin/v1/rooms/&lt;room_id_or_alias&gt;/make_room_admin
  13575. {
  13576. &quot;user_id&quot;: &quot;@foo:example.com&quot;
  13577. }
  13578. </code></pre>
  13579. <h1 id="forward-extremities-admin-api"><a class="header" href="#forward-extremities-admin-api">Forward Extremities Admin API</a></h1>
  13580. <p>Enables querying and deleting forward extremities from rooms. When a lot of forward
  13581. extremities accumulate in a room, performance can become degraded. For details, see
  13582. <a href="https://github.com/matrix-org/synapse/issues/1760">#1760</a>.</p>
  13583. <h2 id="check-for-forward-extremities"><a class="header" href="#check-for-forward-extremities">Check for forward extremities</a></h2>
  13584. <p>To check the status of forward extremities for a room:</p>
  13585. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id_or_alias&gt;/forward_extremities
  13586. </code></pre>
  13587. <p>A response as follows will be returned:</p>
  13588. <pre><code class="language-json">{
  13589. &quot;count&quot;: 1,
  13590. &quot;results&quot;: [
  13591. {
  13592. &quot;event_id&quot;: &quot;$M5SP266vsnxctfwFgFLNceaCo3ujhRtg_NiiHabcdefgh&quot;,
  13593. &quot;state_group&quot;: 439,
  13594. &quot;depth&quot;: 123,
  13595. &quot;received_ts&quot;: 1611263016761
  13596. }
  13597. ]
  13598. }
  13599. </code></pre>
  13600. <h2 id="deleting-forward-extremities"><a class="header" href="#deleting-forward-extremities">Deleting forward extremities</a></h2>
  13601. <p><strong>WARNING</strong>: Please ensure you know what you're doing and have read
  13602. the related issue <a href="https://github.com/matrix-org/synapse/issues/1760">#1760</a>.
  13603. Under no situations should this API be executed as an automated maintenance task!</p>
  13604. <p>If a room has lots of forward extremities, the extra can be
  13605. deleted as follows:</p>
  13606. <pre><code>DELETE /_synapse/admin/v1/rooms/&lt;room_id_or_alias&gt;/forward_extremities
  13607. </code></pre>
  13608. <p>A response as follows will be returned, indicating the amount of forward extremities
  13609. that were deleted.</p>
  13610. <pre><code class="language-json">{
  13611. &quot;deleted&quot;: 1
  13612. }
  13613. </code></pre>
  13614. <h1 id="event-context-api"><a class="header" href="#event-context-api">Event Context API</a></h1>
  13615. <p>This API lets a client find the context of an event. This is designed primarily to investigate abuse reports.</p>
  13616. <pre><code>GET /_synapse/admin/v1/rooms/&lt;room_id&gt;/context/&lt;event_id&gt;
  13617. </code></pre>
  13618. <p>This API mimmicks <a href="https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-rooms-roomid-context-eventid">GET /_matrix/client/r0/rooms/{roomId}/context/{eventId}</a>. Please refer to the link for all details on parameters and reseponse.</p>
  13619. <p>Example response:</p>
  13620. <pre><code class="language-json">{
  13621. &quot;end&quot;: &quot;t29-57_2_0_2&quot;,
  13622. &quot;events_after&quot;: [
  13623. {
  13624. &quot;content&quot;: {
  13625. &quot;body&quot;: &quot;This is an example text message&quot;,
  13626. &quot;msgtype&quot;: &quot;m.text&quot;,
  13627. &quot;format&quot;: &quot;org.matrix.custom.html&quot;,
  13628. &quot;formatted_body&quot;: &quot;&lt;b&gt;This is an example text message&lt;/b&gt;&quot;
  13629. },
  13630. &quot;type&quot;: &quot;m.room.message&quot;,
  13631. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13632. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13633. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13634. &quot;origin_server_ts&quot;: 1432735824653,
  13635. &quot;unsigned&quot;: {
  13636. &quot;age&quot;: 1234
  13637. }
  13638. }
  13639. ],
  13640. &quot;event&quot;: {
  13641. &quot;content&quot;: {
  13642. &quot;body&quot;: &quot;filename.jpg&quot;,
  13643. &quot;info&quot;: {
  13644. &quot;h&quot;: 398,
  13645. &quot;w&quot;: 394,
  13646. &quot;mimetype&quot;: &quot;image/jpeg&quot;,
  13647. &quot;size&quot;: 31037
  13648. },
  13649. &quot;url&quot;: &quot;mxc://example.org/JWEIFJgwEIhweiWJE&quot;,
  13650. &quot;msgtype&quot;: &quot;m.image&quot;
  13651. },
  13652. &quot;type&quot;: &quot;m.room.message&quot;,
  13653. &quot;event_id&quot;: &quot;$f3h4d129462ha:example.com&quot;,
  13654. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13655. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13656. &quot;origin_server_ts&quot;: 1432735824653,
  13657. &quot;unsigned&quot;: {
  13658. &quot;age&quot;: 1234
  13659. }
  13660. },
  13661. &quot;events_before&quot;: [
  13662. {
  13663. &quot;content&quot;: {
  13664. &quot;body&quot;: &quot;something-important.doc&quot;,
  13665. &quot;filename&quot;: &quot;something-important.doc&quot;,
  13666. &quot;info&quot;: {
  13667. &quot;mimetype&quot;: &quot;application/msword&quot;,
  13668. &quot;size&quot;: 46144
  13669. },
  13670. &quot;msgtype&quot;: &quot;m.file&quot;,
  13671. &quot;url&quot;: &quot;mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe&quot;
  13672. },
  13673. &quot;type&quot;: &quot;m.room.message&quot;,
  13674. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13675. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13676. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13677. &quot;origin_server_ts&quot;: 1432735824653,
  13678. &quot;unsigned&quot;: {
  13679. &quot;age&quot;: 1234
  13680. }
  13681. }
  13682. ],
  13683. &quot;start&quot;: &quot;t27-54_2_0_2&quot;,
  13684. &quot;state&quot;: [
  13685. {
  13686. &quot;content&quot;: {
  13687. &quot;creator&quot;: &quot;@example:example.org&quot;,
  13688. &quot;room_version&quot;: &quot;1&quot;,
  13689. &quot;m.federate&quot;: true,
  13690. &quot;predecessor&quot;: {
  13691. &quot;event_id&quot;: &quot;$something:example.org&quot;,
  13692. &quot;room_id&quot;: &quot;!oldroom:example.org&quot;
  13693. }
  13694. },
  13695. &quot;type&quot;: &quot;m.room.create&quot;,
  13696. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13697. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13698. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13699. &quot;origin_server_ts&quot;: 1432735824653,
  13700. &quot;unsigned&quot;: {
  13701. &quot;age&quot;: 1234
  13702. },
  13703. &quot;state_key&quot;: &quot;&quot;
  13704. },
  13705. {
  13706. &quot;content&quot;: {
  13707. &quot;membership&quot;: &quot;join&quot;,
  13708. &quot;avatar_url&quot;: &quot;mxc://example.org/SEsfnsuifSDFSSEF&quot;,
  13709. &quot;displayname&quot;: &quot;Alice Margatroid&quot;
  13710. },
  13711. &quot;type&quot;: &quot;m.room.member&quot;,
  13712. &quot;event_id&quot;: &quot;$143273582443PhrSn:example.org&quot;,
  13713. &quot;room_id&quot;: &quot;!636q39766251:example.com&quot;,
  13714. &quot;sender&quot;: &quot;@example:example.org&quot;,
  13715. &quot;origin_server_ts&quot;: 1432735824653,
  13716. &quot;unsigned&quot;: {
  13717. &quot;age&quot;: 1234
  13718. },
  13719. &quot;state_key&quot;: &quot;@alice:example.org&quot;
  13720. }
  13721. ]
  13722. }
  13723. </code></pre>
  13724. <div style="break-before: page; page-break-before: always;"></div><h1 id="server-notices-1"><a class="header" href="#server-notices-1">Server Notices</a></h1>
  13725. <p>The API to send notices is as follows:</p>
  13726. <pre><code>POST /_synapse/admin/v1/send_server_notice
  13727. </code></pre>
  13728. <p>or:</p>
  13729. <pre><code>PUT /_synapse/admin/v1/send_server_notice/{txnId}
  13730. </code></pre>
  13731. <p>You will need to authenticate with an access token for an admin user.</p>
  13732. <p>When using the <code>PUT</code> form, retransmissions with the same transaction ID will be
  13733. ignored in the same way as with <code>PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}</code>.</p>
  13734. <p>The request body should look something like the following:</p>
  13735. <pre><code class="language-json">{
  13736. &quot;user_id&quot;: &quot;@target_user:server_name&quot;,
  13737. &quot;content&quot;: {
  13738. &quot;msgtype&quot;: &quot;m.text&quot;,
  13739. &quot;body&quot;: &quot;This is my message&quot;
  13740. }
  13741. }
  13742. </code></pre>
  13743. <p>You can optionally include the following additional parameters:</p>
  13744. <ul>
  13745. <li><code>type</code>: the type of event. Defaults to <code>m.room.message</code>.</li>
  13746. <li><code>state_key</code>: Setting this will result in a state event being sent.</li>
  13747. </ul>
  13748. <p>Once the notice has been sent, the API will return the following response:</p>
  13749. <pre><code class="language-json">{
  13750. &quot;event_id&quot;: &quot;&lt;event_id&gt;&quot;
  13751. }
  13752. </code></pre>
  13753. <p>Note that server notices must be enabled in <code>homeserver.yaml</code> before this API
  13754. can be used. See <a href="admin_api/../server_notices.html">the server notices documentation</a> for more information.</p>
  13755. <div style="break-before: page; page-break-before: always;"></div><h1 id="users-media-usage-statistics"><a class="header" href="#users-media-usage-statistics">Users' media usage statistics</a></h1>
  13756. <p>Returns information about all local media usage of users. Gives the
  13757. possibility to filter them by time and user.</p>
  13758. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  13759. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  13760. <p>The API is:</p>
  13761. <pre><code>GET /_synapse/admin/v1/statistics/users/media
  13762. </code></pre>
  13763. <p>A response body like the following is returned:</p>
  13764. <pre><code class="language-json">{
  13765. &quot;users&quot;: [
  13766. {
  13767. &quot;displayname&quot;: &quot;foo_user_0&quot;,
  13768. &quot;media_count&quot;: 2,
  13769. &quot;media_length&quot;: 134,
  13770. &quot;user_id&quot;: &quot;@foo_user_0:test&quot;
  13771. },
  13772. {
  13773. &quot;displayname&quot;: &quot;foo_user_1&quot;,
  13774. &quot;media_count&quot;: 2,
  13775. &quot;media_length&quot;: 134,
  13776. &quot;user_id&quot;: &quot;@foo_user_1:test&quot;
  13777. }
  13778. ],
  13779. &quot;next_token&quot;: 3,
  13780. &quot;total&quot;: 10
  13781. }
  13782. </code></pre>
  13783. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint
  13784. again with <code>from</code> set to the value of <code>next_token</code>. This will return a new page.</p>
  13785. <p>If the endpoint does not return a <code>next_token</code> then there are no more
  13786. reports to paginate through.</p>
  13787. <p><strong>Parameters</strong></p>
  13788. <p>The following parameters should be set in the URL:</p>
  13789. <ul>
  13790. <li><code>limit</code>: string representing a positive integer - Is optional but is
  13791. used for pagination, denoting the maximum number of items to return
  13792. in this call. Defaults to <code>100</code>.</li>
  13793. <li><code>from</code>: string representing a positive integer - Is optional but used for pagination,
  13794. denoting the offset in the returned results. This should be treated as an opaque value
  13795. and not explicitly set to anything other than the return value of <code>next_token</code> from a
  13796. previous call. Defaults to <code>0</code>.</li>
  13797. <li><code>order_by</code> - string - The method in which to sort the returned list of users. Valid values are:
  13798. <ul>
  13799. <li><code>user_id</code> - Users are ordered alphabetically by <code>user_id</code>. This is the default.</li>
  13800. <li><code>displayname</code> - Users are ordered alphabetically by <code>displayname</code>.</li>
  13801. <li><code>media_length</code> - Users are ordered by the total size of uploaded media in bytes.
  13802. Smallest to largest.</li>
  13803. <li><code>media_count</code> - Users are ordered by number of uploaded media. Smallest to largest.</li>
  13804. </ul>
  13805. </li>
  13806. <li><code>from_ts</code> - string representing a positive integer - Considers only
  13807. files created at this timestamp or later. Unix timestamp in ms.</li>
  13808. <li><code>until_ts</code> - string representing a positive integer - Considers only
  13809. files created at this timestamp or earlier. Unix timestamp in ms.</li>
  13810. <li><code>search_term</code> - string - Filter users by their user ID localpart <strong>or</strong> displayname.
  13811. The search term can be found in any part of the string.
  13812. Defaults to no filtering.</li>
  13813. <li><code>dir</code> - string - Direction of order. Either <code>f</code> for forwards or <code>b</code> for backwards.
  13814. Setting this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</li>
  13815. </ul>
  13816. <p><strong>Response</strong></p>
  13817. <p>The following fields are returned in the JSON response body:</p>
  13818. <ul>
  13819. <li><code>users</code> - An array of objects, each containing information
  13820. about the user and their local media. Objects contain the following fields:
  13821. <ul>
  13822. <li><code>displayname</code> - string - Displayname of this user.</li>
  13823. <li><code>media_count</code> - integer - Number of uploaded media by this user.</li>
  13824. <li><code>media_length</code> - integer - Size of uploaded media in bytes by this user.</li>
  13825. <li><code>user_id</code> - string - Fully-qualified user ID (ex. <code>@user:server.com</code>).</li>
  13826. </ul>
  13827. </li>
  13828. <li><code>next_token</code> - integer - Opaque value used for pagination. See above.</li>
  13829. <li><code>total</code> - integer - Total number of users after filtering.</li>
  13830. </ul>
  13831. <h1 id="get-largest-rooms-by-size-in-database"><a class="header" href="#get-largest-rooms-by-size-in-database">Get largest rooms by size in database</a></h1>
  13832. <p>Returns the 10 largest rooms and an estimate of how much space in the database
  13833. they are taking.</p>
  13834. <p>This does not include the size of any associated media associated with the room.</p>
  13835. <p>Returns an error on SQLite.</p>
  13836. <p><em>Note:</em> This uses the planner statistics from PostgreSQL to do the estimates,
  13837. which means that the returned information can vary widely from reality. However,
  13838. it should be enough to get a rough idea of where database disk space is going.</p>
  13839. <p>The API is:</p>
  13840. <pre><code>GET /_synapse/admin/v1/statistics/database/rooms
  13841. </code></pre>
  13842. <p>A response body like the following is returned:</p>
  13843. <pre><code class="language-json">{
  13844. &quot;rooms&quot;: [
  13845. {
  13846. &quot;room_id&quot;: &quot;!OGEhHVWSdvArJzumhm:matrix.org&quot;,
  13847. &quot;estimated_size&quot;: 47325417353
  13848. }
  13849. ],
  13850. }
  13851. </code></pre>
  13852. <p><strong>Response</strong></p>
  13853. <p>The following fields are returned in the JSON response body:</p>
  13854. <ul>
  13855. <li><code>rooms</code> - An array of objects, sorted by largest room first. Objects contain
  13856. the following fields:
  13857. <ul>
  13858. <li><code>room_id</code> - string - The room ID.</li>
  13859. <li><code>estimated_size</code> - integer - Estimated disk space used in bytes by the room
  13860. in the database.</li>
  13861. </ul>
  13862. </li>
  13863. </ul>
  13864. <p><em>Added in Synapse 1.83.0</em></p>
  13865. <div style="break-before: page; page-break-before: always;"></div><h1 id="user-admin-api"><a class="header" href="#user-admin-api">User Admin API</a></h1>
  13866. <p>To use it, you will need to authenticate by providing an <code>access_token</code>
  13867. for a server admin: see <a href="admin_api/../usage/administration/admin_api/">Admin API</a>.</p>
  13868. <h2 id="query-user-account"><a class="header" href="#query-user-account">Query User Account</a></h2>
  13869. <p>This API returns information about a specific user account.</p>
  13870. <p>The api is:</p>
  13871. <pre><code>GET /_synapse/admin/v2/users/&lt;user_id&gt;
  13872. </code></pre>
  13873. <p>It returns a JSON body like the following:</p>
  13874. <pre><code class="language-jsonc">{
  13875. &quot;name&quot;: &quot;@user:example.com&quot;,
  13876. &quot;displayname&quot;: &quot;User&quot;, // can be null if not set
  13877. &quot;threepids&quot;: [
  13878. {
  13879. &quot;medium&quot;: &quot;email&quot;,
  13880. &quot;address&quot;: &quot;&lt;user_mail_1&gt;&quot;,
  13881. &quot;added_at&quot;: 1586458409743,
  13882. &quot;validated_at&quot;: 1586458409743
  13883. },
  13884. {
  13885. &quot;medium&quot;: &quot;email&quot;,
  13886. &quot;address&quot;: &quot;&lt;user_mail_2&gt;&quot;,
  13887. &quot;added_at&quot;: 1586458409743,
  13888. &quot;validated_at&quot;: 1586458409743
  13889. }
  13890. ],
  13891. &quot;avatar_url&quot;: &quot;&lt;avatar_url&gt;&quot;, // can be null if not set
  13892. &quot;is_guest&quot;: 0,
  13893. &quot;admin&quot;: 0,
  13894. &quot;deactivated&quot;: 0,
  13895. &quot;erased&quot;: false,
  13896. &quot;shadow_banned&quot;: 0,
  13897. &quot;creation_ts&quot;: 1560432506,
  13898. &quot;appservice_id&quot;: null,
  13899. &quot;consent_server_notice_sent&quot;: null,
  13900. &quot;consent_version&quot;: null,
  13901. &quot;consent_ts&quot;: null,
  13902. &quot;external_ids&quot;: [
  13903. {
  13904. &quot;auth_provider&quot;: &quot;&lt;provider1&gt;&quot;,
  13905. &quot;external_id&quot;: &quot;&lt;user_id_provider_1&gt;&quot;
  13906. },
  13907. {
  13908. &quot;auth_provider&quot;: &quot;&lt;provider2&gt;&quot;,
  13909. &quot;external_id&quot;: &quot;&lt;user_id_provider_2&gt;&quot;
  13910. }
  13911. ],
  13912. &quot;user_type&quot;: null,
  13913. &quot;locked&quot;: false
  13914. }
  13915. </code></pre>
  13916. <p>URL parameters:</p>
  13917. <ul>
  13918. <li><code>user_id</code>: fully-qualified user id: for example, <code>@user:server.com</code>.</li>
  13919. </ul>
  13920. <h2 id="create-or-modify-account"><a class="header" href="#create-or-modify-account">Create or modify account</a></h2>
  13921. <p>This API allows an administrator to create or modify a user account with a
  13922. specific <code>user_id</code>.</p>
  13923. <p>This api is:</p>
  13924. <pre><code>PUT /_synapse/admin/v2/users/&lt;user_id&gt;
  13925. </code></pre>
  13926. <p>with a body of:</p>
  13927. <pre><code class="language-json">{
  13928. &quot;password&quot;: &quot;user_password&quot;,
  13929. &quot;logout_devices&quot;: false,
  13930. &quot;displayname&quot;: &quot;Alice Marigold&quot;,
  13931. &quot;avatar_url&quot;: &quot;mxc://example.com/abcde12345&quot;,
  13932. &quot;threepids&quot;: [
  13933. {
  13934. &quot;medium&quot;: &quot;email&quot;,
  13935. &quot;address&quot;: &quot;alice@example.com&quot;
  13936. },
  13937. {
  13938. &quot;medium&quot;: &quot;email&quot;,
  13939. &quot;address&quot;: &quot;alice@domain.org&quot;
  13940. }
  13941. ],
  13942. &quot;external_ids&quot;: [
  13943. {
  13944. &quot;auth_provider&quot;: &quot;example&quot;,
  13945. &quot;external_id&quot;: &quot;12345&quot;
  13946. },
  13947. {
  13948. &quot;auth_provider&quot;: &quot;example2&quot;,
  13949. &quot;external_id&quot;: &quot;abc54321&quot;
  13950. }
  13951. ],
  13952. &quot;admin&quot;: false,
  13953. &quot;deactivated&quot;: false,
  13954. &quot;user_type&quot;: null,
  13955. &quot;locked&quot;: false
  13956. }
  13957. </code></pre>
  13958. <p>Returns HTTP status code:</p>
  13959. <ul>
  13960. <li><code>201</code> - When a new user object was created.</li>
  13961. <li><code>200</code> - When a user was modified.</li>
  13962. </ul>
  13963. <p>URL parameters:</p>
  13964. <ul>
  13965. <li><code>user_id</code> - A fully-qualified user id. For example, <code>@user:server.com</code>.</li>
  13966. </ul>
  13967. <p>Body parameters:</p>
  13968. <ul>
  13969. <li>
  13970. <p><code>password</code> - <strong>string</strong>, optional. If provided, the user's password is updated and all
  13971. devices are logged out, unless <code>logout_devices</code> is set to <code>false</code>.</p>
  13972. </li>
  13973. <li>
  13974. <p><code>logout_devices</code> - <strong>bool</strong>, optional, defaults to <code>true</code>. If set to <code>false</code>, devices aren't
  13975. logged out even when <code>password</code> is provided.</p>
  13976. </li>
  13977. <li>
  13978. <p><code>displayname</code> - <strong>string</strong>, optional. If set to an empty string (<code>&quot;&quot;</code>), the user's display name
  13979. will be removed.</p>
  13980. </li>
  13981. <li>
  13982. <p><code>avatar_url</code> - <strong>string</strong>, optional. Must be a
  13983. <a href="https://matrix.org/docs/spec/client_server/r0.6.0#matrix-content-mxc-uris">MXC URI</a>.
  13984. If set to an empty string (<code>&quot;&quot;</code>), the user's avatar is removed.</p>
  13985. </li>
  13986. <li>
  13987. <p><code>threepids</code> - <strong>array</strong>, optional. If provided, the user's third-party IDs (email, msisdn) are
  13988. entirely replaced with the given list. Each item in the array is an object with the following
  13989. fields:</p>
  13990. <ul>
  13991. <li><code>medium</code> - <strong>string</strong>, required. The type of third-party ID, either <code>email</code> or <code>msisdn</code> (phone number).</li>
  13992. <li><code>address</code> - <strong>string</strong>, required. The third-party ID itself, e.g. <code>alice@example.com</code> for <code>email</code> or
  13993. <code>447470274584</code> (for a phone number with country code &quot;44&quot;) and <code>19254857364</code> (for a phone number
  13994. with country code &quot;1&quot;) for <code>msisdn</code>.
  13995. Note: If a threepid is removed from a user via this option, Synapse will also attempt to remove
  13996. that threepid from any identity servers it is aware has a binding for it.</li>
  13997. </ul>
  13998. </li>
  13999. <li>
  14000. <p><code>external_ids</code> - <strong>array</strong>, optional. Allow setting the identifier of the external identity
  14001. provider for SSO (Single sign-on). More details are in the configuration manual under the
  14002. sections <a href="admin_api/../usage/configuration/config_documentation.html#sso">sso</a> and <a href="admin_api/../usage/configuration/config_documentation.html#oidc_providers">oidc_providers</a>.</p>
  14003. <ul>
  14004. <li><code>auth_provider</code> - <strong>string</strong>, required. The unique, internal ID of the external identity provider.
  14005. The same as <code>idp_id</code> from the homeserver configuration. Note that no error is raised if the
  14006. provided value is not in the homeserver configuration.</li>
  14007. <li><code>external_id</code> - <strong>string</strong>, required. An identifier for the user in the external identity provider.
  14008. When the user logs in to the identity provider, this must be the unique ID that they map to.</li>
  14009. </ul>
  14010. </li>
  14011. <li>
  14012. <p><code>admin</code> - <strong>bool</strong>, optional, defaults to <code>false</code>. Whether the user is a homeserver administrator,
  14013. granting them access to the Admin API, among other things.</p>
  14014. </li>
  14015. <li>
  14016. <p><code>deactivated</code> - <strong>bool</strong>, optional. If unspecified, deactivation state will be left unchanged.</p>
  14017. <p>Note: the <code>password</code> field must also be set if both of the following are true:</p>
  14018. <ul>
  14019. <li><code>deactivated</code> is set to <code>false</code> and the user was previously deactivated (you are reactivating this user)</li>
  14020. <li>Users are allowed to set their password on this homeserver (both <code>password_config.enabled</code> and
  14021. <code>password_config.localdb_enabled</code> config options are set to <code>true</code>).
  14022. Users' passwords are wiped upon account deactivation, hence the need to set a new one here.</li>
  14023. </ul>
  14024. <p>Note: a user cannot be erased with this API. For more details on
  14025. deactivating and erasing users see <a href="admin_api/user_admin_api.html#deactivate-account">Deactivate Account</a>.</p>
  14026. </li>
  14027. <li>
  14028. <p><code>locked</code> - <strong>bool</strong>, optional. If unspecified, locked state will be left unchanged.</p>
  14029. </li>
  14030. <li>
  14031. <p><code>user_type</code> - <strong>string</strong> or null, optional. If not provided, the user type will be
  14032. not be changed. If <code>null</code> is given, the user type will be cleared.
  14033. Other allowed options are: <code>bot</code> and <code>support</code>.</p>
  14034. </li>
  14035. </ul>
  14036. <h2 id="list-accounts"><a class="header" href="#list-accounts">List Accounts</a></h2>
  14037. <p>This API returns all local user accounts.
  14038. By default, the response is ordered by ascending user ID.</p>
  14039. <pre><code>GET /_synapse/admin/v2/users?from=0&amp;limit=10&amp;guests=false
  14040. </code></pre>
  14041. <p>A response body like the following is returned:</p>
  14042. <pre><code class="language-json">{
  14043. &quot;users&quot;: [
  14044. {
  14045. &quot;name&quot;: &quot;&lt;user_id1&gt;&quot;,
  14046. &quot;is_guest&quot;: 0,
  14047. &quot;admin&quot;: 0,
  14048. &quot;user_type&quot;: null,
  14049. &quot;deactivated&quot;: 0,
  14050. &quot;erased&quot;: false,
  14051. &quot;shadow_banned&quot;: 0,
  14052. &quot;displayname&quot;: &quot;&lt;User One&gt;&quot;,
  14053. &quot;avatar_url&quot;: null,
  14054. &quot;creation_ts&quot;: 1560432668000,
  14055. &quot;locked&quot;: false
  14056. }, {
  14057. &quot;name&quot;: &quot;&lt;user_id2&gt;&quot;,
  14058. &quot;is_guest&quot;: 0,
  14059. &quot;admin&quot;: 1,
  14060. &quot;user_type&quot;: null,
  14061. &quot;deactivated&quot;: 0,
  14062. &quot;erased&quot;: false,
  14063. &quot;shadow_banned&quot;: 0,
  14064. &quot;displayname&quot;: &quot;&lt;User Two&gt;&quot;,
  14065. &quot;avatar_url&quot;: &quot;&lt;avatar_url&gt;&quot;,
  14066. &quot;creation_ts&quot;: 1561550621000,
  14067. &quot;locked&quot;: false
  14068. }
  14069. ],
  14070. &quot;next_token&quot;: &quot;100&quot;,
  14071. &quot;total&quot;: 200
  14072. }
  14073. </code></pre>
  14074. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint again
  14075. with <code>from</code> set to the value of <code>next_token</code>. This will return a new page.</p>
  14076. <p>If the endpoint does not return a <code>next_token</code> then there are no more users
  14077. to paginate through.</p>
  14078. <p><strong>Parameters</strong></p>
  14079. <p>The following parameters should be set in the URL:</p>
  14080. <ul>
  14081. <li>
  14082. <p><code>user_id</code> - Is optional and filters to only return users with user IDs
  14083. that contain this value. This parameter is ignored when using the <code>name</code> parameter.</p>
  14084. </li>
  14085. <li>
  14086. <p><code>name</code> - Is optional and filters to only return users with user ID localparts
  14087. <strong>or</strong> displaynames that contain this value.</p>
  14088. </li>
  14089. <li>
  14090. <p><code>guests</code> - string representing a bool - Is optional and if <code>false</code> will <strong>exclude</strong> guest users.
  14091. Defaults to <code>true</code> to include guest users. This parameter is not supported when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  14092. </li>
  14093. <li>
  14094. <p><code>admins</code> - Optional flag to filter admins. If <code>true</code>, only admins are queried. If <code>false</code>, admins are excluded from
  14095. the query. When the flag is absent (the default), <strong>both</strong> admins and non-admins are included in the search results.</p>
  14096. </li>
  14097. <li>
  14098. <p><code>deactivated</code> - string representing a bool - Is optional and if <code>true</code> will <strong>include</strong> deactivated users.
  14099. Defaults to <code>false</code> to exclude deactivated users.</p>
  14100. </li>
  14101. <li>
  14102. <p><code>limit</code> - string representing a positive integer - Is optional but is used for pagination,
  14103. denoting the maximum number of items to return in this call. Defaults to <code>100</code>.</p>
  14104. </li>
  14105. <li>
  14106. <p><code>from</code> - string representing a positive integer - Is optional but used for pagination,
  14107. denoting the offset in the returned results. This should be treated as an opaque value and
  14108. not explicitly set to anything other than the return value of <code>next_token</code> from a previous call.
  14109. Defaults to <code>0</code>.</p>
  14110. </li>
  14111. <li>
  14112. <p><code>order_by</code> - The method by which to sort the returned list of users.
  14113. If the ordered field has duplicates, the second order is always by ascending <code>name</code>,
  14114. which guarantees a stable ordering. Valid values are:</p>
  14115. <ul>
  14116. <li><code>name</code> - Users are ordered alphabetically by <code>name</code>. This is the default.</li>
  14117. <li><code>is_guest</code> - Users are ordered by <code>is_guest</code> status.</li>
  14118. <li><code>admin</code> - Users are ordered by <code>admin</code> status.</li>
  14119. <li><code>user_type</code> - Users are ordered alphabetically by <code>user_type</code>.</li>
  14120. <li><code>deactivated</code> - Users are ordered by <code>deactivated</code> status.</li>
  14121. <li><code>shadow_banned</code> - Users are ordered by <code>shadow_banned</code> status.</li>
  14122. <li><code>displayname</code> - Users are ordered alphabetically by <code>displayname</code>.</li>
  14123. <li><code>avatar_url</code> - Users are ordered alphabetically by avatar URL.</li>
  14124. <li><code>creation_ts</code> - Users are ordered by when the users was created in ms.</li>
  14125. <li><code>last_seen_ts</code> - Users are ordered by when the user was lastly seen in ms.</li>
  14126. </ul>
  14127. </li>
  14128. <li>
  14129. <p><code>dir</code> - Direction of media order. Either <code>f</code> for forwards or <code>b</code> for backwards.
  14130. Setting this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</p>
  14131. </li>
  14132. <li>
  14133. <p><code>not_user_type</code> - Exclude certain user types, such as bot users, from the request.
  14134. Can be provided multiple times. Possible values are <code>bot</code>, <code>support</code> or &quot;empty string&quot;.
  14135. &quot;empty string&quot; here means to exclude users without a type.</p>
  14136. </li>
  14137. <li>
  14138. <p><code>locked</code> - string representing a bool - Is optional and if <code>true</code> will <strong>include</strong> locked users.
  14139. Defaults to <code>false</code> to exclude locked users. Note: Introduced in v1.93.</p>
  14140. </li>
  14141. </ul>
  14142. <p>Caution. The database only has indexes on the columns <code>name</code> and <code>creation_ts</code>.
  14143. This means that if a different sort order is used (<code>is_guest</code>, <code>admin</code>,
  14144. <code>user_type</code>, <code>deactivated</code>, <code>shadow_banned</code>, <code>avatar_url</code> or <code>displayname</code>),
  14145. this can cause a large load on the database, especially for large environments.</p>
  14146. <p><strong>Response</strong></p>
  14147. <p>The following fields are returned in the JSON response body:</p>
  14148. <ul>
  14149. <li>
  14150. <p><code>users</code> - An array of objects, each containing information about an user.
  14151. User objects contain the following fields:</p>
  14152. <ul>
  14153. <li><code>name</code> - string - Fully-qualified user ID (ex. <code>@user:server.com</code>).</li>
  14154. <li><code>is_guest</code> - bool - Status if that user is a guest account.</li>
  14155. <li><code>admin</code> - bool - Status if that user is a server administrator.</li>
  14156. <li><code>user_type</code> - string - Type of the user. Normal users are type <code>None</code>.
  14157. This allows user type specific behaviour. There are also types <code>support</code> and <code>bot</code>. </li>
  14158. <li><code>deactivated</code> - bool - Status if that user has been marked as deactivated.</li>
  14159. <li><code>erased</code> - bool - Status if that user has been marked as erased.</li>
  14160. <li><code>shadow_banned</code> - bool - Status if that user has been marked as shadow banned.</li>
  14161. <li><code>displayname</code> - string - The user's display name if they have set one.</li>
  14162. <li><code>avatar_url</code> - string - The user's avatar URL if they have set one.</li>
  14163. <li><code>creation_ts</code> - integer - The user's creation timestamp in ms.</li>
  14164. <li><code>last_seen_ts</code> - integer - The user's last activity timestamp in ms.</li>
  14165. <li><code>locked</code> - bool - Status if that user has been marked as locked. Note: Introduced in v1.93.</li>
  14166. </ul>
  14167. </li>
  14168. <li>
  14169. <p><code>next_token</code>: string representing a positive integer - Indication for pagination. See above.</p>
  14170. </li>
  14171. <li>
  14172. <p><code>total</code> - integer - Total number of media.</p>
  14173. </li>
  14174. </ul>
  14175. <p><em>Added in Synapse 1.93:</em> the <code>locked</code> query parameter and response field.</p>
  14176. <h2 id="query-current-sessions-for-a-user"><a class="header" href="#query-current-sessions-for-a-user">Query current sessions for a user</a></h2>
  14177. <p>This API returns information about the active sessions for a specific user.</p>
  14178. <p>The endpoints are:</p>
  14179. <pre><code>GET /_synapse/admin/v1/whois/&lt;user_id&gt;
  14180. </code></pre>
  14181. <p>and:</p>
  14182. <pre><code>GET /_matrix/client/r0/admin/whois/&lt;userId&gt;
  14183. </code></pre>
  14184. <p>See also: <a href="https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-admin-whois-userid">Client Server
  14185. API Whois</a>.</p>
  14186. <p>It returns a JSON body like the following:</p>
  14187. <pre><code class="language-json">{
  14188. &quot;user_id&quot;: &quot;&lt;user_id&gt;&quot;,
  14189. &quot;devices&quot;: {
  14190. &quot;&quot;: {
  14191. &quot;sessions&quot;: [
  14192. {
  14193. &quot;connections&quot;: [
  14194. {
  14195. &quot;ip&quot;: &quot;1.2.3.4&quot;,
  14196. &quot;last_seen&quot;: 1417222374433,
  14197. &quot;user_agent&quot;: &quot;Mozilla/5.0 ...&quot;
  14198. },
  14199. {
  14200. &quot;ip&quot;: &quot;1.2.3.10&quot;,
  14201. &quot;last_seen&quot;: 1417222374500,
  14202. &quot;user_agent&quot;: &quot;Dalvik/2.1.0 ...&quot;
  14203. }
  14204. ]
  14205. }
  14206. ]
  14207. }
  14208. }
  14209. }
  14210. </code></pre>
  14211. <p><code>last_seen</code> is measured in milliseconds since the Unix epoch.</p>
  14212. <h2 id="deactivate-account"><a class="header" href="#deactivate-account">Deactivate Account</a></h2>
  14213. <p>This API deactivates an account. It removes active access tokens, resets the
  14214. password, and deletes third-party IDs (to prevent the user requesting a
  14215. password reset).</p>
  14216. <p>It can also mark the user as GDPR-erased. This means messages sent by the
  14217. user will still be visible by anyone that was in the room when these messages
  14218. were sent, but hidden from users joining the room afterwards.</p>
  14219. <p>The api is:</p>
  14220. <pre><code>POST /_synapse/admin/v1/deactivate/&lt;user_id&gt;
  14221. </code></pre>
  14222. <p>with a body of:</p>
  14223. <pre><code class="language-json">{
  14224. &quot;erase&quot;: true
  14225. }
  14226. </code></pre>
  14227. <p>The erase parameter is optional and defaults to <code>false</code>.
  14228. An empty body may be passed for backwards compatibility.</p>
  14229. <p>The following actions are performed when deactivating an user:</p>
  14230. <ul>
  14231. <li>Try to unbind 3PIDs from the identity server</li>
  14232. <li>Remove all 3PIDs from the homeserver</li>
  14233. <li>Delete all devices and E2EE keys</li>
  14234. <li>Delete all access tokens</li>
  14235. <li>Delete all pushers</li>
  14236. <li>Delete the password hash</li>
  14237. <li>Removal from all rooms the user is a member of</li>
  14238. <li>Remove the user from the user directory</li>
  14239. <li>Reject all pending invites</li>
  14240. <li>Remove all account validity information related to the user</li>
  14241. <li>Remove the arbitrary data store known as <em>account data</em>. For example, this includes:
  14242. <ul>
  14243. <li>list of ignored users;</li>
  14244. <li>push rules;</li>
  14245. <li>secret storage keys; and</li>
  14246. <li>cross-signing keys.</li>
  14247. </ul>
  14248. </li>
  14249. </ul>
  14250. <p>The following additional actions are performed during deactivation if <code>erase</code>
  14251. is set to <code>true</code>:</p>
  14252. <ul>
  14253. <li>Remove the user's display name</li>
  14254. <li>Remove the user's avatar URL</li>
  14255. <li>Mark the user as erased</li>
  14256. </ul>
  14257. <p>The following actions are <strong>NOT</strong> performed. The list may be incomplete.</p>
  14258. <ul>
  14259. <li>Remove mappings of SSO IDs</li>
  14260. <li><a href="admin_api/user_admin_api.html#delete-media-uploaded-by-a-user">Delete media uploaded</a> by user (included avatar images)</li>
  14261. <li>Delete sent and received messages</li>
  14262. <li>Remove the user's creation (registration) timestamp</li>
  14263. <li><a href="admin_api/user_admin_api.html#override-ratelimiting-for-users">Remove rate limit overrides</a></li>
  14264. <li>Remove from monthly active users</li>
  14265. <li>Remove user's consent information (consent version and timestamp)</li>
  14266. </ul>
  14267. <h2 id="reset-password"><a class="header" href="#reset-password">Reset password</a></h2>
  14268. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  14269. <p>Changes the password of another user. This will automatically log the user out of all their devices.</p>
  14270. <p>The api is:</p>
  14271. <pre><code>POST /_synapse/admin/v1/reset_password/&lt;user_id&gt;
  14272. </code></pre>
  14273. <p>with a body of:</p>
  14274. <pre><code class="language-json">{
  14275. &quot;new_password&quot;: &quot;&lt;secret&gt;&quot;,
  14276. &quot;logout_devices&quot;: true
  14277. }
  14278. </code></pre>
  14279. <p>The parameter <code>new_password</code> is required.
  14280. The parameter <code>logout_devices</code> is optional and defaults to <code>true</code>.</p>
  14281. <h2 id="get-whether-a-user-is-a-server-administrator-or-not"><a class="header" href="#get-whether-a-user-is-a-server-administrator-or-not">Get whether a user is a server administrator or not</a></h2>
  14282. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  14283. <p>The api is:</p>
  14284. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/admin
  14285. </code></pre>
  14286. <p>A response body like the following is returned:</p>
  14287. <pre><code class="language-json">{
  14288. &quot;admin&quot;: true
  14289. }
  14290. </code></pre>
  14291. <h2 id="change-whether-a-user-is-a-server-administrator-or-not"><a class="header" href="#change-whether-a-user-is-a-server-administrator-or-not">Change whether a user is a server administrator or not</a></h2>
  14292. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  14293. <p>Note that you cannot demote yourself.</p>
  14294. <p>The api is:</p>
  14295. <pre><code>PUT /_synapse/admin/v1/users/&lt;user_id&gt;/admin
  14296. </code></pre>
  14297. <p>with a body of:</p>
  14298. <pre><code class="language-json">{
  14299. &quot;admin&quot;: true
  14300. }
  14301. </code></pre>
  14302. <h2 id="list-room-memberships-of-a-user"><a class="header" href="#list-room-memberships-of-a-user">List room memberships of a user</a></h2>
  14303. <p>Gets a list of all <code>room_id</code> that a specific <code>user_id</code> is member.</p>
  14304. <p>The API is:</p>
  14305. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/joined_rooms
  14306. </code></pre>
  14307. <p>A response body like the following is returned:</p>
  14308. <pre><code class="language-json"> {
  14309. &quot;joined_rooms&quot;: [
  14310. &quot;!DuGcnbhHGaSZQoNQR:matrix.org&quot;,
  14311. &quot;!ZtSaPCawyWtxfWiIy:matrix.org&quot;
  14312. ],
  14313. &quot;total&quot;: 2
  14314. }
  14315. </code></pre>
  14316. <p>The server returns the list of rooms of which the user and the server
  14317. are member. If the user is local, all the rooms of which the user is
  14318. member are returned.</p>
  14319. <p><strong>Parameters</strong></p>
  14320. <p>The following parameters should be set in the URL:</p>
  14321. <ul>
  14322. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14323. </ul>
  14324. <p><strong>Response</strong></p>
  14325. <p>The following fields are returned in the JSON response body:</p>
  14326. <ul>
  14327. <li><code>joined_rooms</code> - An array of <code>room_id</code>.</li>
  14328. <li><code>total</code> - Number of rooms.</li>
  14329. </ul>
  14330. <h2 id="account-data"><a class="header" href="#account-data">Account Data</a></h2>
  14331. <p>Gets information about account data for a specific <code>user_id</code>.</p>
  14332. <p>The API is:</p>
  14333. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/accountdata
  14334. </code></pre>
  14335. <p>A response body like the following is returned:</p>
  14336. <pre><code class="language-json">{
  14337. &quot;account_data&quot;: {
  14338. &quot;global&quot;: {
  14339. &quot;m.secret_storage.key.LmIGHTg5W&quot;: {
  14340. &quot;algorithm&quot;: &quot;m.secret_storage.v1.aes-hmac-sha2&quot;,
  14341. &quot;iv&quot;: &quot;fwjNZatxg==&quot;,
  14342. &quot;mac&quot;: &quot;eWh9kNnLWZUNOgnc=&quot;
  14343. },
  14344. &quot;im.vector.hide_profile&quot;: {
  14345. &quot;hide_profile&quot;: true
  14346. },
  14347. &quot;org.matrix.preview_urls&quot;: {
  14348. &quot;disable&quot;: false
  14349. },
  14350. &quot;im.vector.riot.breadcrumb_rooms&quot;: {
  14351. &quot;rooms&quot;: [
  14352. &quot;!LxcBDAsDUVAfJDEo:matrix.org&quot;,
  14353. &quot;!MAhRxqasbItjOqxu:matrix.org&quot;
  14354. ]
  14355. },
  14356. &quot;m.accepted_terms&quot;: {
  14357. &quot;accepted&quot;: [
  14358. &quot;https://example.org/somewhere/privacy-1.2-en.html&quot;,
  14359. &quot;https://example.org/somewhere/terms-2.0-en.html&quot;
  14360. ]
  14361. },
  14362. &quot;im.vector.setting.breadcrumbs&quot;: {
  14363. &quot;recent_rooms&quot;: [
  14364. &quot;!MAhRxqasbItqxuEt:matrix.org&quot;,
  14365. &quot;!ZtSaPCawyWtxiImy:matrix.org&quot;
  14366. ]
  14367. }
  14368. },
  14369. &quot;rooms&quot;: {
  14370. &quot;!GUdfZSHUJibpiVqHYd:matrix.org&quot;: {
  14371. &quot;m.fully_read&quot;: {
  14372. &quot;event_id&quot;: &quot;$156334540fYIhZ:matrix.org&quot;
  14373. }
  14374. },
  14375. &quot;!tOZwOOiqwCYQkLhV:matrix.org&quot;: {
  14376. &quot;m.fully_read&quot;: {
  14377. &quot;event_id&quot;: &quot;$xjsIyp4_NaVl2yPvIZs_k1Jl8tsC_Sp23wjqXPno&quot;
  14378. }
  14379. }
  14380. }
  14381. }
  14382. }
  14383. </code></pre>
  14384. <p><strong>Parameters</strong></p>
  14385. <p>The following parameters should be set in the URL:</p>
  14386. <ul>
  14387. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14388. </ul>
  14389. <p><strong>Response</strong></p>
  14390. <p>The following fields are returned in the JSON response body:</p>
  14391. <ul>
  14392. <li><code>account_data</code> - A map containing the account data for the user
  14393. <ul>
  14394. <li><code>global</code> - A map containing the global account data for the user</li>
  14395. <li><code>rooms</code> - A map containing the account data per room for the user</li>
  14396. </ul>
  14397. </li>
  14398. </ul>
  14399. <h2 id="user-media"><a class="header" href="#user-media">User media</a></h2>
  14400. <h3 id="list-media-uploaded-by-a-user"><a class="header" href="#list-media-uploaded-by-a-user">List media uploaded by a user</a></h3>
  14401. <p>Gets a list of all local media that a specific <code>user_id</code> has created.
  14402. These are media that the user has uploaded themselves
  14403. (<a href="admin_api/../media_repository.html#local-media">local media</a>), as well as
  14404. <a href="admin_api/../media_repository.html#url-previews">URL preview images</a> requested by the user if the
  14405. <a href="admin_api/../usage/configuration/config_documentation.html#url_preview_enabled">feature is enabled</a>.</p>
  14406. <p>By default, the response is ordered by descending creation date and ascending media ID.
  14407. The newest media is on top. You can change the order with parameters
  14408. <code>order_by</code> and <code>dir</code>.</p>
  14409. <p>The API is:</p>
  14410. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/media
  14411. </code></pre>
  14412. <p>A response body like the following is returned:</p>
  14413. <pre><code class="language-json">{
  14414. &quot;media&quot;: [
  14415. {
  14416. &quot;created_ts&quot;: 100400,
  14417. &quot;last_access_ts&quot;: null,
  14418. &quot;media_id&quot;: &quot;qXhyRzulkwLsNHTbpHreuEgo&quot;,
  14419. &quot;media_length&quot;: 67,
  14420. &quot;media_type&quot;: &quot;image/png&quot;,
  14421. &quot;quarantined_by&quot;: null,
  14422. &quot;safe_from_quarantine&quot;: false,
  14423. &quot;upload_name&quot;: &quot;test1.png&quot;
  14424. },
  14425. {
  14426. &quot;created_ts&quot;: 200400,
  14427. &quot;last_access_ts&quot;: null,
  14428. &quot;media_id&quot;: &quot;FHfiSnzoINDatrXHQIXBtahw&quot;,
  14429. &quot;media_length&quot;: 67,
  14430. &quot;media_type&quot;: &quot;image/png&quot;,
  14431. &quot;quarantined_by&quot;: null,
  14432. &quot;safe_from_quarantine&quot;: false,
  14433. &quot;upload_name&quot;: &quot;test2.png&quot;
  14434. },
  14435. {
  14436. &quot;created_ts&quot;: 300400,
  14437. &quot;last_access_ts&quot;: 300700,
  14438. &quot;media_id&quot;: &quot;BzYNLRUgGHphBkdKGbzXwbjX&quot;,
  14439. &quot;media_length&quot;: 1337,
  14440. &quot;media_type&quot;: &quot;application/octet-stream&quot;,
  14441. &quot;quarantined_by&quot;: null,
  14442. &quot;safe_from_quarantine&quot;: false,
  14443. &quot;upload_name&quot;: null
  14444. }
  14445. ],
  14446. &quot;next_token&quot;: 3,
  14447. &quot;total&quot;: 2
  14448. }
  14449. </code></pre>
  14450. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint again
  14451. with <code>from</code> set to the value of <code>next_token</code>. This will return a new page.</p>
  14452. <p>If the endpoint does not return a <code>next_token</code> then there are no more
  14453. reports to paginate through.</p>
  14454. <p><strong>Parameters</strong></p>
  14455. <p>The following parameters should be set in the URL:</p>
  14456. <ul>
  14457. <li>
  14458. <p><code>user_id</code> - string - fully qualified: for example, <code>@user:server.com</code>.</p>
  14459. </li>
  14460. <li>
  14461. <p><code>limit</code>: string representing a positive integer - Is optional but is used for pagination,
  14462. denoting the maximum number of items to return in this call. Defaults to <code>100</code>.</p>
  14463. </li>
  14464. <li>
  14465. <p><code>from</code>: string representing a positive integer - Is optional but used for pagination,
  14466. denoting the offset in the returned results. This should be treated as an opaque value and
  14467. not explicitly set to anything other than the return value of <code>next_token</code> from a previous call.
  14468. Defaults to <code>0</code>.</p>
  14469. </li>
  14470. <li>
  14471. <p><code>order_by</code> - The method by which to sort the returned list of media.
  14472. If the ordered field has duplicates, the second order is always by ascending <code>media_id</code>,
  14473. which guarantees a stable ordering. Valid values are:</p>
  14474. <ul>
  14475. <li><code>media_id</code> - Media are ordered alphabetically by <code>media_id</code>.</li>
  14476. <li><code>upload_name</code> - Media are ordered alphabetically by name the media was uploaded with.</li>
  14477. <li><code>created_ts</code> - Media are ordered by when the content was uploaded in ms.
  14478. Smallest to largest. This is the default.</li>
  14479. <li><code>last_access_ts</code> - Media are ordered by when the content was last accessed in ms.
  14480. Smallest to largest.</li>
  14481. <li><code>media_length</code> - Media are ordered by length of the media in bytes.
  14482. Smallest to largest.</li>
  14483. <li><code>media_type</code> - Media are ordered alphabetically by MIME-type.</li>
  14484. <li><code>quarantined_by</code> - Media are ordered alphabetically by the user ID that
  14485. initiated the quarantine request for this media.</li>
  14486. <li><code>safe_from_quarantine</code> - Media are ordered by the status if this media is safe
  14487. from quarantining.</li>
  14488. </ul>
  14489. </li>
  14490. <li>
  14491. <p><code>dir</code> - Direction of media order. Either <code>f</code> for forwards or <code>b</code> for backwards.
  14492. Setting this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</p>
  14493. </li>
  14494. </ul>
  14495. <p>If neither <code>order_by</code> nor <code>dir</code> is set, the default order is newest media on top
  14496. (corresponds to <code>order_by</code> = <code>created_ts</code> and <code>dir</code> = <code>b</code>).</p>
  14497. <p>Caution. The database only has indexes on the columns <code>media_id</code>,
  14498. <code>user_id</code> and <code>created_ts</code>. This means that if a different sort order is used
  14499. (<code>upload_name</code>, <code>last_access_ts</code>, <code>media_length</code>, <code>media_type</code>,
  14500. <code>quarantined_by</code> or <code>safe_from_quarantine</code>), this can cause a large load on the
  14501. database, especially for large environments.</p>
  14502. <p><strong>Response</strong></p>
  14503. <p>The following fields are returned in the JSON response body:</p>
  14504. <ul>
  14505. <li><code>media</code> - An array of objects, each containing information about a media.
  14506. Media objects contain the following fields:
  14507. <ul>
  14508. <li><code>created_ts</code> - integer - Timestamp when the content was uploaded in ms.</li>
  14509. <li><code>last_access_ts</code> - integer or null - Timestamp when the content was last accessed in ms.
  14510. Null if there was no access, yet.</li>
  14511. <li><code>media_id</code> - string - The id used to refer to the media. Details about the format
  14512. are documented under
  14513. <a href="admin_api/../media_repository.html">media repository</a>.</li>
  14514. <li><code>media_length</code> - integer - Length of the media in bytes.</li>
  14515. <li><code>media_type</code> - string - The MIME-type of the media.</li>
  14516. <li><code>quarantined_by</code> - string or null - The user ID that initiated the quarantine request
  14517. for this media. Null if not quarantined.</li>
  14518. <li><code>safe_from_quarantine</code> - bool - Status if this media is safe from quarantining.</li>
  14519. <li><code>upload_name</code> - string or null - The name the media was uploaded with. Null if not provided during upload.</li>
  14520. </ul>
  14521. </li>
  14522. <li><code>next_token</code>: integer - Indication for pagination. See above.</li>
  14523. <li><code>total</code> - integer - Total number of media.</li>
  14524. </ul>
  14525. <h3 id="delete-media-uploaded-by-a-user-1"><a class="header" href="#delete-media-uploaded-by-a-user-1">Delete media uploaded by a user</a></h3>
  14526. <p>This API deletes the <em>local</em> media from the disk of your own server
  14527. that a specific <code>user_id</code> has created. This includes any local thumbnails.</p>
  14528. <p>This API will not affect media that has been uploaded to external
  14529. media repositories (e.g https://github.com/turt2live/matrix-media-repo/).</p>
  14530. <p>By default, the API deletes media ordered by descending creation date and ascending media ID.
  14531. The newest media is deleted first. You can change the order with parameters
  14532. <code>order_by</code> and <code>dir</code>. If no <code>limit</code> is set the API deletes <code>100</code> files per request.</p>
  14533. <p>The API is:</p>
  14534. <pre><code>DELETE /_synapse/admin/v1/users/&lt;user_id&gt;/media
  14535. </code></pre>
  14536. <p>A response body like the following is returned:</p>
  14537. <pre><code class="language-json">{
  14538. &quot;deleted_media&quot;: [
  14539. &quot;abcdefghijklmnopqrstuvwx&quot;
  14540. ],
  14541. &quot;total&quot;: 1
  14542. }
  14543. </code></pre>
  14544. <p>The following fields are returned in the JSON response body:</p>
  14545. <ul>
  14546. <li><code>deleted_media</code>: an array of strings - List of deleted <code>media_id</code></li>
  14547. <li><code>total</code>: integer - Total number of deleted <code>media_id</code></li>
  14548. </ul>
  14549. <p><strong>Note</strong>: There is no <code>next_token</code>. This is not useful for deleting media, because
  14550. after deleting media the remaining media have a new order.</p>
  14551. <p><strong>Parameters</strong></p>
  14552. <p>This API has the same parameters as
  14553. <a href="admin_api/user_admin_api.html#list-media-uploaded-by-a-user">List media uploaded by a user</a>.
  14554. With the parameters you can for example limit the number of files to delete at once or
  14555. delete largest/smallest or newest/oldest files first.</p>
  14556. <h2 id="login-as-a-user"><a class="header" href="#login-as-a-user">Login as a user</a></h2>
  14557. <p><strong>Note:</strong> This API is disabled when MSC3861 is enabled. <a href="https://github.com/matrix-org/synapse/pull/15582">See #15582</a></p>
  14558. <p>Get an access token that can be used to authenticate as that user. Useful for
  14559. when admins wish to do actions on behalf of a user.</p>
  14560. <p>The API is:</p>
  14561. <pre><code>POST /_synapse/admin/v1/users/&lt;user_id&gt;/login
  14562. {}
  14563. </code></pre>
  14564. <p>An optional <code>valid_until_ms</code> field can be specified in the request body as an
  14565. integer timestamp that specifies when the token should expire. By default tokens
  14566. do not expire. Note that this API does not allow a user to login as themselves
  14567. (to create more tokens).</p>
  14568. <p>A response body like the following is returned:</p>
  14569. <pre><code class="language-json">{
  14570. &quot;access_token&quot;: &quot;&lt;opaque_access_token_string&gt;&quot;
  14571. }
  14572. </code></pre>
  14573. <p>This API does <em>not</em> generate a new device for the user, and so will not appear
  14574. their <code>/devices</code> list, and in general the target user should not be able to
  14575. tell they have been logged in as.</p>
  14576. <p>To expire the token call the standard <code>/logout</code> API with the token.</p>
  14577. <p>Note: The token will expire if the <em>admin</em> user calls <code>/logout/all</code> from any
  14578. of their devices, but the token will <em>not</em> expire if the target user does the
  14579. same.</p>
  14580. <h2 id="allow-replacing-master-cross-signing-key-without-user-interactive-auth"><a class="header" href="#allow-replacing-master-cross-signing-key-without-user-interactive-auth">Allow replacing master cross-signing key without User-Interactive Auth</a></h2>
  14581. <p>This endpoint is not intended for server administrator usage;
  14582. we describe it here for completeness.</p>
  14583. <p>This API temporarily permits a user to replace their master cross-signing key
  14584. without going through
  14585. <a href="https://spec.matrix.org/v1.8/client-server-api/#user-interactive-authentication-api">user-interactive authentication</a> (UIA).
  14586. This is useful when Synapse has delegated its authentication to the
  14587. <a href="https://github.com/matrix-org/matrix-authentication-service/">Matrix Authentication Service</a>;
  14588. as Synapse cannot perform UIA is not possible in these circumstances.</p>
  14589. <p>The API is</p>
  14590. <pre><code class="language-http request">POST /_synapse/admin/v1/users/&lt;user_id&gt;/_allow_cross_signing_replacement_without_uia
  14591. {}
  14592. </code></pre>
  14593. <p>If the user does not exist, or does exist but has no master cross-signing key,
  14594. this will return with status code <code>404 Not Found</code>.</p>
  14595. <p>Otherwise, a response body like the following is returned, with status <code>200 OK</code>:</p>
  14596. <pre><code class="language-json">{
  14597. &quot;updatable_without_uia_before_ms&quot;: 1234567890
  14598. }
  14599. </code></pre>
  14600. <p>The response body is a JSON object with a single field:</p>
  14601. <ul>
  14602. <li><code>updatable_without_uia_before_ms</code>: integer. The timestamp in milliseconds
  14603. before which the user is permitted to replace their cross-signing key without
  14604. going through UIA.</li>
  14605. </ul>
  14606. <p><em>Added in Synapse 1.97.0.</em></p>
  14607. <h2 id="user-devices"><a class="header" href="#user-devices">User devices</a></h2>
  14608. <h3 id="list-all-devices"><a class="header" href="#list-all-devices">List all devices</a></h3>
  14609. <p>Gets information about all devices for a specific <code>user_id</code>.</p>
  14610. <p>The API is:</p>
  14611. <pre><code>GET /_synapse/admin/v2/users/&lt;user_id&gt;/devices
  14612. </code></pre>
  14613. <p>A response body like the following is returned:</p>
  14614. <pre><code class="language-json">{
  14615. &quot;devices&quot;: [
  14616. {
  14617. &quot;device_id&quot;: &quot;QBUAZIFURK&quot;,
  14618. &quot;display_name&quot;: &quot;android&quot;,
  14619. &quot;last_seen_ip&quot;: &quot;1.2.3.4&quot;,
  14620. &quot;last_seen_user_agent&quot;: &quot;Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0&quot;,
  14621. &quot;last_seen_ts&quot;: 1474491775024,
  14622. &quot;user_id&quot;: &quot;&lt;user_id&gt;&quot;
  14623. },
  14624. {
  14625. &quot;device_id&quot;: &quot;AUIECTSRND&quot;,
  14626. &quot;display_name&quot;: &quot;ios&quot;,
  14627. &quot;last_seen_ip&quot;: &quot;1.2.3.5&quot;,
  14628. &quot;last_seen_user_agent&quot;: &quot;Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0&quot;,
  14629. &quot;last_seen_ts&quot;: 1474491775025,
  14630. &quot;user_id&quot;: &quot;&lt;user_id&gt;&quot;
  14631. }
  14632. ],
  14633. &quot;total&quot;: 2
  14634. }
  14635. </code></pre>
  14636. <p><strong>Parameters</strong></p>
  14637. <p>The following parameters should be set in the URL:</p>
  14638. <ul>
  14639. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14640. </ul>
  14641. <p><strong>Response</strong></p>
  14642. <p>The following fields are returned in the JSON response body:</p>
  14643. <ul>
  14644. <li>
  14645. <p><code>devices</code> - An array of objects, each containing information about a device.
  14646. Device objects contain the following fields:</p>
  14647. <ul>
  14648. <li><code>device_id</code> - Identifier of device.</li>
  14649. <li><code>display_name</code> - Display name set by the user for this device.
  14650. Absent if no name has been set.</li>
  14651. <li><code>last_seen_ip</code> - The IP address where this device was last seen.
  14652. (May be a few minutes out of date, for efficiency reasons).</li>
  14653. <li><code>last_seen_user_agent</code> - The user agent of the device when it was last seen.
  14654. (May be a few minutes out of date, for efficiency reasons).</li>
  14655. <li><code>last_seen_ts</code> - The timestamp (in milliseconds since the unix epoch) when this
  14656. devices was last seen. (May be a few minutes out of date, for efficiency reasons).</li>
  14657. <li><code>user_id</code> - Owner of device.</li>
  14658. </ul>
  14659. </li>
  14660. <li>
  14661. <p><code>total</code> - Total number of user's devices.</p>
  14662. </li>
  14663. </ul>
  14664. <h3 id="create-a-device"><a class="header" href="#create-a-device">Create a device</a></h3>
  14665. <p>Creates a new device for a specific <code>user_id</code> and <code>device_id</code>. Does nothing if the <code>device_id</code>
  14666. exists already.</p>
  14667. <p>The API is:</p>
  14668. <pre><code>POST /_synapse/admin/v2/users/&lt;user_id&gt;/devices
  14669. {
  14670. &quot;device_id&quot;: &quot;QBUAZIFURK&quot;
  14671. }
  14672. </code></pre>
  14673. <p>An empty JSON dict is returned.</p>
  14674. <p><strong>Parameters</strong></p>
  14675. <p>The following parameters should be set in the URL:</p>
  14676. <ul>
  14677. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14678. </ul>
  14679. <p>The following fields are required in the JSON request body:</p>
  14680. <ul>
  14681. <li><code>device_id</code> - The device ID to create.</li>
  14682. </ul>
  14683. <h3 id="delete-multiple-devices"><a class="header" href="#delete-multiple-devices">Delete multiple devices</a></h3>
  14684. <p>Deletes the given devices for a specific <code>user_id</code>, and invalidates
  14685. any access token associated with them.</p>
  14686. <p>The API is:</p>
  14687. <pre><code>POST /_synapse/admin/v2/users/&lt;user_id&gt;/delete_devices
  14688. {
  14689. &quot;devices&quot;: [
  14690. &quot;QBUAZIFURK&quot;,
  14691. &quot;AUIECTSRND&quot;
  14692. ]
  14693. }
  14694. </code></pre>
  14695. <p>An empty JSON dict is returned.</p>
  14696. <p><strong>Parameters</strong></p>
  14697. <p>The following parameters should be set in the URL:</p>
  14698. <ul>
  14699. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14700. </ul>
  14701. <p>The following fields are required in the JSON request body:</p>
  14702. <ul>
  14703. <li><code>devices</code> - The list of device IDs to delete.</li>
  14704. </ul>
  14705. <h3 id="show-a-device"><a class="header" href="#show-a-device">Show a device</a></h3>
  14706. <p>Gets information on a single device, by <code>device_id</code> for a specific <code>user_id</code>.</p>
  14707. <p>The API is:</p>
  14708. <pre><code>GET /_synapse/admin/v2/users/&lt;user_id&gt;/devices/&lt;device_id&gt;
  14709. </code></pre>
  14710. <p>A response body like the following is returned:</p>
  14711. <pre><code class="language-json">{
  14712. &quot;device_id&quot;: &quot;&lt;device_id&gt;&quot;,
  14713. &quot;display_name&quot;: &quot;android&quot;,
  14714. &quot;last_seen_ip&quot;: &quot;1.2.3.4&quot;,
  14715. &quot;last_seen_user_agent&quot;: &quot;Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0&quot;,
  14716. &quot;last_seen_ts&quot;: 1474491775024,
  14717. &quot;user_id&quot;: &quot;&lt;user_id&gt;&quot;
  14718. }
  14719. </code></pre>
  14720. <p><strong>Parameters</strong></p>
  14721. <p>The following parameters should be set in the URL:</p>
  14722. <ul>
  14723. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14724. <li><code>device_id</code> - The device to retrieve.</li>
  14725. </ul>
  14726. <p><strong>Response</strong></p>
  14727. <p>The following fields are returned in the JSON response body:</p>
  14728. <ul>
  14729. <li><code>device_id</code> - Identifier of device.</li>
  14730. <li><code>display_name</code> - Display name set by the user for this device.
  14731. Absent if no name has been set.</li>
  14732. <li><code>last_seen_ip</code> - The IP address where this device was last seen.
  14733. (May be a few minutes out of date, for efficiency reasons).
  14734. <ul>
  14735. <li><code>last_seen_user_agent</code> - The user agent of the device when it was last seen.
  14736. (May be a few minutes out of date, for efficiency reasons).</li>
  14737. </ul>
  14738. </li>
  14739. <li><code>last_seen_ts</code> - The timestamp (in milliseconds since the unix epoch) when this
  14740. devices was last seen. (May be a few minutes out of date, for efficiency reasons).</li>
  14741. <li><code>user_id</code> - Owner of device.</li>
  14742. </ul>
  14743. <h3 id="update-a-device"><a class="header" href="#update-a-device">Update a device</a></h3>
  14744. <p>Updates the metadata on the given <code>device_id</code> for a specific <code>user_id</code>.</p>
  14745. <p>The API is:</p>
  14746. <pre><code>PUT /_synapse/admin/v2/users/&lt;user_id&gt;/devices/&lt;device_id&gt;
  14747. {
  14748. &quot;display_name&quot;: &quot;My other phone&quot;
  14749. }
  14750. </code></pre>
  14751. <p>An empty JSON dict is returned.</p>
  14752. <p><strong>Parameters</strong></p>
  14753. <p>The following parameters should be set in the URL:</p>
  14754. <ul>
  14755. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14756. <li><code>device_id</code> - The device to update.</li>
  14757. </ul>
  14758. <p>The following fields are required in the JSON request body:</p>
  14759. <ul>
  14760. <li><code>display_name</code> - The new display name for this device. If not given,
  14761. the display name is unchanged.</li>
  14762. </ul>
  14763. <h3 id="delete-a-device"><a class="header" href="#delete-a-device">Delete a device</a></h3>
  14764. <p>Deletes the given <code>device_id</code> for a specific <code>user_id</code>,
  14765. and invalidates any access token associated with it.</p>
  14766. <p>The API is:</p>
  14767. <pre><code>DELETE /_synapse/admin/v2/users/&lt;user_id&gt;/devices/&lt;device_id&gt;
  14768. {}
  14769. </code></pre>
  14770. <p>An empty JSON dict is returned.</p>
  14771. <p><strong>Parameters</strong></p>
  14772. <p>The following parameters should be set in the URL:</p>
  14773. <ul>
  14774. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14775. <li><code>device_id</code> - The device to delete.</li>
  14776. </ul>
  14777. <h2 id="list-all-pushers"><a class="header" href="#list-all-pushers">List all pushers</a></h2>
  14778. <p>Gets information about all pushers for a specific <code>user_id</code>.</p>
  14779. <p>The API is:</p>
  14780. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/pushers
  14781. </code></pre>
  14782. <p>A response body like the following is returned:</p>
  14783. <pre><code class="language-json">{
  14784. &quot;pushers&quot;: [
  14785. {
  14786. &quot;app_display_name&quot;:&quot;HTTP Push Notifications&quot;,
  14787. &quot;app_id&quot;:&quot;m.http&quot;,
  14788. &quot;data&quot;: {
  14789. &quot;url&quot;:&quot;example.com&quot;
  14790. },
  14791. &quot;device_display_name&quot;:&quot;pushy push&quot;,
  14792. &quot;kind&quot;:&quot;http&quot;,
  14793. &quot;lang&quot;:&quot;None&quot;,
  14794. &quot;profile_tag&quot;:&quot;&quot;,
  14795. &quot;pushkey&quot;:&quot;a@example.com&quot;
  14796. }
  14797. ],
  14798. &quot;total&quot;: 1
  14799. }
  14800. </code></pre>
  14801. <p><strong>Parameters</strong></p>
  14802. <p>The following parameters should be set in the URL:</p>
  14803. <ul>
  14804. <li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
  14805. </ul>
  14806. <p><strong>Response</strong></p>
  14807. <p>The following fields are returned in the JSON response body:</p>
  14808. <ul>
  14809. <li>
  14810. <p><code>pushers</code> - An array containing the current pushers for the user</p>
  14811. <ul>
  14812. <li>
  14813. <p><code>app_display_name</code> - string - A string that will allow the user to identify
  14814. what application owns this pusher.</p>
  14815. </li>
  14816. <li>
  14817. <p><code>app_id</code> - string - This is a reverse-DNS style identifier for the application.
  14818. Max length, 64 chars.</p>
  14819. </li>
  14820. <li>
  14821. <p><code>data</code> - A dictionary of information for the pusher implementation itself.</p>
  14822. <ul>
  14823. <li>
  14824. <p><code>url</code> - string - Required if <code>kind</code> is <code>http</code>. The URL to use to send
  14825. notifications to.</p>
  14826. </li>
  14827. <li>
  14828. <p><code>format</code> - string - The format to use when sending notifications to the
  14829. Push Gateway.</p>
  14830. </li>
  14831. </ul>
  14832. </li>
  14833. <li>
  14834. <p><code>device_display_name</code> - string - A string that will allow the user to identify
  14835. what device owns this pusher.</p>
  14836. </li>
  14837. <li>
  14838. <p><code>profile_tag</code> - string - This string determines which set of device specific rules
  14839. this pusher executes.</p>
  14840. </li>
  14841. <li>
  14842. <p><code>kind</code> - string - The kind of pusher. &quot;http&quot; is a pusher that sends HTTP pokes.</p>
  14843. </li>
  14844. <li>
  14845. <p><code>lang</code> - string - The preferred language for receiving notifications
  14846. (e.g. 'en' or 'en-US')</p>
  14847. </li>
  14848. <li>
  14849. <p><code>profile_tag</code> - string - This string determines which set of device specific rules
  14850. this pusher executes.</p>
  14851. </li>
  14852. <li>
  14853. <p><code>pushkey</code> - string - This is a unique identifier for this pusher.
  14854. Max length, 512 bytes.</p>
  14855. </li>
  14856. </ul>
  14857. </li>
  14858. <li>
  14859. <p><code>total</code> - integer - Number of pushers.</p>
  14860. </li>
  14861. </ul>
  14862. <p>See also the
  14863. <a href="https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushers">Client-Server API Spec on pushers</a>.</p>
  14864. <h2 id="controlling-whether-a-user-is-shadow-banned"><a class="header" href="#controlling-whether-a-user-is-shadow-banned">Controlling whether a user is shadow-banned</a></h2>
  14865. <p>Shadow-banning is a useful tool for moderating malicious or egregiously abusive users.
  14866. A shadow-banned users receives successful responses to their client-server API requests,
  14867. but the events are not propagated into rooms. This can be an effective tool as it
  14868. (hopefully) takes longer for the user to realise they are being moderated before
  14869. pivoting to another account.</p>
  14870. <p>Shadow-banning a user should be used as a tool of last resort and may lead to confusing
  14871. or broken behaviour for the client. A shadow-banned user will not receive any
  14872. notification and it is generally more appropriate to ban or kick abusive users.
  14873. A shadow-banned user will be unable to contact anyone on the server.</p>
  14874. <p>To shadow-ban a user the API is:</p>
  14875. <pre><code>POST /_synapse/admin/v1/users/&lt;user_id&gt;/shadow_ban
  14876. </code></pre>
  14877. <p>To un-shadow-ban a user the API is:</p>
  14878. <pre><code>DELETE /_synapse/admin/v1/users/&lt;user_id&gt;/shadow_ban
  14879. </code></pre>
  14880. <p>An empty JSON dict is returned in both cases.</p>
  14881. <p><strong>Parameters</strong></p>
  14882. <p>The following parameters should be set in the URL:</p>
  14883. <ul>
  14884. <li><code>user_id</code> - The fully qualified MXID: for example, <code>@user:server.com</code>. The user must
  14885. be local.</li>
  14886. </ul>
  14887. <h2 id="override-ratelimiting-for-users"><a class="header" href="#override-ratelimiting-for-users">Override ratelimiting for users</a></h2>
  14888. <p>This API allows to override or disable ratelimiting for a specific user.
  14889. There are specific APIs to set, get and delete a ratelimit.</p>
  14890. <h3 id="get-status-of-ratelimit"><a class="header" href="#get-status-of-ratelimit">Get status of ratelimit</a></h3>
  14891. <p>The API is:</p>
  14892. <pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/override_ratelimit
  14893. </code></pre>
  14894. <p>A response body like the following is returned:</p>
  14895. <pre><code class="language-json">{
  14896. &quot;messages_per_second&quot;: 0,
  14897. &quot;burst_count&quot;: 0
  14898. }
  14899. </code></pre>
  14900. <p><strong>Parameters</strong></p>
  14901. <p>The following parameters should be set in the URL:</p>
  14902. <ul>
  14903. <li><code>user_id</code> - The fully qualified MXID: for example, <code>@user:server.com</code>. The user must
  14904. be local.</li>
  14905. </ul>
  14906. <p><strong>Response</strong></p>
  14907. <p>The following fields are returned in the JSON response body:</p>
  14908. <ul>
  14909. <li><code>messages_per_second</code> - integer - The number of actions that can
  14910. be performed in a second. <code>0</code> mean that ratelimiting is disabled for this user.</li>
  14911. <li><code>burst_count</code> - integer - How many actions that can be performed before
  14912. being limited.</li>
  14913. </ul>
  14914. <p>If <strong>no</strong> custom ratelimit is set, an empty JSON dict is returned.</p>
  14915. <pre><code class="language-json">{}
  14916. </code></pre>
  14917. <h3 id="set-ratelimit"><a class="header" href="#set-ratelimit">Set ratelimit</a></h3>
  14918. <p>The API is:</p>
  14919. <pre><code>POST /_synapse/admin/v1/users/&lt;user_id&gt;/override_ratelimit
  14920. </code></pre>
  14921. <p>A response body like the following is returned:</p>
  14922. <pre><code class="language-json">{
  14923. &quot;messages_per_second&quot;: 0,
  14924. &quot;burst_count&quot;: 0
  14925. }
  14926. </code></pre>
  14927. <p><strong>Parameters</strong></p>
  14928. <p>The following parameters should be set in the URL:</p>
  14929. <ul>
  14930. <li><code>user_id</code> - The fully qualified MXID: for example, <code>@user:server.com</code>. The user must
  14931. be local.</li>
  14932. </ul>
  14933. <p>Body parameters:</p>
  14934. <ul>
  14935. <li><code>messages_per_second</code> - positive integer, optional. The number of actions that can
  14936. be performed in a second. Defaults to <code>0</code>.</li>
  14937. <li><code>burst_count</code> - positive integer, optional. How many actions that can be performed
  14938. before being limited. Defaults to <code>0</code>.</li>
  14939. </ul>
  14940. <p>To disable users' ratelimit set both values to <code>0</code>.</p>
  14941. <p><strong>Response</strong></p>
  14942. <p>The following fields are returned in the JSON response body:</p>
  14943. <ul>
  14944. <li><code>messages_per_second</code> - integer - The number of actions that can
  14945. be performed in a second.</li>
  14946. <li><code>burst_count</code> - integer - How many actions that can be performed before
  14947. being limited.</li>
  14948. </ul>
  14949. <h3 id="delete-ratelimit"><a class="header" href="#delete-ratelimit">Delete ratelimit</a></h3>
  14950. <p>The API is:</p>
  14951. <pre><code>DELETE /_synapse/admin/v1/users/&lt;user_id&gt;/override_ratelimit
  14952. </code></pre>
  14953. <p>An empty JSON dict is returned.</p>
  14954. <pre><code class="language-json">{}
  14955. </code></pre>
  14956. <p><strong>Parameters</strong></p>
  14957. <p>The following parameters should be set in the URL:</p>
  14958. <ul>
  14959. <li><code>user_id</code> - The fully qualified MXID: for example, <code>@user:server.com</code>. The user must
  14960. be local.</li>
  14961. </ul>
  14962. <h2 id="check-username-availability"><a class="header" href="#check-username-availability">Check username availability</a></h2>
  14963. <p>Checks to see if a username is available, and valid, for the server. See <a href="https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available">the client-server
  14964. API</a>
  14965. for more information.</p>
  14966. <p>This endpoint will work even if registration is disabled on the server, unlike
  14967. <code>/_matrix/client/r0/register/available</code>.</p>
  14968. <p>The API is:</p>
  14969. <pre><code>GET /_synapse/admin/v1/username_available?username=$localpart
  14970. </code></pre>
  14971. <p>The request and response format is the same as the
  14972. <a href="https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available">/_matrix/client/r0/register/available</a> API.</p>
  14973. <h2 id="find-a-user-based-on-their-id-in-an-auth-provider"><a class="header" href="#find-a-user-based-on-their-id-in-an-auth-provider">Find a user based on their ID in an auth provider</a></h2>
  14974. <p>The API is:</p>
  14975. <pre><code>GET /_synapse/admin/v1/auth_providers/$provider/users/$external_id
  14976. </code></pre>
  14977. <p>When a user matched the given ID for the given provider, an HTTP code <code>200</code> with a response body like the following is returned:</p>
  14978. <pre><code class="language-json">{
  14979. &quot;user_id&quot;: &quot;@hello:example.org&quot;
  14980. }
  14981. </code></pre>
  14982. <p><strong>Parameters</strong></p>
  14983. <p>The following parameters should be set in the URL:</p>
  14984. <ul>
  14985. <li><code>provider</code> - The ID of the authentication provider, as advertised by the <a href="https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3login"><code>GET /_matrix/client/v3/login</code></a> API in the <code>m.login.sso</code> authentication method.</li>
  14986. <li><code>external_id</code> - The user ID from the authentication provider. Usually corresponds to the <code>sub</code> claim for OIDC providers, or to the <code>uid</code> attestation for SAML2 providers.</li>
  14987. </ul>
  14988. <p>The <code>external_id</code> may have characters that are not URL-safe (typically <code>/</code>, <code>:</code> or <code>@</code>), so it is advised to URL-encode those parameters.</p>
  14989. <p><strong>Errors</strong></p>
  14990. <p>Returns a <code>404</code> HTTP status code if no user was found, with a response body like this:</p>
  14991. <pre><code class="language-json">{
  14992. &quot;errcode&quot;:&quot;M_NOT_FOUND&quot;,
  14993. &quot;error&quot;:&quot;User not found&quot;
  14994. }
  14995. </code></pre>
  14996. <p><em>Added in Synapse 1.68.0.</em></p>
  14997. <h2 id="find-a-user-based-on-their-third-party-id-threepid-or-3pid"><a class="header" href="#find-a-user-based-on-their-third-party-id-threepid-or-3pid">Find a user based on their Third Party ID (ThreePID or 3PID)</a></h2>
  14998. <p>The API is:</p>
  14999. <pre><code>GET /_synapse/admin/v1/threepid/$medium/users/$address
  15000. </code></pre>
  15001. <p>When a user matched the given address for the given medium, an HTTP code <code>200</code> with a response body like the following is returned:</p>
  15002. <pre><code class="language-json">{
  15003. &quot;user_id&quot;: &quot;@hello:example.org&quot;
  15004. }
  15005. </code></pre>
  15006. <p><strong>Parameters</strong></p>
  15007. <p>The following parameters should be set in the URL:</p>
  15008. <ul>
  15009. <li><code>medium</code> - Kind of third-party ID, either <code>email</code> or <code>msisdn</code>.</li>
  15010. <li><code>address</code> - Value of the third-party ID.</li>
  15011. </ul>
  15012. <p>The <code>address</code> may have characters that are not URL-safe, so it is advised to URL-encode those parameters.</p>
  15013. <p><strong>Errors</strong></p>
  15014. <p>Returns a <code>404</code> HTTP status code if no user was found, with a response body like this:</p>
  15015. <pre><code class="language-json">{
  15016. &quot;errcode&quot;:&quot;M_NOT_FOUND&quot;,
  15017. &quot;error&quot;:&quot;User not found&quot;
  15018. }
  15019. </code></pre>
  15020. <p><em>Added in Synapse 1.72.0.</em></p>
  15021. <div style="break-before: page; page-break-before: always;"></div><h1 id="version-api"><a class="header" href="#version-api">Version API</a></h1>
  15022. <p>This API returns the running Synapse version.
  15023. This is useful when a Synapse instance
  15024. is behind a proxy that does not forward the 'Server' header (which also
  15025. contains Synapse version information).</p>
  15026. <p>The api is:</p>
  15027. <pre><code>GET /_synapse/admin/v1/server_version
  15028. </code></pre>
  15029. <p>It returns a JSON body like the following:</p>
  15030. <pre><code class="language-json">{
  15031. &quot;server_version&quot;: &quot;0.99.2rc1 (b=develop, abcdef123)&quot;
  15032. }
  15033. </code></pre>
  15034. <p><em>Changed in Synapse 1.94.0:</em> The <code>python_version</code> key was removed from the
  15035. response body.</p>
  15036. <div style="break-before: page; page-break-before: always;"></div><h1 id="federation-api"><a class="header" href="#federation-api">Federation API</a></h1>
  15037. <p>This API allows a server administrator to manage Synapse's federation with other homeservers.</p>
  15038. <p>Note: This API is new, experimental and &quot;subject to change&quot;.</p>
  15039. <h2 id="list-of-destinations"><a class="header" href="#list-of-destinations">List of destinations</a></h2>
  15040. <p>This API gets the current destination retry timing info for all remote servers.</p>
  15041. <p>The list contains all the servers with which the server federates,
  15042. regardless of whether an error occurred or not.
  15043. If an error occurs, it may take up to 20 minutes for the error to be displayed here,
  15044. as a complete retry must have failed.</p>
  15045. <p>The API is:</p>
  15046. <p>A standard request with no filtering:</p>
  15047. <pre><code>GET /_synapse/admin/v1/federation/destinations
  15048. </code></pre>
  15049. <p>A response body like the following is returned:</p>
  15050. <pre><code class="language-json">{
  15051. &quot;destinations&quot;:[
  15052. {
  15053. &quot;destination&quot;: &quot;matrix.org&quot;,
  15054. &quot;retry_last_ts&quot;: 1557332397936,
  15055. &quot;retry_interval&quot;: 3000000,
  15056. &quot;failure_ts&quot;: 1557329397936,
  15057. &quot;last_successful_stream_ordering&quot;: null
  15058. }
  15059. ],
  15060. &quot;total&quot;: 1
  15061. }
  15062. </code></pre>
  15063. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint again
  15064. with <code>from</code> set to the value of <code>next_token</code>. This will return a new page.</p>
  15065. <p>If the endpoint does not return a <code>next_token</code> then there are no more destinations
  15066. to paginate through.</p>
  15067. <p><strong>Parameters</strong></p>
  15068. <p>The following query parameters are available:</p>
  15069. <ul>
  15070. <li><code>from</code> - Offset in the returned list. Defaults to <code>0</code>.</li>
  15071. <li><code>limit</code> - Maximum amount of destinations to return. Defaults to <code>100</code>.</li>
  15072. <li><code>order_by</code> - The method in which to sort the returned list of destinations.
  15073. Valid values are:
  15074. <ul>
  15075. <li><code>destination</code> - Destinations are ordered alphabetically by remote server name.
  15076. This is the default.</li>
  15077. <li><code>retry_last_ts</code> - Destinations are ordered by time of last retry attempt in ms.</li>
  15078. <li><code>retry_interval</code> - Destinations are ordered by how long until next retry in ms.</li>
  15079. <li><code>failure_ts</code> - Destinations are ordered by when the server started failing in ms.</li>
  15080. <li><code>last_successful_stream_ordering</code> - Destinations are ordered by the stream ordering
  15081. of the most recent successfully-sent PDU.</li>
  15082. </ul>
  15083. </li>
  15084. <li><code>dir</code> - Direction of room order. Either <code>f</code> for forwards or <code>b</code> for backwards. Setting
  15085. this value to <code>b</code> will reverse the above sort order. Defaults to <code>f</code>.</li>
  15086. </ul>
  15087. <p><em>Caution:</em> The database only has an index on the column <code>destination</code>.
  15088. This means that if a different sort order is used,
  15089. this can cause a large load on the database, especially for large environments.</p>
  15090. <p><strong>Response</strong></p>
  15091. <p>The following fields are returned in the JSON response body:</p>
  15092. <ul>
  15093. <li><code>destinations</code> - An array of objects, each containing information about a destination.
  15094. Destination objects contain the following fields:
  15095. <ul>
  15096. <li><code>destination</code> - string - Name of the remote server to federate.</li>
  15097. <li><code>retry_last_ts</code> - integer - The last time Synapse tried and failed to reach the
  15098. remote server, in ms. This is <code>0</code> if the last attempt to communicate with the
  15099. remote server was successful.</li>
  15100. <li><code>retry_interval</code> - integer - How long since the last time Synapse tried to reach
  15101. the remote server before trying again, in ms. This is <code>0</code> if no further retrying occurring.</li>
  15102. <li><code>failure_ts</code> - nullable integer - The first time Synapse tried and failed to reach the
  15103. remote server, in ms. This is <code>null</code> if communication with the remote server has never failed.</li>
  15104. <li><code>last_successful_stream_ordering</code> - nullable integer - The stream ordering of the most
  15105. recent successfully-sent <a href="usage/administration/admin_api/../understanding_synapse_through_grafana_graphs.html#federation">PDU</a>
  15106. to this destination, or <code>null</code> if this information has not been tracked yet.</li>
  15107. </ul>
  15108. </li>
  15109. <li><code>next_token</code>: string representing a positive integer - Indication for pagination. See above.</li>
  15110. <li><code>total</code> - integer - Total number of destinations.</li>
  15111. </ul>
  15112. <h2 id="destination-details-api"><a class="header" href="#destination-details-api">Destination Details API</a></h2>
  15113. <p>This API gets the retry timing info for a specific remote server.</p>
  15114. <p>The API is:</p>
  15115. <pre><code>GET /_synapse/admin/v1/federation/destinations/&lt;destination&gt;
  15116. </code></pre>
  15117. <p>A response body like the following is returned:</p>
  15118. <pre><code class="language-json">{
  15119. &quot;destination&quot;: &quot;matrix.org&quot;,
  15120. &quot;retry_last_ts&quot;: 1557332397936,
  15121. &quot;retry_interval&quot;: 3000000,
  15122. &quot;failure_ts&quot;: 1557329397936,
  15123. &quot;last_successful_stream_ordering&quot;: null
  15124. }
  15125. </code></pre>
  15126. <p><strong>Parameters</strong></p>
  15127. <p>The following parameters should be set in the URL:</p>
  15128. <ul>
  15129. <li><code>destination</code> - Name of the remote server.</li>
  15130. </ul>
  15131. <p><strong>Response</strong></p>
  15132. <p>The response fields are the same like in the <code>destinations</code> array in
  15133. <a href="usage/administration/admin_api/federation.html#list-of-destinations">List of destinations</a> response.</p>
  15134. <h2 id="destination-rooms"><a class="header" href="#destination-rooms">Destination rooms</a></h2>
  15135. <p>This API gets the rooms that federate with a specific remote server.</p>
  15136. <p>The API is:</p>
  15137. <pre><code>GET /_synapse/admin/v1/federation/destinations/&lt;destination&gt;/rooms
  15138. </code></pre>
  15139. <p>A response body like the following is returned:</p>
  15140. <pre><code class="language-json">{
  15141. &quot;rooms&quot;:[
  15142. {
  15143. &quot;room_id&quot;: &quot;!OGEhHVWSdvArJzumhm:matrix.org&quot;,
  15144. &quot;stream_ordering&quot;: 8326
  15145. },
  15146. {
  15147. &quot;room_id&quot;: &quot;!xYvNcQPhnkrdUmYczI:matrix.org&quot;,
  15148. &quot;stream_ordering&quot;: 93534
  15149. }
  15150. ],
  15151. &quot;total&quot;: 2
  15152. }
  15153. </code></pre>
  15154. <p>To paginate, check for <code>next_token</code> and if present, call the endpoint again
  15155. with <code>from</code> set to the value of <code>next_token</code>. This will return a new page.</p>
  15156. <p>If the endpoint does not return a <code>next_token</code> then there are no more destinations
  15157. to paginate through.</p>
  15158. <p><strong>Parameters</strong></p>
  15159. <p>The following parameters should be set in the URL:</p>
  15160. <ul>
  15161. <li><code>destination</code> - Name of the remote server.</li>
  15162. </ul>
  15163. <p>The following query parameters are available:</p>
  15164. <ul>
  15165. <li><code>from</code> - Offset in the returned list. Defaults to <code>0</code>.</li>
  15166. <li><code>limit</code> - Maximum amount of destinations to return. Defaults to <code>100</code>.</li>
  15167. <li><code>dir</code> - Direction of room order by <code>room_id</code>. Either <code>f</code> for forwards or <code>b</code> for
  15168. backwards. Defaults to <code>f</code>.</li>
  15169. </ul>
  15170. <p><strong>Response</strong></p>
  15171. <p>The following fields are returned in the JSON response body:</p>
  15172. <ul>
  15173. <li><code>rooms</code> - An array of objects, each containing information about a room.
  15174. Room objects contain the following fields:
  15175. <ul>
  15176. <li><code>room_id</code> - string - The ID of the room.</li>
  15177. <li><code>stream_ordering</code> - integer - The stream ordering of the most recent
  15178. successfully-sent <a href="usage/administration/admin_api/../understanding_synapse_through_grafana_graphs.html#federation">PDU</a>
  15179. to this destination in this room.</li>
  15180. </ul>
  15181. </li>
  15182. <li><code>next_token</code>: string representing a positive integer - Indication for pagination. See above.</li>
  15183. <li><code>total</code> - integer - Total number of destinations.</li>
  15184. </ul>
  15185. <h2 id="reset-connection-timeout"><a class="header" href="#reset-connection-timeout">Reset connection timeout</a></h2>
  15186. <p>Synapse makes federation requests to other homeservers. If a federation request fails,
  15187. Synapse will mark the destination homeserver as offline, preventing any future requests
  15188. to that server for a &quot;cooldown&quot; period. This period grows over time if the server
  15189. continues to fail its responses
  15190. (<a href="https://en.wikipedia.org/wiki/Exponential_backoff">exponential backoff</a>).</p>
  15191. <p>Admins can cancel the cooldown period with this API.</p>
  15192. <p>This API resets the retry timing for a specific remote server and tries to connect to
  15193. the remote server again. It does not wait for the next <code>retry_interval</code>.
  15194. The connection must have previously run into an error and <code>retry_last_ts</code>
  15195. (<a href="usage/administration/admin_api/federation.html#destination-details-api">Destination Details API</a>) must not be equal to <code>0</code>.</p>
  15196. <p>The connection attempt is carried out in the background and can take a while
  15197. even if the API already returns the http status 200.</p>
  15198. <p>The API is:</p>
  15199. <pre><code>POST /_synapse/admin/v1/federation/destinations/&lt;destination&gt;/reset_connection
  15200. {}
  15201. </code></pre>
  15202. <p><strong>Parameters</strong></p>
  15203. <p>The following parameters should be set in the URL:</p>
  15204. <ul>
  15205. <li><code>destination</code> - Name of the remote server.</li>
  15206. </ul>
  15207. <div style="break-before: page; page-break-before: always;"></div><h1 id="using-the-synapse-manhole"><a class="header" href="#using-the-synapse-manhole">Using the synapse manhole</a></h1>
  15208. <p>The &quot;manhole&quot; allows server administrators to access a Python shell on a running
  15209. Synapse installation. This is a very powerful mechanism for administration and
  15210. debugging.</p>
  15211. <p><strong><em>Security Warning</em></strong></p>
  15212. <p>Note that this will give administrative access to synapse to <strong>all users</strong> with
  15213. shell access to the server. It should therefore <strong>not</strong> be enabled in
  15214. environments where untrusted users have shell access.</p>
  15215. <h2 id="configuring-the-manhole"><a class="header" href="#configuring-the-manhole">Configuring the manhole</a></h2>
  15216. <p>To enable it, first add the <code>manhole</code> listener configuration in your
  15217. <code>homeserver.yaml</code>. You can find information on how to do that
  15218. in the <a href="usage/configuration/config_documentation.html#manhole_settings">configuration manual</a>.
  15219. The configuration is slightly different if you're using docker.</p>
  15220. <h4 id="docker-config"><a class="header" href="#docker-config">Docker config</a></h4>
  15221. <p>If you are using Docker, set <code>bind_addresses</code> to <code>['0.0.0.0']</code> as shown:</p>
  15222. <pre><code class="language-yaml">listeners:
  15223. - port: 9000
  15224. bind_addresses: ['0.0.0.0']
  15225. type: manhole
  15226. </code></pre>
  15227. <p>When using <code>docker run</code> to start the server, you will then need to change the command to the following to include the
  15228. <code>manhole</code> port forwarding. The <code>-p 127.0.0.1:9000:9000</code> below is important: it
  15229. ensures that access to the <code>manhole</code> is only possible for local users.</p>
  15230. <pre><code class="language-bash">docker run -d --name synapse \
  15231. --mount type=volume,src=synapse-data,dst=/data \
  15232. -p 8008:8008 \
  15233. -p 127.0.0.1:9000:9000 \
  15234. matrixdotorg/synapse:latest
  15235. </code></pre>
  15236. <h4 id="native-config"><a class="header" href="#native-config">Native config</a></h4>
  15237. <p>If you are not using docker, set <code>bind_addresses</code> to <code>['::1', '127.0.0.1']</code> as shown.
  15238. The <code>bind_addresses</code> in the example below is important: it ensures that access to the
  15239. <code>manhole</code> is only possible for local users).</p>
  15240. <pre><code class="language-yaml">listeners:
  15241. - port: 9000
  15242. bind_addresses: ['::1', '127.0.0.1']
  15243. type: manhole
  15244. </code></pre>
  15245. <h3 id="security-settings"><a class="header" href="#security-settings">Security settings</a></h3>
  15246. <p>The following config options are available:</p>
  15247. <ul>
  15248. <li><code>username</code> - The username for the manhole (defaults to <code>matrix</code>)</li>
  15249. <li><code>password</code> - The password for the manhole (defaults to <code>rabbithole</code>)</li>
  15250. <li><code>ssh_priv_key</code> - The path to a private SSH key (defaults to a hardcoded value)</li>
  15251. <li><code>ssh_pub_key</code> - The path to a public SSH key (defaults to a hardcoded value)</li>
  15252. </ul>
  15253. <p>For example:</p>
  15254. <pre><code class="language-yaml">manhole_settings:
  15255. username: manhole
  15256. password: mypassword
  15257. ssh_priv_key: &quot;/home/synapse/manhole_keys/id_rsa&quot;
  15258. ssh_pub_key: &quot;/home/synapse/manhole_keys/id_rsa.pub&quot;
  15259. </code></pre>
  15260. <h2 id="accessing-synapse-manhole"><a class="header" href="#accessing-synapse-manhole">Accessing synapse manhole</a></h2>
  15261. <p>Then restart synapse, and point an ssh client at port 9000 on localhost, using
  15262. the username and password configured in <code>homeserver.yaml</code> - with the default
  15263. configuration, this would be:</p>
  15264. <pre><code class="language-bash">ssh -p9000 matrix@localhost
  15265. </code></pre>
  15266. <p>Then enter the password when prompted (the default is <code>rabbithole</code>).</p>
  15267. <p>This gives a Python REPL in which <code>hs</code> gives access to the
  15268. <code>synapse.server.HomeServer</code> object - which in turn gives access to many other
  15269. parts of the process.</p>
  15270. <p>Note that, prior to Synapse 1.41, any call which returns a coroutine will need to be wrapped in <code>ensureDeferred</code>.</p>
  15271. <p>As a simple example, retrieving an event from the database:</p>
  15272. <pre><code class="language-pycon">&gt;&gt;&gt; from twisted.internet import defer
  15273. &gt;&gt;&gt; defer.ensureDeferred(hs.get_datastores().main.get_event('$1416420717069yeQaw:matrix.org'))
  15274. &lt;Deferred at 0x7ff253fc6998 current result: &lt;FrozenEvent event_id='$1416420717069yeQaw:matrix.org', type='m.room.create', state_key=''&gt;&gt;
  15275. </code></pre>
  15276. <div style="break-before: page; page-break-before: always;"></div><h1 id="how-to-monitor-synapse-metrics-using-prometheus"><a class="header" href="#how-to-monitor-synapse-metrics-using-prometheus">How to monitor Synapse metrics using Prometheus</a></h1>
  15277. <ol>
  15278. <li>
  15279. <p>Install Prometheus:</p>
  15280. <p>Follow instructions at
  15281. <a href="http://prometheus.io/docs/introduction/install/">http://prometheus.io/docs/introduction/install/</a></p>
  15282. </li>
  15283. <li>
  15284. <p>Enable Synapse metrics:</p>
  15285. <p>In <code>homeserver.yaml</code>, make sure <code>enable_metrics</code> is
  15286. set to <code>True</code>.</p>
  15287. </li>
  15288. <li>
  15289. <p>Enable the <code>/_synapse/metrics</code> Synapse endpoint that Prometheus uses to
  15290. collect data:</p>
  15291. <p>There are two methods of enabling the metrics endpoint in Synapse.</p>
  15292. <p>The first serves the metrics as a part of the usual web server and
  15293. can be enabled by adding the <code>metrics</code> resource to the existing
  15294. listener as such as in this example:</p>
  15295. <pre><code class="language-yaml">listeners:
  15296. - port: 8008
  15297. tls: false
  15298. type: http
  15299. x_forwarded: true
  15300. bind_addresses: ['::1', '127.0.0.1']
  15301. resources:
  15302. # added &quot;metrics&quot; in this line
  15303. - names: [client, federation, metrics]
  15304. compress: false
  15305. </code></pre>
  15306. <p>This provides a simple way of adding metrics to your Synapse
  15307. installation, and serves under <code>/_synapse/metrics</code>. If you do not
  15308. wish your metrics be publicly exposed, you will need to either
  15309. filter it out at your load balancer, or use the second method.</p>
  15310. <p>The second method runs the metrics server on a different port, in a
  15311. different thread to Synapse. This can make it more resilient to
  15312. heavy load meaning metrics cannot be retrieved, and can be exposed
  15313. to just internal networks easier. The served metrics are available
  15314. over HTTP only, and will be available at <code>/_synapse/metrics</code>.</p>
  15315. <p>Add a new listener to homeserver.yaml as in this example:</p>
  15316. <pre><code class="language-yaml">listeners:
  15317. - port: 8008
  15318. tls: false
  15319. type: http
  15320. x_forwarded: true
  15321. bind_addresses: ['::1', '127.0.0.1']
  15322. resources:
  15323. - names: [client, federation]
  15324. compress: false
  15325. # beginning of the new metrics listener
  15326. - port: 9000
  15327. type: metrics
  15328. bind_addresses: ['::1', '127.0.0.1']
  15329. </code></pre>
  15330. </li>
  15331. <li>
  15332. <p>Restart Synapse.</p>
  15333. </li>
  15334. <li>
  15335. <p>Add a Prometheus target for Synapse.</p>
  15336. <p>It needs to set the <code>metrics_path</code> to a non-default value (under
  15337. <code>scrape_configs</code>):</p>
  15338. <pre><code class="language-yaml"> - job_name: &quot;synapse&quot;
  15339. scrape_interval: 15s
  15340. metrics_path: &quot;/_synapse/metrics&quot;
  15341. static_configs:
  15342. - targets: [&quot;my.server.here:port&quot;]
  15343. </code></pre>
  15344. <p>where <code>my.server.here</code> is the IP address of Synapse, and <code>port</code> is
  15345. the listener port configured with the <code>metrics</code> resource.</p>
  15346. <p>If your prometheus is older than 1.5.2, you will need to replace
  15347. <code>static_configs</code> in the above with <code>target_groups</code>.</p>
  15348. </li>
  15349. <li>
  15350. <p>Restart Prometheus.</p>
  15351. </li>
  15352. <li>
  15353. <p>Consider using the <a href="https://github.com/matrix-org/synapse/tree/master/contrib/grafana/">grafana dashboard</a>
  15354. and required <a href="https://github.com/matrix-org/synapse/tree/master/contrib/prometheus/">recording rules</a> </p>
  15355. </li>
  15356. </ol>
  15357. <h2 id="monitoring-workers"><a class="header" href="#monitoring-workers">Monitoring workers</a></h2>
  15358. <p>To monitor a Synapse installation using <a href="workers.html">workers</a>,
  15359. every worker needs to be monitored independently, in addition to
  15360. the main homeserver process. This is because workers don't send
  15361. their metrics to the main homeserver process, but expose them
  15362. directly (if they are configured to do so).</p>
  15363. <p>To allow collecting metrics from a worker, you need to add a
  15364. <code>metrics</code> listener to its configuration, by adding the following
  15365. under <code>worker_listeners</code>:</p>
  15366. <pre><code class="language-yaml"> - type: metrics
  15367. bind_address: ''
  15368. port: 9101
  15369. </code></pre>
  15370. <p>The <code>bind_address</code> and <code>port</code> parameters should be set so that
  15371. the resulting listener can be reached by prometheus, and they
  15372. don't clash with an existing worker.
  15373. With this example, the worker's metrics would then be available
  15374. on <code>http://127.0.0.1:9101</code>.</p>
  15375. <p>Example Prometheus target for Synapse with workers:</p>
  15376. <pre><code class="language-yaml"> - job_name: &quot;synapse&quot;
  15377. scrape_interval: 15s
  15378. metrics_path: &quot;/_synapse/metrics&quot;
  15379. static_configs:
  15380. - targets: [&quot;my.server.here:port&quot;]
  15381. labels:
  15382. instance: &quot;my.server&quot;
  15383. job: &quot;master&quot;
  15384. index: 1
  15385. - targets: [&quot;my.workerserver.here:port&quot;]
  15386. labels:
  15387. instance: &quot;my.server&quot;
  15388. job: &quot;generic_worker&quot;
  15389. index: 1
  15390. - targets: [&quot;my.workerserver.here:port&quot;]
  15391. labels:
  15392. instance: &quot;my.server&quot;
  15393. job: &quot;generic_worker&quot;
  15394. index: 2
  15395. - targets: [&quot;my.workerserver.here:port&quot;]
  15396. labels:
  15397. instance: &quot;my.server&quot;
  15398. job: &quot;media_repository&quot;
  15399. index: 1
  15400. </code></pre>
  15401. <p>Labels (<code>instance</code>, <code>job</code>, <code>index</code>) can be defined as anything.
  15402. The labels are used to group graphs in grafana.</p>
  15403. <h2 id="renaming-of-metrics--deprecation-of-old-names-in-12"><a class="header" href="#renaming-of-metrics--deprecation-of-old-names-in-12">Renaming of metrics &amp; deprecation of old names in 1.2</a></h2>
  15404. <p>Synapse 1.2 updates the Prometheus metrics to match the naming
  15405. convention of the upstream <code>prometheus_client</code>. The old names are
  15406. considered deprecated and will be removed in a future version of
  15407. Synapse.
  15408. <strong>The old names will be disabled by default in Synapse v1.71.0 and removed
  15409. altogether in Synapse v1.73.0.</strong></p>
  15410. <table><thead><tr><th>New Name</th><th>Old Name</th></tr></thead><tbody>
  15411. <tr><td>python_gc_objects_collected_total</td><td>python_gc_objects_collected</td></tr>
  15412. <tr><td>python_gc_objects_uncollectable_total</td><td>python_gc_objects_uncollectable</td></tr>
  15413. <tr><td>python_gc_collections_total</td><td>python_gc_collections</td></tr>
  15414. <tr><td>process_cpu_seconds_total</td><td>process_cpu_seconds</td></tr>
  15415. <tr><td>synapse_federation_client_sent_transactions_total</td><td>synapse_federation_client_sent_transactions</td></tr>
  15416. <tr><td>synapse_federation_client_events_processed_total</td><td>synapse_federation_client_events_processed</td></tr>
  15417. <tr><td>synapse_event_processing_loop_count_total</td><td>synapse_event_processing_loop_count</td></tr>
  15418. <tr><td>synapse_event_processing_loop_room_count_total</td><td>synapse_event_processing_loop_room_count</td></tr>
  15419. <tr><td>synapse_util_caches_cache_hits</td><td>synapse_util_caches_cache:hits</td></tr>
  15420. <tr><td>synapse_util_caches_cache_size</td><td>synapse_util_caches_cache:size</td></tr>
  15421. <tr><td>synapse_util_caches_cache_evicted_size</td><td>synapse_util_caches_cache:evicted_size</td></tr>
  15422. <tr><td>synapse_util_caches_cache</td><td>synapse_util_caches_cache:total</td></tr>
  15423. <tr><td>synapse_util_caches_response_cache_size</td><td>synapse_util_caches_response_cache:size</td></tr>
  15424. <tr><td>synapse_util_caches_response_cache_hits</td><td>synapse_util_caches_response_cache:hits</td></tr>
  15425. <tr><td>synapse_util_caches_response_cache_evicted_size</td><td>synapse_util_caches_response_cache:evicted_size</td></tr>
  15426. <tr><td>synapse_util_metrics_block_count_total</td><td>synapse_util_metrics_block_count</td></tr>
  15427. <tr><td>synapse_util_metrics_block_time_seconds_total</td><td>synapse_util_metrics_block_time_seconds</td></tr>
  15428. <tr><td>synapse_util_metrics_block_ru_utime_seconds_total</td><td>synapse_util_metrics_block_ru_utime_seconds</td></tr>
  15429. <tr><td>synapse_util_metrics_block_ru_stime_seconds_total</td><td>synapse_util_metrics_block_ru_stime_seconds</td></tr>
  15430. <tr><td>synapse_util_metrics_block_db_txn_count_total</td><td>synapse_util_metrics_block_db_txn_count</td></tr>
  15431. <tr><td>synapse_util_metrics_block_db_txn_duration_seconds_total</td><td>synapse_util_metrics_block_db_txn_duration_seconds</td></tr>
  15432. <tr><td>synapse_util_metrics_block_db_sched_duration_seconds_total</td><td>synapse_util_metrics_block_db_sched_duration_seconds</td></tr>
  15433. <tr><td>synapse_background_process_start_count_total</td><td>synapse_background_process_start_count</td></tr>
  15434. <tr><td>synapse_background_process_ru_utime_seconds_total</td><td>synapse_background_process_ru_utime_seconds</td></tr>
  15435. <tr><td>synapse_background_process_ru_stime_seconds_total</td><td>synapse_background_process_ru_stime_seconds</td></tr>
  15436. <tr><td>synapse_background_process_db_txn_count_total</td><td>synapse_background_process_db_txn_count</td></tr>
  15437. <tr><td>synapse_background_process_db_txn_duration_seconds_total</td><td>synapse_background_process_db_txn_duration_seconds</td></tr>
  15438. <tr><td>synapse_background_process_db_sched_duration_seconds_total</td><td>synapse_background_process_db_sched_duration_seconds</td></tr>
  15439. <tr><td>synapse_storage_events_persisted_events_total</td><td>synapse_storage_events_persisted_events</td></tr>
  15440. <tr><td>synapse_storage_events_persisted_events_sep_total</td><td>synapse_storage_events_persisted_events_sep</td></tr>
  15441. <tr><td>synapse_storage_events_state_delta_total</td><td>synapse_storage_events_state_delta</td></tr>
  15442. <tr><td>synapse_storage_events_state_delta_single_event_total</td><td>synapse_storage_events_state_delta_single_event</td></tr>
  15443. <tr><td>synapse_storage_events_state_delta_reuse_delta_total</td><td>synapse_storage_events_state_delta_reuse_delta</td></tr>
  15444. <tr><td>synapse_federation_server_received_pdus_total</td><td>synapse_federation_server_received_pdus</td></tr>
  15445. <tr><td>synapse_federation_server_received_edus_total</td><td>synapse_federation_server_received_edus</td></tr>
  15446. <tr><td>synapse_handler_presence_notified_presence_total</td><td>synapse_handler_presence_notified_presence</td></tr>
  15447. <tr><td>synapse_handler_presence_federation_presence_out_total</td><td>synapse_handler_presence_federation_presence_out</td></tr>
  15448. <tr><td>synapse_handler_presence_presence_updates_total</td><td>synapse_handler_presence_presence_updates</td></tr>
  15449. <tr><td>synapse_handler_presence_timers_fired_total</td><td>synapse_handler_presence_timers_fired</td></tr>
  15450. <tr><td>synapse_handler_presence_federation_presence_total</td><td>synapse_handler_presence_federation_presence</td></tr>
  15451. <tr><td>synapse_handler_presence_bump_active_time_total</td><td>synapse_handler_presence_bump_active_time</td></tr>
  15452. <tr><td>synapse_federation_client_sent_edus_total</td><td>synapse_federation_client_sent_edus</td></tr>
  15453. <tr><td>synapse_federation_client_sent_pdu_destinations_count_total</td><td>synapse_federation_client_sent_pdu_destinations:count</td></tr>
  15454. <tr><td>synapse_federation_client_sent_pdu_destinations_total</td><td>synapse_federation_client_sent_pdu_destinations:total</td></tr>
  15455. <tr><td>synapse_handlers_appservice_events_processed_total</td><td>synapse_handlers_appservice_events_processed</td></tr>
  15456. <tr><td>synapse_notifier_notified_events_total</td><td>synapse_notifier_notified_events</td></tr>
  15457. <tr><td>synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter_total</td><td>synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter</td></tr>
  15458. <tr><td>synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter_total</td><td>synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter</td></tr>
  15459. <tr><td>synapse_http_httppusher_http_pushes_processed_total</td><td>synapse_http_httppusher_http_pushes_processed</td></tr>
  15460. <tr><td>synapse_http_httppusher_http_pushes_failed_total</td><td>synapse_http_httppusher_http_pushes_failed</td></tr>
  15461. <tr><td>synapse_http_httppusher_badge_updates_processed_total</td><td>synapse_http_httppusher_badge_updates_processed</td></tr>
  15462. <tr><td>synapse_http_httppusher_badge_updates_failed_total</td><td>synapse_http_httppusher_badge_updates_failed</td></tr>
  15463. <tr><td>synapse_admin_mau_current</td><td>synapse_admin_mau:current</td></tr>
  15464. <tr><td>synapse_admin_mau_max</td><td>synapse_admin_mau:max</td></tr>
  15465. <tr><td>synapse_admin_mau_registered_reserved_users</td><td>synapse_admin_mau:registered_reserved_users</td></tr>
  15466. </tbody></table>
  15467. <h2 id="removal-of-deprecated-metrics--time-based-counters-becoming-histograms-in-0310"><a class="header" href="#removal-of-deprecated-metrics--time-based-counters-becoming-histograms-in-0310">Removal of deprecated metrics &amp; time based counters becoming histograms in 0.31.0</a></h2>
  15468. <p>The duplicated metrics deprecated in Synapse 0.27.0 have been removed.</p>
  15469. <p>All time duration-based metrics have been changed to be seconds. This
  15470. affects:</p>
  15471. <table><thead><tr><th>msec -&gt; sec metrics</th></tr></thead><tbody>
  15472. <tr><td>python_gc_time</td></tr>
  15473. <tr><td>python_twisted_reactor_tick_time</td></tr>
  15474. <tr><td>synapse_storage_query_time</td></tr>
  15475. <tr><td>synapse_storage_schedule_time</td></tr>
  15476. <tr><td>synapse_storage_transaction_time</td></tr>
  15477. </tbody></table>
  15478. <p>Several metrics have been changed to be histograms, which sort entries
  15479. into buckets and allow better analysis. The following metrics are now
  15480. histograms:</p>
  15481. <table><thead><tr><th>Altered metrics</th></tr></thead><tbody>
  15482. <tr><td>python_gc_time</td></tr>
  15483. <tr><td>python_twisted_reactor_pending_calls</td></tr>
  15484. <tr><td>python_twisted_reactor_tick_time</td></tr>
  15485. <tr><td>synapse_http_server_response_time_seconds</td></tr>
  15486. <tr><td>synapse_storage_query_time</td></tr>
  15487. <tr><td>synapse_storage_schedule_time</td></tr>
  15488. <tr><td>synapse_storage_transaction_time</td></tr>
  15489. </tbody></table>
  15490. <h2 id="block-and-response-metrics-renamed-for-0270"><a class="header" href="#block-and-response-metrics-renamed-for-0270">Block and response metrics renamed for 0.27.0</a></h2>
  15491. <p>Synapse 0.27.0 begins the process of rationalising the duplicate
  15492. <code>*:count</code> metrics reported for the resource tracking for code blocks and
  15493. HTTP requests.</p>
  15494. <p>At the same time, the corresponding <code>*:total</code> metrics are being renamed,
  15495. as the <code>:total</code> suffix no longer makes sense in the absence of a
  15496. corresponding <code>:count</code> metric.</p>
  15497. <p>To enable a graceful migration path, this release just adds new names
  15498. for the metrics being renamed. A future release will remove the old
  15499. ones.</p>
  15500. <p>The following table shows the new metrics, and the old metrics which
  15501. they are replacing.</p>
  15502. <table><thead><tr><th>New name</th><th>Old name</th></tr></thead><tbody>
  15503. <tr><td>synapse_util_metrics_block_count</td><td>synapse_util_metrics_block_timer:count</td></tr>
  15504. <tr><td>synapse_util_metrics_block_count</td><td>synapse_util_metrics_block_ru_utime:count</td></tr>
  15505. <tr><td>synapse_util_metrics_block_count</td><td>synapse_util_metrics_block_ru_stime:count</td></tr>
  15506. <tr><td>synapse_util_metrics_block_count</td><td>synapse_util_metrics_block_db_txn_count:count</td></tr>
  15507. <tr><td>synapse_util_metrics_block_count</td><td>synapse_util_metrics_block_db_txn_duration:count</td></tr>
  15508. <tr><td>synapse_util_metrics_block_time_seconds</td><td>synapse_util_metrics_block_timer:total</td></tr>
  15509. <tr><td>synapse_util_metrics_block_ru_utime_seconds</td><td>synapse_util_metrics_block_ru_utime:total</td></tr>
  15510. <tr><td>synapse_util_metrics_block_ru_stime_seconds</td><td>synapse_util_metrics_block_ru_stime:total</td></tr>
  15511. <tr><td>synapse_util_metrics_block_db_txn_count</td><td>synapse_util_metrics_block_db_txn_count:total</td></tr>
  15512. <tr><td>synapse_util_metrics_block_db_txn_duration_seconds</td><td>synapse_util_metrics_block_db_txn_duration:total</td></tr>
  15513. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_requests</td></tr>
  15514. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_response_time:count</td></tr>
  15515. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_response_ru_utime:count</td></tr>
  15516. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_response_ru_stime:count</td></tr>
  15517. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_response_db_txn_count:count</td></tr>
  15518. <tr><td>synapse_http_server_response_count</td><td>synapse_http_server_response_db_txn_duration:count</td></tr>
  15519. <tr><td>synapse_http_server_response_time_seconds</td><td>synapse_http_server_response_time:total</td></tr>
  15520. <tr><td>synapse_http_server_response_ru_utime_seconds</td><td>synapse_http_server_response_ru_utime:total</td></tr>
  15521. <tr><td>synapse_http_server_response_ru_stime_seconds</td><td>synapse_http_server_response_ru_stime:total</td></tr>
  15522. <tr><td>synapse_http_server_response_db_txn_count</td><td>synapse_http_server_response_db_txn_count:total</td></tr>
  15523. <tr><td>synapse_http_server_response_db_txn_duration_seconds</td><td>synapse_http_server_response_db_txn_duration:total</td></tr>
  15524. </tbody></table>
  15525. <h2 id="standard-metric-names"><a class="header" href="#standard-metric-names">Standard Metric Names</a></h2>
  15526. <p>As of synapse version 0.18.2, the format of the process-wide metrics has
  15527. been changed to fit prometheus standard naming conventions. Additionally
  15528. the units have been changed to seconds, from milliseconds.</p>
  15529. <table><thead><tr><th>New name</th><th>Old name</th></tr></thead><tbody>
  15530. <tr><td>process_cpu_user_seconds_total</td><td>process_resource_utime / 1000</td></tr>
  15531. <tr><td>process_cpu_system_seconds_total</td><td>process_resource_stime / 1000</td></tr>
  15532. <tr><td>process_open_fds (no 'type' label)</td><td>process_fds</td></tr>
  15533. </tbody></table>
  15534. <p>The python-specific counts of garbage collector performance have been
  15535. renamed.</p>
  15536. <table><thead><tr><th>New name</th><th>Old name</th></tr></thead><tbody>
  15537. <tr><td>python_gc_time</td><td>reactor_gc_time</td></tr>
  15538. <tr><td>python_gc_unreachable_total</td><td>reactor_gc_unreachable</td></tr>
  15539. <tr><td>python_gc_counts</td><td>reactor_gc_counts</td></tr>
  15540. </tbody></table>
  15541. <p>The twisted-specific reactor metrics have been renamed.</p>
  15542. <table><thead><tr><th>New name</th><th>Old name</th></tr></thead><tbody>
  15543. <tr><td>python_twisted_reactor_pending_calls</td><td>reactor_pending_calls</td></tr>
  15544. <tr><td>python_twisted_reactor_tick_time</td><td>reactor_tick_time</td></tr>
  15545. </tbody></table>
  15546. <div style="break-before: page; page-break-before: always;"></div><h1 id="reporting-homeserver-usage-statistics"><a class="header" href="#reporting-homeserver-usage-statistics">Reporting Homeserver Usage Statistics</a></h1>
  15547. <p>When generating your Synapse configuration file, you are asked whether you
  15548. would like to report usage statistics to Matrix.org. These statistics
  15549. provide the foundation a glimpse into the number of Synapse homeservers
  15550. participating in the network, as well as statistics such as the number of
  15551. rooms being created and messages being sent. This feature is sometimes
  15552. affectionately called &quot;phone home&quot; stats. Reporting
  15553. <a href="usage/administration/monitoring/../../configuration/config_documentation.html#report_stats">is optional</a>
  15554. and the reporting endpoint
  15555. <a href="usage/administration/monitoring/../../configuration/config_documentation.html#report_stats_endpoint">can be configured</a>,
  15556. in case you would like to instead report statistics from a set of homeservers
  15557. to your own infrastructure.</p>
  15558. <p>This documentation aims to define the statistics available and the
  15559. homeserver configuration options that exist to tweak it.</p>
  15560. <h2 id="available-statistics"><a class="header" href="#available-statistics">Available Statistics</a></h2>
  15561. <p>The following statistics are sent to the configured reporting endpoint:</p>
  15562. <table><thead><tr><th>Statistic Name</th><th>Type</th><th>Description</th></tr></thead><tbody>
  15563. <tr><td><code>homeserver</code></td><td>string</td><td>The homeserver's server name.</td></tr>
  15564. <tr><td><code>memory_rss</code></td><td>int</td><td>The memory usage of the process (in kilobytes on Unix-based systems, bytes on MacOS).</td></tr>
  15565. <tr><td><code>cpu_average</code></td><td>int</td><td>CPU time in % of a single core (not % of all cores).</td></tr>
  15566. <tr><td><code>server_context</code></td><td>string</td><td>An arbitrary string used to group statistics from a set of homeservers.</td></tr>
  15567. <tr><td><code>timestamp</code></td><td>int</td><td>The current time, represented as the number of seconds since the epoch.</td></tr>
  15568. <tr><td><code>uptime_seconds</code></td><td>int</td><td>The number of seconds since the homeserver was last started.</td></tr>
  15569. <tr><td><code>python_version</code></td><td>string</td><td>The Python version number in use (e.g &quot;3.7.1&quot;). Taken from <code>sys.version_info</code>.</td></tr>
  15570. <tr><td><code>total_users</code></td><td>int</td><td>The number of registered users on the homeserver.</td></tr>
  15571. <tr><td><code>total_nonbridged_users</code></td><td>int</td><td>The number of users, excluding those created by an Application Service.</td></tr>
  15572. <tr><td><code>daily_user_type_native</code></td><td>int</td><td>The number of native users created in the last 24 hours.</td></tr>
  15573. <tr><td><code>daily_user_type_guest</code></td><td>int</td><td>The number of guest users created in the last 24 hours.</td></tr>
  15574. <tr><td><code>daily_user_type_bridged</code></td><td>int</td><td>The number of users created by Application Services in the last 24 hours.</td></tr>
  15575. <tr><td><code>total_room_count</code></td><td>int</td><td>The total number of rooms present on the homeserver.</td></tr>
  15576. <tr><td><code>daily_active_users</code></td><td>int</td><td>The number of unique users<sup class="footnote-reference"><a href="#1">1</a></sup> that have used the homeserver in the last 24 hours.</td></tr>
  15577. <tr><td><code>monthly_active_users</code></td><td>int</td><td>The number of unique users<sup class="footnote-reference"><a href="#1">1</a></sup> that have used the homeserver in the last 30 days.</td></tr>
  15578. <tr><td><code>daily_active_rooms</code></td><td>int</td><td>The number of rooms that have had a (state) event with the type <code>m.room.message</code> sent in them in the last 24 hours.</td></tr>
  15579. <tr><td><code>daily_active_e2ee_rooms</code></td><td>int</td><td>The number of rooms that have had a (state) event with the type <code>m.room.encrypted</code> sent in them in the last 24 hours.</td></tr>
  15580. <tr><td><code>daily_messages</code></td><td>int</td><td>The number of (state) events with the type <code>m.room.message</code> seen in the last 24 hours.</td></tr>
  15581. <tr><td><code>daily_e2ee_messages</code></td><td>int</td><td>The number of (state) events with the type <code>m.room.encrypted</code> seen in the last 24 hours.</td></tr>
  15582. <tr><td><code>daily_sent_messages</code></td><td>int</td><td>The number of (state) events sent by a local user with the type <code>m.room.message</code> seen in the last 24 hours.</td></tr>
  15583. <tr><td><code>daily_sent_e2ee_messages</code></td><td>int</td><td>The number of (state) events sent by a local user with the type <code>m.room.encrypted</code> seen in the last 24 hours.</td></tr>
  15584. <tr><td><code>r30v2_users_all</code></td><td>int</td><td>The number of 30 day retained users, with a revised algorithm. Defined as users that appear more than once in the past 60 days, and have more than 30 days between the most and least recent appearances in the past 60 days. Includes clients that do not fit into the below r30 client types.</td></tr>
  15585. <tr><td><code>r30v2_users_android</code></td><td>int</td><td>The number of 30 day retained users, as defined above. Filtered only to clients with (&quot;riot&quot; or &quot;element&quot;) and &quot;android&quot; (case-insensitive) in the user agent string.</td></tr>
  15586. <tr><td><code>r30v2_users_ios</code></td><td>int</td><td>The number of 30 day retained users, as defined above. Filtered only to clients with (&quot;riot&quot; or &quot;element&quot;) and &quot;ios&quot; (case-insensitive) in the user agent string.</td></tr>
  15587. <tr><td><code>r30v2_users_electron</code></td><td>int</td><td>The number of 30 day retained users, as defined above. Filtered only to clients with (&quot;riot&quot; or &quot;element&quot;) and &quot;electron&quot; (case-insensitive) in the user agent string.</td></tr>
  15588. <tr><td><code>r30v2_users_web</code></td><td>int</td><td>The number of 30 day retained users, as defined above. Filtered only to clients with &quot;mozilla&quot; or &quot;gecko&quot; (case-insensitive) in the user agent string.</td></tr>
  15589. <tr><td><code>cache_factor</code></td><td>int</td><td>The configured <a href="usage/administration/monitoring/../../configuration/config_documentation.html#caching"><code>global factor</code></a> value for caching.</td></tr>
  15590. <tr><td><code>event_cache_size</code></td><td>int</td><td>The configured <a href="usage/administration/monitoring/../../configuration/config_documentation.html#caching"><code>event_cache_size</code></a> value for caching.</td></tr>
  15591. <tr><td><code>database_engine</code></td><td>string</td><td>The database engine that is in use. Either &quot;psycopg2&quot; meaning PostgreSQL is in use, or &quot;sqlite3&quot; for SQLite3.</td></tr>
  15592. <tr><td><code>database_server_version</code></td><td>string</td><td>The version of the database server. Examples being &quot;10.10&quot; for PostgreSQL server version 10.0, and &quot;3.38.5&quot; for SQLite 3.38.5 installed on the system.</td></tr>
  15593. <tr><td><code>log_level</code></td><td>string</td><td>The log level in use. Examples are &quot;INFO&quot;, &quot;WARNING&quot;, &quot;ERROR&quot;, &quot;DEBUG&quot;, etc.</td></tr>
  15594. </tbody></table>
  15595. <div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
  15596. <p>Native matrix users and guests are always counted. If the
  15597. <a href="usage/administration/monitoring/../../configuration/config_documentation.html#track_puppeted_user_ips"><code>track_puppeted_user_ips</code></a>
  15598. option is set to <code>true</code>, &quot;puppeted&quot; users (users that an Application Service have performed
  15599. <a href="https://spec.matrix.org/v1.3/application-service-api/#identity-assertion">an action on behalf of</a>)
  15600. will also be counted. Note that an Application Service can &quot;puppet&quot; any user in their
  15601. <a href="https://spec.matrix.org/v1.3/application-service-api/#registration">user namespace</a>,
  15602. not only users that the Application Service has created. If this happens, the Application Service
  15603. will additionally be counted as a user (irrespective of <code>track_puppeted_user_ips</code>).</p>
  15604. </div>
  15605. <h2 id="using-a-custom-statistics-collection-server"><a class="header" href="#using-a-custom-statistics-collection-server">Using a Custom Statistics Collection Server</a></h2>
  15606. <p>If statistics reporting is enabled, the endpoint that Synapse sends metrics to is configured by the
  15607. <a href="usage/administration/monitoring/../../configuration/config_documentation.html#report_stats_endpoint"><code>report_stats_endpoint</code></a> config
  15608. option. By default, statistics are sent to Matrix.org.</p>
  15609. <p>If you would like to set up your own statistics collection server and send metrics there, you may
  15610. consider using one of the following known implementations:</p>
  15611. <ul>
  15612. <li><a href="https://github.com/matrix-org/panopticon">Matrix.org's Panopticon</a></li>
  15613. <li><a href="https://gitlab.com/famedly/infra/services/barad-dur">Famedly's Barad-dûr</a></li>
  15614. </ul>
  15615. <div style="break-before: page; page-break-before: always;"></div><h1 id="monthly-active-users"><a class="header" href="#monthly-active-users">Monthly Active Users</a></h1>
  15616. <p>Synapse can be configured to record the number of monthly active users (also referred to as MAU) on a given homeserver.
  15617. For clarity's sake, MAU only tracks local users.</p>
  15618. <p>Please note that the metrics recorded by the <a href="usage/administration/../../usage/administration/monitoring/reporting_homeserver_usage_statistics.html">Homeserver Usage Stats</a>
  15619. are calculated differently. The <code>monthly_active_users</code> from the usage stats does not take into account any
  15620. of the rules below, and counts any users who have made a request to the homeserver in the last 30 days.</p>
  15621. <p>See the <a href="usage/administration/../../usage/configuration/config_documentation.html#limit_usage_by_mau">configuration manual</a> for details on how to configure MAU.</p>
  15622. <h2 id="calculating-active-users"><a class="header" href="#calculating-active-users">Calculating active users</a></h2>
  15623. <p>Individual user activity is measured in active days. If a user performs an action, the exact time of that action is then recorded. When
  15624. calculating the MAU figure, any users with a recorded action in the last 30 days are considered part of the cohort. Days are measured
  15625. as a rolling window from the current system time to 30 days ago.</p>
  15626. <p>So for example, if Synapse were to calculate the active users on the 15th July at 13:25, it would include any activity from 15th June 13:25 onwards.</p>
  15627. <p>A user is <strong>never</strong> considered active if they are either:</p>
  15628. <ul>
  15629. <li>Part of the trial day cohort (described below)</li>
  15630. <li>Owned by an application service.
  15631. <ul>
  15632. <li>Note: This <strong>only</strong> covers users that are part of an application service <code>namespaces.users</code> registration. The namespace
  15633. must also be marked as <code>exclusive</code>.</li>
  15634. </ul>
  15635. </li>
  15636. </ul>
  15637. <p>Otherwise, any request to Synapse will mark the user as active. Please note that registration will not mark a user as active <em>unless</em>
  15638. they register with a 3pid that is included in the config field <code>mau_limits_reserved_threepids</code>.</p>
  15639. <p>The Prometheus metric for MAU is refreshed every 5 minutes.</p>
  15640. <p>Once an hour, Synapse checks to see if any users are inactive (with only activity timestamps later than 30 days). These users
  15641. are removed from the active users cohort. If they then become active, they are immediately restored to the cohort.</p>
  15642. <p>It is important to note that <strong>deactivated</strong> users are not immediately removed from the pool of active users, but as these users won't
  15643. perform actions they will eventually be removed from the cohort.</p>
  15644. <h3 id="trial-days"><a class="header" href="#trial-days">Trial days</a></h3>
  15645. <p>If the config option <code>mau_trial_days</code> is set, a user must have been active this many days <strong>after</strong> registration to be active. A user is in the
  15646. trial period if their registration timestamp (also known as the <code>creation_ts</code>) is less than <code>mau_trial_days</code> old.</p>
  15647. <p>As an example, if <code>mau_trial_days</code> is set to <code>3</code> and a user is active <strong>after</strong> 3 days (72 hours from registration time) then they will be counted as active.</p>
  15648. <p>The <code>mau_appservice_trial_days</code> config further extends this rule by applying different durations depending on the <code>appservice_id</code> of the user.
  15649. Users registered by an application service will be recorded with an <code>appservice_id</code> matching the <code>id</code> key in the registration file for that service.</p>
  15650. <h2 id="limiting-usage-of-the-homeserver-when-the-maximum-mau-is-reached"><a class="header" href="#limiting-usage-of-the-homeserver-when-the-maximum-mau-is-reached">Limiting usage of the homeserver when the maximum MAU is reached</a></h2>
  15651. <p>If both config options <code>limit_usage_by_mau</code> and <code>max_mau_value</code> is set, and the current MAU value exceeds the maximum value, the
  15652. homeserver will begin to block some actions.</p>
  15653. <p>Individual users matching <strong>any</strong> of the below criteria never have their actions blocked:</p>
  15654. <ul>
  15655. <li>Considered part of the cohort of MAU users.</li>
  15656. <li>Considered part of the trial period.</li>
  15657. <li>Registered as a <code>support</code> user.</li>
  15658. <li>Application service users if <code>track_appservice_user_ips</code> is NOT set.</li>
  15659. </ul>
  15660. <p>Please not that server admins are <strong>not</strong> exempt from blocking.</p>
  15661. <p>The following actions are blocked when the MAU limit is exceeded:</p>
  15662. <ul>
  15663. <li>Logging in</li>
  15664. <li>Sending events</li>
  15665. <li>Creating rooms</li>
  15666. <li>Syncing</li>
  15667. </ul>
  15668. <p>Registration is also blocked for all new signups <em>unless</em> the user is registering with a threepid included in the <code>mau_limits_reserved_threepids</code>
  15669. config value.</p>
  15670. <p>When a request is blocked, the response will have the <code>errcode</code> <code>M_RESOURCE_LIMIT_EXCEEDED</code>.</p>
  15671. <h2 id="metrics-1"><a class="header" href="#metrics-1">Metrics</a></h2>
  15672. <p>Synapse records several different prometheus metrics for MAU.</p>
  15673. <p><code>synapse_admin_mau_current</code> records the current MAU figure for native (non-application-service) users.</p>
  15674. <p><code>synapse_admin_mau_max</code> records the maximum MAU as dictated by the <code>max_mau_value</code> config value.</p>
  15675. <p><code>synapse_admin_mau_current_mau_by_service</code> records the current MAU including application service users. The label <code>app_service</code> can be used
  15676. to filter by a specific service ID. This <em>also</em> includes non-application-service users under <code>app_service=native</code> .</p>
  15677. <p><code>synapse_admin_mau_registered_reserved_users</code> records the number of users specified in <code>mau_limits_reserved_threepids</code> which have
  15678. registered accounts on the homeserver.</p>
  15679. <div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-synapse-through-grafana-graphs"><a class="header" href="#understanding-synapse-through-grafana-graphs">Understanding Synapse through Grafana graphs</a></h2>
  15680. <p>It is possible to monitor much of the internal state of Synapse using <a href="https://prometheus.io">Prometheus</a>
  15681. metrics and <a href="https://grafana.com/">Grafana</a>.
  15682. A guide for configuring Synapse to provide metrics is available <a href="usage/administration/../../metrics-howto.html">here</a>
  15683. and information on setting up Grafana is <a href="https://github.com/matrix-org/synapse/tree/master/contrib/grafana">here</a>.
  15684. In this setup, Prometheus will periodically scrape the information Synapse provides and
  15685. store a record of it over time. Grafana is then used as an interface to query and
  15686. present this information through a series of pretty graphs.</p>
  15687. <p>Once you have grafana set up, and assuming you're using <a href="https://github.com/matrix-org/synapse/blob/master/contrib/grafana/synapse.json">our grafana dashboard template</a>, look for the following graphs when debugging a slow/overloaded Synapse:</p>
  15688. <h2 id="message-event-send-time"><a class="header" href="#message-event-send-time">Message Event Send Time</a></h2>
  15689. <p><img src="https://user-images.githubusercontent.com/1342360/82239409-a1c8e900-9930-11ea-8081-e4614e0c63f4.png" alt="image" /></p>
  15690. <p>This, along with the CPU and Memory graphs, is a good way to check the general health of your Synapse instance. It represents how long it takes for a user on your homeserver to send a message.</p>
  15691. <h2 id="transaction-count-and-transaction-duration"><a class="header" href="#transaction-count-and-transaction-duration">Transaction Count and Transaction Duration</a></h2>
  15692. <p><img src="https://user-images.githubusercontent.com/1342360/82239985-8d392080-9931-11ea-80d0-843ab2f22e1e.png" alt="image" /></p>
  15693. <p><img src="https://user-images.githubusercontent.com/1342360/82240050-ab068580-9931-11ea-98f1-f94671cbac9a.png" alt="image" /></p>
  15694. <p>These graphs show the database transactions that are occurring the most frequently, as well as those are that are taking the most amount of time to execute.</p>
  15695. <p><img src="https://user-images.githubusercontent.com/1342360/82240192-e86b1300-9931-11ea-9aac-3e2c9bfa6fdc.png" alt="image" /></p>
  15696. <p>In the first graph, we can see obvious spikes corresponding to lots of <code>get_user_by_id</code> transactions. This would be useful information to figure out which part of the Synapse codebase is potentially creating a heavy load on the system. However, be sure to cross-reference this with Transaction Duration, which states that <code>get_users_by_id</code> is actually a very quick database transaction and isn't causing as much load as others, like <code>persist_events</code>:</p>
  15697. <p><img src="https://user-images.githubusercontent.com/1342360/82240467-62030100-9932-11ea-8db9-917f2d977fe1.png" alt="image" /></p>
  15698. <p>Still, it's probably worth investigating why we're getting users from the database that often, and whether it's possible to reduce the amount of queries we make by adjusting our cache factor(s).</p>
  15699. <p>The <code>persist_events</code> transaction is responsible for saving new room events to the Synapse database, so can often show a high transaction duration.</p>
  15700. <h2 id="federation-2"><a class="header" href="#federation-2">Federation</a></h2>
  15701. <p>The charts in the &quot;Federation&quot; section show information about incoming and outgoing federation requests. Federation data can be divided into two basic types:</p>
  15702. <ul>
  15703. <li>PDU (Persistent Data Unit) - room events: messages, state events (join/leave), etc. These are permanently stored in the database.</li>
  15704. <li>EDU (Ephemeral Data Unit) - other data, which need not be stored permanently, such as read receipts, typing notifications.</li>
  15705. </ul>
  15706. <p>The &quot;Outgoing EDUs by type&quot; chart shows the EDUs within outgoing federation requests by type: <code>m.device_list_update</code>, <code>m.direct_to_device</code>, <code>m.presence</code>, <code>m.receipt</code>, <code>m.typing</code>.</p>
  15707. <p>If you see a large number of <code>m.presence</code> EDUs and are having trouble with too much CPU load, you can disable <code>presence</code> in the Synapse config. See also <a href="https://github.com/matrix-org/synapse/issues/3971">#3971</a>.</p>
  15708. <h2 id="caches"><a class="header" href="#caches">Caches</a></h2>
  15709. <p><img src="https://user-images.githubusercontent.com/1342360/82240572-8b239180-9932-11ea-96ff-6b5f0e57ebe5.png" alt="image" /></p>
  15710. <p><img src="https://user-images.githubusercontent.com/1342360/82240666-b8703f80-9932-11ea-86af-9f663988d8da.png" alt="image" /></p>
  15711. <p>This is quite a useful graph. It shows how many times Synapse attempts to retrieve a piece of data from a cache which the cache did not contain, thus resulting in a call to the database. We can see here that the <code>_get_joined_profile_from_event_id</code> cache is being requested a lot, and often the data we're after is not cached.</p>
  15712. <p>Cross-referencing this with the Eviction Rate graph, which shows that entries are being evicted from <code>_get_joined_profile_from_event_id</code> quite often:</p>
  15713. <p><img src="https://user-images.githubusercontent.com/1342360/82240766-de95df80-9932-11ea-8c15-5acfc57c48da.png" alt="image" /></p>
  15714. <p>we should probably consider raising the size of that cache by raising its cache factor (a multiplier value for the size of an individual cache). Information on doing so is available <a href="https://github.com/matrix-org/synapse/blob/ee421e524478c1ad8d43741c27379499c2f6135c/docs/sample_config.yaml#L608-L642">here</a> (note that the configuration of individual cache factors through the configuration file is available in Synapse v1.14.0+, whereas doing so through environment variables has been supported for a very long time). Note that this will increase Synapse's overall memory usage.</p>
  15715. <h2 id="forward-extremities"><a class="header" href="#forward-extremities">Forward Extremities</a></h2>
  15716. <p><img src="https://user-images.githubusercontent.com/1342360/82241440-13566680-9934-11ea-8b88-ba468db937ed.png" alt="image" /></p>
  15717. <p>Forward extremities are the leaf events at the end of a DAG in a room, aka events that have no children. The more that exist in a room, the more <a href="https://spec.matrix.org/v1.1/server-server-api/#room-state-resolution">state resolution</a> that Synapse needs to perform (hint: it's an expensive operation). While Synapse has code to prevent too many of these existing at one time in a room, bugs can sometimes make them crop up again.</p>
  15718. <p>If a room has &gt;10 forward extremities, it's worth checking which room is the culprit and potentially removing them using the SQL queries mentioned in <a href="https://github.com/matrix-org/synapse/issues/1760">#1760</a>.</p>
  15719. <h2 id="garbage-collection"><a class="header" href="#garbage-collection">Garbage Collection</a></h2>
  15720. <p><img src="https://user-images.githubusercontent.com/1342360/82241911-da6ac180-9934-11ea-9a0d-a311fe22acd0.png" alt="image" /></p>
  15721. <p>Large spikes in garbage collection times (bigger than shown here, I'm talking in the
  15722. multiple seconds range), can cause lots of problems in Synapse performance. It's more an
  15723. indicator of problems, and a symptom of other problems though, so check other graphs for what might be causing it.</p>
  15724. <h2 id="final-thoughts"><a class="header" href="#final-thoughts">Final Thoughts</a></h2>
  15725. <p>If you're still having performance problems with your Synapse instance and you've
  15726. tried everything you can, it may just be a lack of system resources. Consider adding
  15727. more CPU and RAM, and make use of <a href="usage/administration/../../workers.html">worker mode</a>
  15728. to make use of multiple CPU cores / multiple machines for your homeserver.</p>
  15729. <div style="break-before: page; page-break-before: always;"></div><h2 id="some-useful-sql-queries-for-synapse-admins"><a class="header" href="#some-useful-sql-queries-for-synapse-admins">Some useful SQL queries for Synapse Admins</a></h2>
  15730. <h2 id="size-of-full-matrix-db"><a class="header" href="#size-of-full-matrix-db">Size of full matrix db</a></h2>
  15731. <pre><code class="language-sql">SELECT pg_size_pretty( pg_database_size( 'matrix' ) );
  15732. </code></pre>
  15733. <h3 id="result-example"><a class="header" href="#result-example">Result example:</a></h3>
  15734. <pre><code>pg_size_pretty
  15735. ----------------
  15736. 6420 MB
  15737. (1 row)
  15738. </code></pre>
  15739. <h2 id="show-top-20-larger-tables-by-row-count"><a class="header" href="#show-top-20-larger-tables-by-row-count">Show top 20 larger tables by row count</a></h2>
  15740. <pre><code class="language-sql">SELECT relname, n_live_tup AS &quot;rows&quot;
  15741. FROM pg_stat_user_tables
  15742. ORDER BY n_live_tup DESC
  15743. LIMIT 20;
  15744. </code></pre>
  15745. <p>This query is quick, but may be very approximate, for exact number of rows use:</p>
  15746. <pre><code class="language-sql">SELECT COUNT(*) FROM &lt;table_name&gt;;
  15747. </code></pre>
  15748. <h3 id="result-example-1"><a class="header" href="#result-example-1">Result example:</a></h3>
  15749. <pre><code>state_groups_state - 161687170
  15750. event_auth - 8584785
  15751. event_edges - 6995633
  15752. event_json - 6585916
  15753. event_reference_hashes - 6580990
  15754. events - 6578879
  15755. received_transactions - 5713989
  15756. event_to_state_groups - 4873377
  15757. stream_ordering_to_exterm - 4136285
  15758. current_state_delta_stream - 3770972
  15759. event_search - 3670521
  15760. state_events - 2845082
  15761. room_memberships - 2785854
  15762. cache_invalidation_stream - 2448218
  15763. state_groups - 1255467
  15764. state_group_edges - 1229849
  15765. current_state_events - 1222905
  15766. users_in_public_rooms - 364059
  15767. device_lists_stream - 326903
  15768. user_directory_search - 316433
  15769. </code></pre>
  15770. <h2 id="show-top-20-larger-tables-by-storage-size"><a class="header" href="#show-top-20-larger-tables-by-storage-size">Show top 20 larger tables by storage size</a></h2>
  15771. <pre><code class="language-sql">SELECT nspname || '.' || relname AS &quot;relation&quot;,
  15772. pg_size_pretty(pg_total_relation_size(c.oid)) AS &quot;total_size&quot;
  15773. FROM pg_class c
  15774. LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
  15775. WHERE nspname NOT IN ('pg_catalog', 'information_schema')
  15776. AND c.relkind &lt;&gt; 'i'
  15777. AND nspname !~ '^pg_toast'
  15778. ORDER BY pg_total_relation_size(c.oid) DESC
  15779. LIMIT 20;
  15780. </code></pre>
  15781. <h3 id="result-example-2"><a class="header" href="#result-example-2">Result example:</a></h3>
  15782. <pre><code>public.state_groups_state - 27 GB
  15783. public.event_json - 9855 MB
  15784. public.events - 3675 MB
  15785. public.event_edges - 3404 MB
  15786. public.received_transactions - 2745 MB
  15787. public.event_reference_hashes - 1864 MB
  15788. public.event_auth - 1775 MB
  15789. public.stream_ordering_to_exterm - 1663 MB
  15790. public.event_search - 1370 MB
  15791. public.room_memberships - 1050 MB
  15792. public.event_to_state_groups - 948 MB
  15793. public.current_state_delta_stream - 711 MB
  15794. public.state_events - 611 MB
  15795. public.presence_stream - 530 MB
  15796. public.current_state_events - 525 MB
  15797. public.cache_invalidation_stream - 466 MB
  15798. public.receipts_linearized - 279 MB
  15799. public.state_groups - 160 MB
  15800. public.device_lists_remote_cache - 124 MB
  15801. public.state_group_edges - 122 MB
  15802. </code></pre>
  15803. <h2 id="show-top-20-larger-rooms-by-state-events-count"><a class="header" href="#show-top-20-larger-rooms-by-state-events-count">Show top 20 larger rooms by state events count</a></h2>
  15804. <p>You get the same information when you use the
  15805. <a href="usage/administration/../../admin_api/rooms.html#list-room-api">admin API</a>
  15806. and set parameter <code>order_by=state_events</code>.</p>
  15807. <pre><code class="language-sql">SELECT r.name, s.room_id, s.current_state_events
  15808. FROM room_stats_current s
  15809. LEFT JOIN room_stats_state r USING (room_id)
  15810. ORDER BY current_state_events DESC
  15811. LIMIT 20;
  15812. </code></pre>
  15813. <p>and by state_group_events count:</p>
  15814. <pre><code class="language-sql">SELECT rss.name, s.room_id, COUNT(s.room_id)
  15815. FROM state_groups_state s
  15816. LEFT JOIN room_stats_state rss USING (room_id)
  15817. GROUP BY s.room_id, rss.name
  15818. ORDER BY COUNT(s.room_id) DESC
  15819. LIMIT 20;
  15820. </code></pre>
  15821. <p>plus same, but with join removed for performance reasons:</p>
  15822. <pre><code class="language-sql">SELECT s.room_id, COUNT(s.room_id)
  15823. FROM state_groups_state s
  15824. GROUP BY s.room_id
  15825. ORDER BY COUNT(s.room_id) DESC
  15826. LIMIT 20;
  15827. </code></pre>
  15828. <h2 id="show-top-20-rooms-by-new-events-count-in-last-1-day"><a class="header" href="#show-top-20-rooms-by-new-events-count-in-last-1-day">Show top 20 rooms by new events count in last 1 day:</a></h2>
  15829. <pre><code class="language-sql">SELECT e.room_id, r.name, COUNT(e.event_id) cnt
  15830. FROM events e
  15831. LEFT JOIN room_stats_state r USING (room_id)
  15832. WHERE e.origin_server_ts &gt;= DATE_PART('epoch', NOW() - INTERVAL '1 day') * 1000
  15833. GROUP BY e.room_id, r.name
  15834. ORDER BY cnt DESC
  15835. LIMIT 20;
  15836. </code></pre>
  15837. <h2 id="show-top-20-users-on-homeserver-by-sent-events-messages-at-last-month"><a class="header" href="#show-top-20-users-on-homeserver-by-sent-events-messages-at-last-month">Show top 20 users on homeserver by sent events (messages) at last month:</a></h2>
  15838. <p>Caution. This query does not use any indexes, can be slow and create load on the database.</p>
  15839. <pre><code class="language-sql">SELECT COUNT(*), sender
  15840. FROM events
  15841. WHERE (type = 'm.room.encrypted' OR type = 'm.room.message')
  15842. AND origin_server_ts &gt;= DATE_PART('epoch', NOW() - INTERVAL '1 month') * 1000
  15843. GROUP BY sender
  15844. ORDER BY COUNT(*) DESC
  15845. LIMIT 20;
  15846. </code></pre>
  15847. <h2 id="show-last-100-messages-from-needed-user-with-room-names"><a class="header" href="#show-last-100-messages-from-needed-user-with-room-names">Show last 100 messages from needed user, with room names:</a></h2>
  15848. <pre><code class="language-sql">SELECT e.room_id, r.name, e.event_id, e.type, e.content, j.json
  15849. FROM events e
  15850. LEFT JOIN event_json j USING (room_id)
  15851. LEFT JOIN room_stats_state r USING (room_id)
  15852. WHERE sender = '@LOGIN:example.com'
  15853. AND e.type = 'm.room.message'
  15854. ORDER BY stream_ordering DESC
  15855. LIMIT 100;
  15856. </code></pre>
  15857. <h2 id="show-rooms-with-names-sorted-by-events-in-this-rooms"><a class="header" href="#show-rooms-with-names-sorted-by-events-in-this-rooms">Show rooms with names, sorted by events in this rooms</a></h2>
  15858. <p><strong>Sort and order with bash</strong></p>
  15859. <pre><code class="language-bash">echo &quot;SELECT event_json.room_id, room_stats_state.name FROM event_json, room_stats_state \
  15860. WHERE room_stats_state.room_id = event_json.room_id&quot; | psql -d synapse -h localhost -U synapse_user -t \
  15861. | sort | uniq -c | sort -n
  15862. </code></pre>
  15863. <p>Documentation for <code>psql</code> command line parameters: https://www.postgresql.org/docs/current/app-psql.html</p>
  15864. <p><strong>Sort and order with SQL</strong></p>
  15865. <pre><code class="language-sql">SELECT COUNT(*), event_json.room_id, room_stats_state.name
  15866. FROM event_json, room_stats_state
  15867. WHERE room_stats_state.room_id = event_json.room_id
  15868. GROUP BY event_json.room_id, room_stats_state.name
  15869. ORDER BY COUNT(*) DESC
  15870. LIMIT 50;
  15871. </code></pre>
  15872. <h3 id="result-example-3"><a class="header" href="#result-example-3">Result example:</a></h3>
  15873. <pre><code> 9459 !FPUfgzXYWTKgIrwKxW:matrix.org | This Week in Matrix
  15874. 9459 !FPUfgzXYWTKgIrwKxW:matrix.org | This Week in Matrix (TWIM)
  15875. 17799 !iDIOImbmXxwNngznsa:matrix.org | Linux in Russian
  15876. 18739 !GnEEPYXUhoaHbkFBNX:matrix.org | Riot Android
  15877. 23373 !QtykxKocfZaZOUrTwp:matrix.org | Matrix HQ
  15878. 39504 !gTQfWzbYncrtNrvEkB:matrix.org | ru.[matrix]
  15879. 43601 !iNmaIQExDMeqdITdHH:matrix.org | Riot
  15880. 43601 !iNmaIQExDMeqdITdHH:matrix.org | Riot Web/Desktop
  15881. </code></pre>
  15882. <h2 id="lookup-room-state-info-by-list-of-room_id"><a class="header" href="#lookup-room-state-info-by-list-of-room_id">Lookup room state info by list of room_id</a></h2>
  15883. <p>You get the same information when you use the
  15884. <a href="usage/administration/../../admin_api/rooms.html#room-details-api">admin API</a>.</p>
  15885. <pre><code class="language-sql">SELECT rss.room_id, rss.name, rss.canonical_alias, rss.topic, rss.encryption,
  15886. rsc.joined_members, rsc.local_users_in_room, rss.join_rules
  15887. FROM room_stats_state rss
  15888. LEFT JOIN room_stats_current rsc USING (room_id)
  15889. WHERE room_id IN (
  15890. '!OGEhHVWSdvArJzumhm:matrix.org',
  15891. '!YTvKGNlinIzlkMTVRl:matrix.org'
  15892. );
  15893. </code></pre>
  15894. <h2 id="show-users-and-devices-that-have-not-been-online-for-a-while"><a class="header" href="#show-users-and-devices-that-have-not-been-online-for-a-while">Show users and devices that have not been online for a while</a></h2>
  15895. <pre><code class="language-sql">SELECT user_id, device_id, user_agent, TO_TIMESTAMP(last_seen / 1000) AS &quot;last_seen&quot;
  15896. FROM devices
  15897. WHERE last_seen &lt; DATE_PART('epoch', NOW() - INTERVAL '3 month') * 1000;
  15898. </code></pre>
  15899. <div style="break-before: page; page-break-before: always;"></div><p><em>This <a href="https://jacksonchen666.com/posts/2022-12-03/14-33-00/">blog post by Jackson Chen</a> (Dec 2022) explains how to use many of the tools listed on this page. There is also an <a href="https://levans.fr/shrink-synapse-database.html">earlier blog by Victor Berger</a> (June 2020), though this may be outdated in places.</em></p>
  15900. <h1 id="list-of-useful-tools-and-scripts-for-maintenance-synapse-database"><a class="header" href="#list-of-useful-tools-and-scripts-for-maintenance-synapse-database">List of useful tools and scripts for maintenance Synapse database:</a></h1>
  15901. <h2 id="purge-remote-media-api-1"><a class="header" href="#purge-remote-media-api-1"><a href="usage/administration/../../admin_api/media_admin_api.html#purge-remote-media-api">Purge Remote Media API</a></a></h2>
  15902. <p>The purge remote media API allows server admins to purge old cached remote media.</p>
  15903. <h2 id="purge-local-media-api"><a class="header" href="#purge-local-media-api"><a href="usage/administration/../../admin_api/media_admin_api.html#delete-local-media">Purge Local Media API</a></a></h2>
  15904. <p>This API deletes the <em>local</em> media from the disk of your own server.</p>
  15905. <h2 id="purge-history-api-1"><a class="header" href="#purge-history-api-1"><a href="usage/administration/../../admin_api/purge_history_api.html">Purge History API</a></a></h2>
  15906. <p>The purge history API allows server admins to purge historic events from their database, reclaiming disk space.</p>
  15907. <h2 id="synapse-compress-state"><a class="header" href="#synapse-compress-state"><a href="https://github.com/matrix-org/rust-synapse-compress-state">synapse-compress-state</a></a></h2>
  15908. <p>Tool for compressing (deduplicating) <code>state_groups_state</code> table.</p>
  15909. <h2 id="sql-for-analyzing-synapse-postgresql-database-stats"><a class="header" href="#sql-for-analyzing-synapse-postgresql-database-stats"><a href="usage/administration/useful_sql_for_admins.html">SQL for analyzing Synapse PostgreSQL database stats</a></a></h2>
  15910. <p>Some easy SQL that reports useful stats about your Synapse database.</p>
  15911. <div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-state-groups-work"><a class="header" href="#how-do-state-groups-work">How do State Groups work?</a></h1>
  15912. <p>As a general rule, I encourage people who want to understand the deepest darkest secrets of the database schema to drop by #synapse-dev:matrix.org and ask questions.</p>
  15913. <p>However, one question that comes up frequently is that of how &quot;state groups&quot; work, and why the <code>state_groups_state</code> table gets so big, so here's an attempt to answer that question.</p>
  15914. <p>We need to be able to relatively quickly calculate the state of a room at any point in that room's history. In other words, we need to know the state of the room at each event in that room. This is done as follows:</p>
  15915. <p>A sequence of events where the state is the same are grouped together into a <code>state_group</code>; the mapping is recorded in <code>event_to_state_groups</code>. (Technically speaking, since a state event usually changes the state in the room, we are recording the state of the room <em>after</em> the given event id: which is to say, to a handwavey simplification, the first event in a state group is normally a state event, and others in the same state group are normally non-state-events.)</p>
  15916. <p><code>state_groups</code> records, for each state group, the id of the room that we're looking at, and also the id of the first event in that group. (I'm not sure if that event id is used much in practice.) </p>
  15917. <p>Now, if we stored all the room state for each <code>state_group</code>, that would be a huge amount of data. Instead, for each state group, we normally store the difference between the state in that group and some other state group, and only occasionally (every 100 state changes or so) record the full state.</p>
  15918. <p>So, most state groups have an entry in <code>state_group_edges</code> (don't ask me why it's not a column in <code>state_groups</code>) which records the previous state group in the room, and <code>state_groups_state</code> records the differences in state since that previous state group.</p>
  15919. <p>A full state group just records the event id for each piece of state in the room at that point.</p>
  15920. <h2 id="known-bugs-with-state-groups"><a class="header" href="#known-bugs-with-state-groups">Known bugs with state groups</a></h2>
  15921. <p>There are various reasons that we can end up creating many more state groups than we need: see https://github.com/matrix-org/synapse/issues/3364 for more details.</p>
  15922. <h2 id="compression-tool"><a class="header" href="#compression-tool">Compression tool</a></h2>
  15923. <p>There is a tool at https://github.com/matrix-org/rust-synapse-compress-state which can compress the <code>state_groups_state</code> on a room by-room basis (essentially, it reduces the number of &quot;full&quot; state groups). This can result in dramatic reductions of the storage used.</p>
  15924. <div style="break-before: page; page-break-before: always;"></div><h1 id="request-log-format"><a class="header" href="#request-log-format">Request log format</a></h1>
  15925. <p>HTTP request logs are written by synapse (see <a href="https://github.com/matrix-org/synapse/tree/develop/synapse/http/site.py"><code>synapse/http/site.py</code></a> for details).</p>
  15926. <p>See the following for how to decode the dense data available from the default logging configuration.</p>
  15927. <pre><code>2020-10-01 12:00:00,000 - synapse.access.http.8008 - 311 - INFO - PUT-1000- 192.168.0.1 - 8008 - {another-matrix-server.com} Processed request: 0.100sec/-0.000sec (0.000sec, 0.000sec) (0.001sec/0.090sec/3) 11B !200 &quot;PUT /_matrix/federation/v1/send/1600000000000 HTTP/1.1&quot; &quot;Synapse/1.20.1&quot; [0 dbevts]
  15928. -AAAAAAAAAAAAAAAAAAAAA- -BBBBBBBBBBBBBBBBBBBBBB- -C- -DD- -EEEEEE- -FFFFFFFFF- -GG- -HHHHHHHHHHHHHHHHHHHHHHH- -IIIIII- -JJJJJJJ- -KKKKKK-, -LLLLLL- -MMMMMMM- -NNNNNN- O -P- -QQ- -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR- -SSSSSSSSSSSS- -TTTTTT-
  15929. </code></pre>
  15930. <table><thead><tr><th>Part</th><th>Explanation</th></tr></thead><tbody>
  15931. <tr><td>AAAA</td><td>Timestamp request was logged (not received)</td></tr>
  15932. <tr><td>BBBB</td><td>Logger name (<code>synapse.access.(http\|https).&lt;tag&gt;</code>, where 'tag' is defined in the <a href="usage/administration/../configuration/config_documentation.html#listeners"><code>listeners</code></a> config section, normally the port)</td></tr>
  15933. <tr><td>CCCC</td><td>Line number in code</td></tr>
  15934. <tr><td>DDDD</td><td>Log Level</td></tr>
  15935. <tr><td>EEEE</td><td>Request Identifier (This identifier is shared by related log lines)</td></tr>
  15936. <tr><td>FFFF</td><td>Source IP (Or X-Forwarded-For if enabled)</td></tr>
  15937. <tr><td>GGGG</td><td>Server Port</td></tr>
  15938. <tr><td>HHHH</td><td>Federated Server or Local User making request (blank if unauthenticated or not supplied).<br/>If this is of the form `@aaa:example.com</td></tr>
  15939. <tr><td>IIII</td><td>Total Time to process the request</td></tr>
  15940. <tr><td>JJJJ</td><td>Time to send response over network once generated (this may be negative if the socket is closed before the response is generated)</td></tr>
  15941. <tr><td>KKKK</td><td>Userland CPU time</td></tr>
  15942. <tr><td>LLLL</td><td>System CPU time</td></tr>
  15943. <tr><td>MMMM</td><td>Total time waiting for a free DB connection from the pool across all parallel DB work from this request</td></tr>
  15944. <tr><td>NNNN</td><td>Total time waiting for response to DB queries across all parallel DB work from this request</td></tr>
  15945. <tr><td>OOOO</td><td>Count of DB transactions performed</td></tr>
  15946. <tr><td>PPPP</td><td>Response body size</td></tr>
  15947. <tr><td>QQQQ</td><td>Response status code<br/>Suffixed with <code>!</code> if the socket was closed before the response was generated.<br/>A <code>499!</code> status code indicates that Synapse also cancelled request processing after the socket was closed.<br/></td></tr>
  15948. <tr><td>RRRR</td><td>Request</td></tr>
  15949. <tr><td>SSSS</td><td>User-agent</td></tr>
  15950. <tr><td>TTTT</td><td>Events fetched from DB to service this request (note that this does not include events fetched from the cache)</td></tr>
  15951. </tbody></table>
  15952. <p>MMMM / NNNN can be greater than IIII if there are multiple slow database queries
  15953. running in parallel.</p>
  15954. <p>Some actions can result in multiple identical http requests, which will return
  15955. the same data, but only the first request will report time/transactions in
  15956. <code>KKKK</code>/<code>LLLL</code>/<code>MMMM</code>/<code>NNNN</code>/<code>OOOO</code> - the others will be awaiting the first query to return a
  15957. response and will simultaneously return with the first request, but with very
  15958. small processing times.</p>
  15959. <div style="break-before: page; page-break-before: always;"></div><h2 id="admin-faq"><a class="header" href="#admin-faq">Admin FAQ</a></h2>
  15960. <h2 id="how-do-i-become-a-server-admin"><a class="header" href="#how-do-i-become-a-server-admin">How do I become a server admin?</a></h2>
  15961. <p>If your server already has an admin account you should use the
  15962. <a href="usage/administration/../../admin_api/user_admin_api.html#change-whether-a-user-is-a-server-administrator-or-not">User Admin API</a>
  15963. to promote other accounts to become admins.</p>
  15964. <p>If you don't have any admin accounts yet you won't be able to use the admin API,
  15965. so you'll have to edit the database manually. Manually editing the database is
  15966. generally not recommended so once you have an admin account: use the admin APIs
  15967. to make further changes.</p>
  15968. <pre><code class="language-sql">UPDATE users SET admin = 1 WHERE name = '@foo:bar.com';
  15969. </code></pre>
  15970. <h2 id="what-servers-are-my-server-talking-to"><a class="header" href="#what-servers-are-my-server-talking-to">What servers are my server talking to?</a></h2>
  15971. <p>Run this sql query on your db:</p>
  15972. <pre><code class="language-sql">SELECT * FROM destinations;
  15973. </code></pre>
  15974. <h2 id="what-servers-are-currently-participating-in-this-room"><a class="header" href="#what-servers-are-currently-participating-in-this-room">What servers are currently participating in this room?</a></h2>
  15975. <p>Run this sql query on your db:</p>
  15976. <pre><code class="language-sql">SELECT DISTINCT split_part(state_key, ':', 2)
  15977. FROM current_state_events
  15978. WHERE room_id = '!cURbafjkfsMDVwdRDQ:matrix.org' AND membership = 'join';
  15979. </code></pre>
  15980. <h2 id="what-users-are-registered-on-my-server"><a class="header" href="#what-users-are-registered-on-my-server">What users are registered on my server?</a></h2>
  15981. <pre><code class="language-sql">SELECT NAME from users;
  15982. </code></pre>
  15983. <h2 id="how-can-i-export-user-data"><a class="header" href="#how-can-i-export-user-data">How can I export user data?</a></h2>
  15984. <p>Synapse includes a Python command to export data for a specific user. It takes the homeserver
  15985. configuration file and the full Matrix ID of the user to export:</p>
  15986. <pre><code class="language-console">python -m synapse.app.admin_cmd -c &lt;config_file&gt; export-data &lt;user_id&gt; --output-directory &lt;directory_path&gt;
  15987. </code></pre>
  15988. <p>If you uses <a href="usage/administration/../../development/dependencies.html#managing-dependencies-with-poetry">Poetry</a>
  15989. to run Synapse:</p>
  15990. <pre><code class="language-console">poetry run python -m synapse.app.admin_cmd -c &lt;config_file&gt; export-data &lt;user_id&gt; --output-directory &lt;directory_path&gt;
  15991. </code></pre>
  15992. <p>The directory to store the export data in can be customised with the
  15993. <code>--output-directory</code> parameter; ensure that the provided directory is
  15994. empty. If this parameter is not provided, Synapse defaults to creating
  15995. a temporary directory (which starts with &quot;synapse-exfiltrate&quot;) in <code>/tmp</code>,
  15996. <code>/var/tmp</code>, or <code>/usr/tmp</code>, in that order.</p>
  15997. <p>The exported data has the following layout:</p>
  15998. <pre><code>output-directory
  15999. ├───rooms
  16000. │ └───&lt;room_id&gt;
  16001. │ ├───events
  16002. │ ├───state
  16003. │ ├───invite_state
  16004. │ └───knock_state
  16005. ├───user_data
  16006. │ ├───account_data
  16007. │ │ ├───global
  16008. │ │ └───&lt;room_id&gt;
  16009. │ ├───connections
  16010. │ ├───devices
  16011. │ └───profile
  16012. └───media_ids
  16013. └───&lt;media_id&gt;
  16014. </code></pre>
  16015. <p>The <code>media_ids</code> folder contains only the metadata of the media uploaded by the user.
  16016. It does not contain the media itself.
  16017. Furthermore, only the <code>media_ids</code> that Synapse manages itself are exported.
  16018. If another media repository (e.g. <a href="https://github.com/turt2live/matrix-media-repo">matrix-media-repo</a>)
  16019. is used, the data must be exported separately.</p>
  16020. <p>With the <code>media_ids</code> the media files can be downloaded.
  16021. Media that have been sent in encrypted rooms are only retrieved in encrypted form.
  16022. The following script can help with download the media files:</p>
  16023. <pre><code class="language-bash">#!/usr/bin/env bash
  16024. # Parameters
  16025. #
  16026. # source_directory: Directory which contains the export with the media_ids.
  16027. # target_directory: Directory into which all files are to be downloaded.
  16028. # repository_url: Address of the media repository resp. media worker.
  16029. # serverName: Name of the server (`server_name` from homeserver.yaml).
  16030. #
  16031. # Example:
  16032. # ./download_media.sh /tmp/export_data/media_ids/ /tmp/export_data/media_files/ http://localhost:8008 matrix.example.com
  16033. source_directory=$1
  16034. target_directory=$2
  16035. repository_url=$3
  16036. serverName=$4
  16037. mkdir -p $target_directory
  16038. for file in $source_directory/*; do
  16039. filename=$(basename ${file})
  16040. url=$repository_url/_matrix/media/v3/download/$serverName/$filename
  16041. echo &quot;Downloading $filename - $url&quot;
  16042. if ! wget -o /dev/null -P $target_directory $url; then
  16043. echo &quot;Could not download $filename&quot;
  16044. fi
  16045. done
  16046. </code></pre>
  16047. <h2 id="manually-resetting-passwords"><a class="header" href="#manually-resetting-passwords">Manually resetting passwords</a></h2>
  16048. <p>Users can reset their password through their client. Alternatively, a server admin
  16049. can reset a user's password using the <a href="usage/administration/../../admin_api/user_admin_api.html#reset-password">admin API</a>.</p>
  16050. <h2 id="i-have-a-problem-with-my-server-can-i-just-delete-my-database-and-start-again"><a class="header" href="#i-have-a-problem-with-my-server-can-i-just-delete-my-database-and-start-again">I have a problem with my server. Can I just delete my database and start again?</a></h2>
  16051. <p>Deleting your database is unlikely to make anything better.</p>
  16052. <p>It's easy to make the mistake of thinking that you can start again from a clean
  16053. slate by dropping your database, but things don't work like that in a federated
  16054. network: lots of other servers have information about your server.</p>
  16055. <p>For example: other servers might think that you are in a room, your server will
  16056. think that you are not, and you'll probably be unable to interact with that room
  16057. in a sensible way ever again.</p>
  16058. <p>In general, there are better solutions to any problem than dropping the database.
  16059. Come and seek help in https://matrix.to/#/#synapse:matrix.org.</p>
  16060. <p>There are two exceptions when it might be sensible to delete your database and start again:</p>
  16061. <ul>
  16062. <li>You have <em>never</em> joined any rooms which are federated with other servers. For
  16063. instance, a local deployment which the outside world can't talk to.</li>
  16064. <li>You are changing the <code>server_name</code> in the homeserver configuration. In effect
  16065. this makes your server a completely new one from the point of view of the network,
  16066. so in this case it makes sense to start with a clean database.
  16067. (In both cases you probably also want to clear out the media_store.)</li>
  16068. </ul>
  16069. <h2 id="ive-stuffed-up-access-to-my-room-how-can-i-delete-it-to-free-up-the-alias"><a class="header" href="#ive-stuffed-up-access-to-my-room-how-can-i-delete-it-to-free-up-the-alias">I've stuffed up access to my room, how can I delete it to free up the alias?</a></h2>
  16070. <p>Using the following curl command:</p>
  16071. <pre><code class="language-console">curl -H 'Authorization: Bearer &lt;access-token&gt;' -X DELETE https://matrix.org/_matrix/client/r0/directory/room/&lt;room-alias&gt;
  16072. </code></pre>
  16073. <p><code>&lt;access-token&gt;</code> - can be obtained in riot by looking in the riot settings, down the bottom is:
  16074. Access Token:&lt;click to reveal&gt;</p>
  16075. <p><code>&lt;room-alias&gt;</code> - the room alias, eg. #my_room:matrix.org this possibly needs to be URL encoded also, for example %23my_room%3Amatrix.org</p>
  16076. <h2 id="how-can-i-find-the-lines-corresponding-to-a-given-http-request-in-my-homeserver-log"><a class="header" href="#how-can-i-find-the-lines-corresponding-to-a-given-http-request-in-my-homeserver-log">How can I find the lines corresponding to a given HTTP request in my homeserver log?</a></h2>
  16077. <p>Synapse tags each log line according to the HTTP request it is processing. When
  16078. it finishes processing each request, it logs a line containing the words
  16079. <code>Processed request: </code>. For example:</p>
  16080. <pre><code>2019-02-14 22:35:08,196 - synapse.access.http.8008 - 302 - INFO - GET-37 - ::1 - 8008 - {@richvdh:localhost} Processed request: 0.173sec/0.001sec (0.002sec, 0.000sec) (0.027sec/0.026sec/2) 687B 200 &quot;GET /_matrix/client/r0/sync HTTP/1.1&quot; &quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36&quot; [0 dbevts]&quot;
  16081. </code></pre>
  16082. <p>Here we can see that the request has been tagged with <code>GET-37</code>. (The tag depends
  16083. on the method of the HTTP request, so might start with <code>GET-</code>, <code>PUT-</code>, <code>POST-</code>,
  16084. <code>OPTIONS-</code> or <code>DELETE-</code>.) So to find all lines corresponding to this request, we can do:</p>
  16085. <pre><code class="language-console">grep 'GET-37' homeserver.log
  16086. </code></pre>
  16087. <p>If you want to paste that output into a github issue or matrix room, please
  16088. remember to surround it with triple-backticks (```) to make it legible
  16089. (see <a href="https://help.github.com/en/articles/basic-writing-and-formatting-syntax#quoting-code">quoting code</a>).</p>
  16090. <h2 id="what-do-all-those-fields-in-the-processed-line-mean"><a class="header" href="#what-do-all-those-fields-in-the-processed-line-mean">What do all those fields in the 'Processed' line mean?</a></h2>
  16091. <p>See <a href="usage/administration/request_log.html">Request log format</a>.</p>
  16092. <h2 id="what-are-the-biggest-rooms-on-my-server"><a class="header" href="#what-are-the-biggest-rooms-on-my-server">What are the biggest rooms on my server?</a></h2>
  16093. <pre><code class="language-sql">SELECT s.canonical_alias, g.room_id, count(*) AS num_rows
  16094. FROM
  16095. state_groups_state AS g,
  16096. room_stats_state AS s
  16097. WHERE g.room_id = s.room_id
  16098. GROUP BY s.canonical_alias, g.room_id
  16099. ORDER BY num_rows desc
  16100. LIMIT 10;
  16101. </code></pre>
  16102. <p>You can also use the <a href="usage/administration/../../admin_api/rooms.html#list-room-api">List Room API</a>
  16103. and <code>order_by</code> <code>state_events</code>.</p>
  16104. <h2 id="people-cant-accept-room-invitations-from-me"><a class="header" href="#people-cant-accept-room-invitations-from-me">People can't accept room invitations from me</a></h2>
  16105. <p>The typical failure mode here is that you send an invitation to someone
  16106. to join a room or direct chat, but when they go to accept it, they get an
  16107. error (typically along the lines of &quot;Invalid signature&quot;). They might see
  16108. something like the following in their logs:</p>
  16109. <pre><code>2019-09-11 19:32:04,271 - synapse.federation.transport.server - 288 - WARNING - GET-11752 - authenticate_request failed: 401: Invalid signature for server &lt;server&gt; with key ed25519:a_EqML: Unable to verify signature for &lt;server&gt;
  16110. </code></pre>
  16111. <p>This is normally caused by a misconfiguration in your reverse-proxy. See <a href="usage/administration/../../reverse_proxy.html">the reverse proxy docs</a> and double-check that your settings are correct.</p>
  16112. <h2 id="help-synapse-is-slow-and-eats-all-my-ramcpu"><a class="header" href="#help-synapse-is-slow-and-eats-all-my-ramcpu">Help!! Synapse is slow and eats all my RAM/CPU!</a></h2>
  16113. <p>First, ensure you are running the latest version of Synapse, using Python 3
  16114. with a <a href="usage/administration/../../postgres.html">PostgreSQL database</a>.</p>
  16115. <p>Synapse's architecture is quite RAM hungry currently - we deliberately
  16116. cache a lot of recent room data and metadata in RAM in order to speed up
  16117. common requests. We'll improve this in the future, but for now the easiest
  16118. way to either reduce the RAM usage (at the risk of slowing things down)
  16119. is to set the almost-undocumented <code>SYNAPSE_CACHE_FACTOR</code> environment
  16120. variable. The default is 0.5, which can be decreased to reduce RAM usage
  16121. in memory constrained environments, or increased if performance starts to
  16122. degrade.</p>
  16123. <p>However, degraded performance due to a low cache factor, common on
  16124. machines with slow disks, often leads to explosions in memory use due
  16125. backlogged requests. In this case, reducing the cache factor will make
  16126. things worse. Instead, try increasing it drastically. 2.0 is a good
  16127. starting value.</p>
  16128. <p>Using <a href="https://jemalloc.net">libjemalloc</a> can also yield a significant
  16129. improvement in overall memory use, and especially in terms of giving back
  16130. RAM to the OS. To use it, the library must simply be put in the
  16131. LD_PRELOAD environment variable when launching Synapse. On Debian, this
  16132. can be done by installing the <code>libjemalloc1</code> package and adding this
  16133. line to <code>/etc/default/matrix-synapse</code>:</p>
  16134. <pre><code>LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.1
  16135. </code></pre>
  16136. <p>This made a significant difference on Python 2.7 - it's unclear how
  16137. much of an improvement it provides on Python 3.x.</p>
  16138. <p>If you're encountering high CPU use by the Synapse process itself, you
  16139. may be affected by a bug with presence tracking that leads to a
  16140. massive excess of outgoing federation requests (see <a href="https://github.com/matrix-org/synapse/issues/3971">discussion</a>). If metrics
  16141. indicate that your server is also issuing far more outgoing federation
  16142. requests than can be accounted for by your users' activity, this is a
  16143. likely cause. The misbehavior can be worked around by disabling presence
  16144. in the Synapse config file: <a href="usage/administration/../configuration/config_documentation.html#presence">see here</a>.</p>
  16145. <h2 id="running-out-of-file-handles"><a class="header" href="#running-out-of-file-handles">Running out of File Handles</a></h2>
  16146. <p>If Synapse runs out of file handles, it typically fails badly - live-locking
  16147. at 100% CPU, and/or failing to accept new TCP connections (blocking the
  16148. connecting client). Matrix currently can legitimately use a lot of file handles,
  16149. thanks to busy rooms like <code>#matrix:matrix.org</code> containing hundreds of participating
  16150. servers. The first time a server talks in a room it will try to connect
  16151. simultaneously to all participating servers, which could exhaust the available
  16152. file descriptors between DNS queries &amp; HTTPS sockets, especially if DNS is slow
  16153. to respond. (We need to improve the routing algorithm used to be better than
  16154. full mesh, but as of March 2019 this hasn't happened yet).</p>
  16155. <p>If you hit this failure mode, we recommend increasing the maximum number of
  16156. open file handles to be at least 4096 (assuming a default of 1024 or 256).
  16157. This is typically done by editing <code>/etc/security/limits.conf</code></p>
  16158. <p>Separately, Synapse may leak file handles if inbound HTTP requests get stuck
  16159. during processing - e.g. blocked behind a lock or talking to a remote server etc.
  16160. This is best diagnosed by matching up the 'Received request' and 'Processed request'
  16161. log lines and looking for any 'Processed request' lines which take more than
  16162. a few seconds to execute. Please let us know at <a href="https://matrix.to/#/#synapse-dev:matrix.org"><code>#synapse:matrix.org</code></a> if
  16163. you see this failure mode so we can help debug it, however.</p>
  16164. <div style="break-before: page; page-break-before: always;"></div><h1 id="contributing"><a class="header" href="#contributing">Contributing</a></h1>
  16165. <p>This document aims to get you started with contributing to Synapse!</p>
  16166. <h1 id="1-who-can-contribute-to-synapse"><a class="header" href="#1-who-can-contribute-to-synapse">1. Who can contribute to Synapse?</a></h1>
  16167. <p>Everyone is welcome to contribute code to <a href="https://github.com/matrix-org">matrix.org
  16168. projects</a>, provided that they are willing to
  16169. license their contributions under the same license as the project itself. We
  16170. follow a simple 'inbound=outbound' model for contributions: the act of
  16171. submitting an 'inbound' contribution means that the contributor agrees to
  16172. license the code under the same terms as the project's overall 'outbound'
  16173. license - in our case, this is almost always Apache Software License v2 (see
  16174. <a href="https://github.com/matrix-org/synapse/blob/develop/LICENSE">LICENSE</a>).</p>
  16175. <h1 id="2-what-do-i-need"><a class="header" href="#2-what-do-i-need">2. What do I need?</a></h1>
  16176. <p>If you are running Windows, the Windows Subsystem for Linux (WSL) is strongly
  16177. recommended for development. More information about WSL can be found at
  16178. <a href="https://docs.microsoft.com/en-us/windows/wsl/install">https://docs.microsoft.com/en-us/windows/wsl/install</a>. Running Synapse natively
  16179. on Windows is not officially supported.</p>
  16180. <p>The code of Synapse is written in Python 3. To do pretty much anything, you'll need <a href="https://www.python.org/downloads/">a recent version of Python 3</a>. Your Python also needs support for <a href="https://docs.python.org/3/library/venv.html">virtual environments</a>. This is usually built-in, but some Linux distributions like Debian and Ubuntu split it out into its own package. Running <code>sudo apt install python3-venv</code> should be enough.</p>
  16181. <p>A recent version of the Rust compiler is needed to build the native modules. The
  16182. easiest way of installing the latest version is to use <a href="https://rustup.rs/">rustup</a>.</p>
  16183. <p>Synapse can connect to PostgreSQL via the <a href="https://pypi.org/project/psycopg2/">psycopg2</a> Python library. Building this library from source requires access to PostgreSQL's C header files. On Debian or Ubuntu Linux, these can be installed with <code>sudo apt install libpq-dev</code>.</p>
  16184. <p>Synapse has an optional, improved user search with better Unicode support. For that you need the development package of <code>libicu</code>. On Debian or Ubuntu Linux, this can be installed with <code>sudo apt install libicu-dev</code>.</p>
  16185. <p>The source code of Synapse is hosted on GitHub. You will also need <a href="https://github.com/git-guides/install-git">a recent version of git</a>.</p>
  16186. <p>For some tests, you will need <a href="https://docs.docker.com/get-docker/">a recent version of Docker</a>.</p>
  16187. <h1 id="3-get-the-source"><a class="header" href="#3-get-the-source">3. Get the source.</a></h1>
  16188. <p>The preferred and easiest way to contribute changes is to fork the relevant
  16189. project on GitHub, and then <a href="https://help.github.com/articles/using-pull-requests/">create a pull request</a> to ask us to pull your
  16190. changes into our repo.</p>
  16191. <p>Please base your changes on the <code>develop</code> branch.</p>
  16192. <pre><code class="language-sh">git clone git@github.com:YOUR_GITHUB_USER_NAME/synapse.git
  16193. git checkout develop
  16194. </code></pre>
  16195. <p>If you need help getting started with git, this is beyond the scope of the document, but you
  16196. can find many good git tutorials on the web.</p>
  16197. <h1 id="4-install-the-dependencies"><a class="header" href="#4-install-the-dependencies">4. Install the dependencies</a></h1>
  16198. <p>Before installing the Python dependencies, make sure you have installed a recent version
  16199. of Rust (see the &quot;What do I need?&quot; section above). The easiest way of installing the
  16200. latest version is to use <a href="https://rustup.rs/">rustup</a>.</p>
  16201. <p>Synapse uses the <a href="https://python-poetry.org/">poetry</a> project to manage its dependencies
  16202. and development environment. Once you have installed Python 3 and added the
  16203. source, you should install <code>poetry</code>.
  16204. Of their installation methods, we recommend
  16205. <a href="https://python-poetry.org/docs/#installing-with-pipx">installing <code>poetry</code> using <code>pipx</code></a>,</p>
  16206. <pre><code class="language-shell">pip install --user pipx
  16207. pipx install poetry==1.5.1 # Problems with Poetry 1.6, see https://github.com/matrix-org/synapse/issues/16147
  16208. </code></pre>
  16209. <p>but see poetry's <a href="https://python-poetry.org/docs/#installation">installation instructions</a>
  16210. for other installation methods.</p>
  16211. <p>Developing Synapse requires Poetry version 1.3.2 or later.</p>
  16212. <p>Next, open a terminal and install dependencies as follows:</p>
  16213. <pre><code class="language-sh">cd path/where/you/have/cloned/the/repository
  16214. poetry install --extras all
  16215. </code></pre>
  16216. <p>This will install the runtime and developer dependencies for the project. Be sure to check
  16217. that the <code>poetry install</code> step completed cleanly.</p>
  16218. <h2 id="running-synapse-via-poetry"><a class="header" href="#running-synapse-via-poetry">Running Synapse via poetry</a></h2>
  16219. <p>To start a local instance of Synapse in the locked poetry environment, create a config file:</p>
  16220. <pre><code class="language-sh">cp docs/sample_config.yaml homeserver.yaml
  16221. cp docs/sample_log_config.yaml log_config.yaml
  16222. </code></pre>
  16223. <p>Now edit <code>homeserver.yaml</code>, things you might want to change include:</p>
  16224. <ul>
  16225. <li>Set a <code>server_name</code></li>
  16226. <li>Adjusting paths to be correct for your system like the <code>log_config</code> to point to the log config you just copied</li>
  16227. <li>Using a <a href="https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database">PostgreSQL database instead of SQLite</a></li>
  16228. <li>Adding a <a href="https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret"><code>registration_shared_secret</code></a> so you can use <a href="https://matrix-org.github.io/synapse/latest/setup/installation.html#registering-a-user"><code>register_new_matrix_user</code> command</a>.</li>
  16229. </ul>
  16230. <p>And then run Synapse with the following command:</p>
  16231. <pre><code class="language-sh">poetry run python -m synapse.app.homeserver -c homeserver.yaml
  16232. </code></pre>
  16233. <p>If you get an error like the following:</p>
  16234. <pre><code>importlib.metadata.PackageNotFoundError: matrix-synapse
  16235. </code></pre>
  16236. <p>this probably indicates that the <code>poetry install</code> step did not complete cleanly - go back and
  16237. resolve any issues and re-run until successful.</p>
  16238. <h1 id="5-get-in-touch"><a class="header" href="#5-get-in-touch">5. Get in touch.</a></h1>
  16239. <p>Join our developer community on Matrix: <a href="https://matrix.to/#/#synapse-dev:matrix.org">#synapse-dev:matrix.org</a>!</p>
  16240. <h1 id="6-pick-an-issue"><a class="header" href="#6-pick-an-issue">6. Pick an issue.</a></h1>
  16241. <p>Fix your favorite problem or perhaps find a <a href="https://github.com/matrix-org/synapse/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+First+Issue%22">Good First Issue</a>
  16242. to work on.</p>
  16243. <h1 id="7-turn-coffee-into-code-and-documentation"><a class="header" href="#7-turn-coffee-into-code-and-documentation">7. Turn coffee into code and documentation!</a></h1>
  16244. <p>There is a growing amount of documentation located in the
  16245. <a href="https://github.com/matrix-org/synapse/tree/develop/docs"><code>docs</code></a>
  16246. directory, with a rendered version <a href="https://matrix-org.github.io/synapse">available online</a>.
  16247. This documentation is intended primarily for sysadmins running their
  16248. own Synapse instance, as well as developers interacting externally with
  16249. Synapse.
  16250. <a href="https://github.com/matrix-org/synapse/tree/develop/docs/development"><code>docs/development</code></a>
  16251. exists primarily to house documentation for
  16252. Synapse developers.
  16253. <a href="https://github.com/matrix-org/synapse/tree/develop/docs/admin_api"><code>docs/admin_api</code></a> houses documentation
  16254. regarding Synapse's Admin API, which is used mostly by sysadmins and external
  16255. service developers.</p>
  16256. <p>Synapse's code style is documented <a href="development/../code_style.html">here</a>. Please follow
  16257. it, including the conventions for <a href="development/../code_style.html#configuration-code-and-documentation-format">configuration
  16258. options and documentation</a>.</p>
  16259. <p>We welcome improvements and additions to our documentation itself! When
  16260. writing new pages, please
  16261. <a href="https://github.com/matrix-org/synapse/tree/develop/docs#adding-to-the-documentation">build <code>docs</code> to a book</a>
  16262. to check that your contributions render correctly. The docs are written in
  16263. <a href="https://guides.github.com/features/mastering-markdown/">GitHub-Flavoured Markdown</a>.</p>
  16264. <p>Some documentation also exists in <a href="https://github.com/matrix-org/synapse/wiki">Synapse's GitHub
  16265. Wiki</a>, although this is primarily
  16266. contributed to by community authors.</p>
  16267. <p>When changes are made to any Rust code then you must call either <code>poetry install</code>
  16268. or <code>maturin develop</code> (if installed) to rebuild the Rust code. Using <a href="https://github.com/PyO3/maturin"><code>maturin</code></a>
  16269. is quicker than <code>poetry install</code>, so is recommended when making frequent
  16270. changes to the Rust code.</p>
  16271. <h1 id="8-test-test-test"><a class="header" href="#8-test-test-test">8. Test, test, test!</a></h1>
  16272. <p><a name="test-test-test" id="test-test-test"></a></p>
  16273. <p>While you're developing and before submitting a patch, you'll
  16274. want to test your code.</p>
  16275. <h2 id="run-the-linters"><a class="header" href="#run-the-linters">Run the linters.</a></h2>
  16276. <p>The linters look at your code and do two things:</p>
  16277. <ul>
  16278. <li>ensure that your code follows the coding style adopted by the project;</li>
  16279. <li>catch a number of errors in your code.</li>
  16280. </ul>
  16281. <p>The linter takes no time at all to run as soon as you've <a href="development/contributing_guide.html#4-install-the-dependencies">downloaded the dependencies</a>.</p>
  16282. <pre><code class="language-sh">poetry run ./scripts-dev/lint.sh
  16283. </code></pre>
  16284. <p>Note that this script <em>will modify your files</em> to fix styling errors.
  16285. Make sure that you have saved all your files.</p>
  16286. <p>If you wish to restrict the linters to only the files changed since the last commit
  16287. (much faster!), you can instead run:</p>
  16288. <pre><code class="language-sh">poetry run ./scripts-dev/lint.sh -d
  16289. </code></pre>
  16290. <p>Or if you know exactly which files you wish to lint, you can instead run:</p>
  16291. <pre><code class="language-sh">poetry run ./scripts-dev/lint.sh path/to/file1.py path/to/file2.py path/to/folder
  16292. </code></pre>
  16293. <h2 id="run-the-unit-tests-twisted-trial"><a class="header" href="#run-the-unit-tests-twisted-trial">Run the unit tests (Twisted trial).</a></h2>
  16294. <p>The unit tests run parts of Synapse, including your changes, to see if anything
  16295. was broken. They are slower than the linters but will typically catch more errors.</p>
  16296. <pre><code class="language-sh">poetry run trial tests
  16297. </code></pre>
  16298. <p>You can run unit tests in parallel by specifying <code>-jX</code> argument to <code>trial</code> where <code>X</code> is the number of parallel runners you want. To use 4 cpu cores, you would run them like:</p>
  16299. <pre><code class="language-sh">poetry run trial -j4 tests
  16300. </code></pre>
  16301. <p>If you wish to only run <em>some</em> unit tests, you may specify
  16302. another module instead of <code>tests</code> - or a test class or a method:</p>
  16303. <pre><code class="language-sh">poetry run trial tests.rest.admin.test_room tests.handlers.test_admin.ExfiltrateData.test_invite
  16304. </code></pre>
  16305. <p>If your tests fail, you may wish to look at the logs (the default log level is <code>ERROR</code>):</p>
  16306. <pre><code class="language-sh">less _trial_temp/test.log
  16307. </code></pre>
  16308. <p>To increase the log level for the tests, set <code>SYNAPSE_TEST_LOG_LEVEL</code>:</p>
  16309. <pre><code class="language-sh">SYNAPSE_TEST_LOG_LEVEL=DEBUG poetry run trial tests
  16310. </code></pre>
  16311. <p>By default, tests will use an in-memory SQLite database for test data. For additional
  16312. help with debugging, one can use an on-disk SQLite database file instead, in order to
  16313. review database state during and after running tests. This can be done by setting
  16314. the <code>SYNAPSE_TEST_PERSIST_SQLITE_DB</code> environment variable. Doing so will cause the
  16315. database state to be stored in a file named <code>test.db</code> under the trial process'
  16316. working directory. Typically, this ends up being <code>_trial_temp/test.db</code>. For example:</p>
  16317. <pre><code class="language-sh">SYNAPSE_TEST_PERSIST_SQLITE_DB=1 poetry run trial tests
  16318. </code></pre>
  16319. <p>The database file can then be inspected with:</p>
  16320. <pre><code class="language-sh">sqlite3 _trial_temp/test.db
  16321. </code></pre>
  16322. <p>Note that the database file is cleared at the beginning of each test run. Thus it
  16323. will always only contain the data generated by the <em>last run test</em>. Though generally
  16324. when debugging, one is only running a single test anyway.</p>
  16325. <h3 id="running-tests-under-postgresql"><a class="header" href="#running-tests-under-postgresql">Running tests under PostgreSQL</a></h3>
  16326. <p>Invoking <code>trial</code> as above will use an in-memory SQLite database. This is great for
  16327. quick development and testing. However, we recommend using a PostgreSQL database
  16328. in production (and indeed, we have some code paths specific to each database).
  16329. This means that we need to run our unit tests against PostgreSQL too. Our CI does
  16330. this automatically for pull requests and release candidates, but it's sometimes
  16331. useful to reproduce this locally.</p>
  16332. <h4 id="using-docker"><a class="header" href="#using-docker">Using Docker</a></h4>
  16333. <p>The easiest way to do so is to run Postgres via a docker container. In one
  16334. terminal:</p>
  16335. <pre><code class="language-shell">docker run --rm -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_USER=postgres -e POSTGRES_DB=postgres -p 5432:5432 postgres:14
  16336. </code></pre>
  16337. <p>If you see an error like</p>
  16338. <pre><code>docker: Error response from daemon: driver failed programming external connectivity on endpoint nice_ride (b57bbe2e251b70015518d00c9981e8cb8346b5c785250341a6c53e3c899875f1): Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in use.
  16339. </code></pre>
  16340. <p>then something is already bound to port 5432. You're probably already running postgres locally.</p>
  16341. <p>Once you have a postgres server running, invoke <code>trial</code> in a second terminal:</p>
  16342. <pre><code class="language-shell">SYNAPSE_POSTGRES=1 SYNAPSE_POSTGRES_HOST=127.0.0.1 SYNAPSE_POSTGRES_USER=postgres SYNAPSE_POSTGRES_PASSWORD=mysecretpassword poetry run trial tests
  16343. </code></pre>
  16344. <h4 id="using-an-existing-postgres-installation"><a class="header" href="#using-an-existing-postgres-installation">Using an existing Postgres installation</a></h4>
  16345. <p>If you have postgres already installed on your system, you can run <code>trial</code> with the
  16346. following environment variables matching your configuration:</p>
  16347. <ul>
  16348. <li><code>SYNAPSE_POSTGRES</code> to anything nonempty</li>
  16349. <li><code>SYNAPSE_POSTGRES_HOST</code> (optional if it's the default: UNIX socket)</li>
  16350. <li><code>SYNAPSE_POSTGRES_PORT</code> (optional if it's the default: 5432)</li>
  16351. <li><code>SYNAPSE_POSTGRES_USER</code> (optional if using a UNIX socket)</li>
  16352. <li><code>SYNAPSE_POSTGRES_PASSWORD</code> (optional if using a UNIX socket)</li>
  16353. </ul>
  16354. <p>For example:</p>
  16355. <pre><code class="language-shell">export SYNAPSE_POSTGRES=1
  16356. export SYNAPSE_POSTGRES_HOST=localhost
  16357. export SYNAPSE_POSTGRES_USER=postgres
  16358. export SYNAPSE_POSTGRES_PASSWORD=mydevenvpassword
  16359. trial
  16360. </code></pre>
  16361. <p>You don't need to specify the host, user, port or password if your Postgres
  16362. server is set to authenticate you over the UNIX socket (i.e. if the <code>psql</code> command
  16363. works without further arguments).</p>
  16364. <p>Your Postgres account needs to be able to create databases; see the postgres
  16365. docs for <a href="https://www.postgresql.org/docs/current/sql-alterrole.html"><code>ALTER ROLE</code></a>.</p>
  16366. <h2 id="run-the-integration-tests-sytest"><a class="header" href="#run-the-integration-tests-sytest">Run the integration tests (<a href="https://github.com/matrix-org/sytest">Sytest</a>).</a></h2>
  16367. <p>The integration tests are a more comprehensive suite of tests. They
  16368. run a full version of Synapse, including your changes, to check if
  16369. anything was broken. They are slower than the unit tests but will
  16370. typically catch more errors.</p>
  16371. <p>The following command will let you run the integration test with the most common
  16372. configuration:</p>
  16373. <pre><code class="language-sh">$ docker run --rm -it -v /path/where/you/have/cloned/the/repository\:/src:ro -v /path/to/where/you/want/logs\:/logs matrixdotorg/sytest-synapse:focal
  16374. </code></pre>
  16375. <p>(Note that the paths must be full paths! You could also write <code>$(realpath relative/path)</code> if needed.)</p>
  16376. <p>This configuration should generally cover your needs.</p>
  16377. <ul>
  16378. <li>To run with Postgres, supply the <code>-e POSTGRES=1 -e MULTI_POSTGRES=1</code> environment flags.</li>
  16379. <li>To run with Synapse in worker mode, supply the <code>-e WORKERS=1 -e REDIS=1</code> environment flags (in addition to the Postgres flags).</li>
  16380. </ul>
  16381. <p>For more details about other configurations, see the <a href="https://github.com/matrix-org/sytest/blob/develop/docker/README.md">Docker-specific documentation in the SyTest repo</a>.</p>
  16382. <h2 id="run-the-integration-tests-complement"><a class="header" href="#run-the-integration-tests-complement">Run the integration tests (<a href="https://github.com/matrix-org/complement">Complement</a>).</a></h2>
  16383. <p><a href="https://github.com/matrix-org/complement">Complement</a> is a suite of black box tests that can be run on any homeserver implementation. It can also be thought of as end-to-end (e2e) tests.</p>
  16384. <p>It's often nice to develop on Synapse and write Complement tests at the same time.
  16385. Here is how to run your local Synapse checkout against your local Complement checkout.</p>
  16386. <p>(checkout <a href="https://github.com/matrix-org/complement"><code>complement</code></a> alongside your <code>synapse</code> checkout)</p>
  16387. <pre><code class="language-sh">COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh
  16388. </code></pre>
  16389. <p>To run a specific test file, you can pass the test name at the end of the command. The name passed comes from the naming structure in your Complement tests. If you're unsure of the name, you can do a full run and copy it from the test output:</p>
  16390. <pre><code class="language-sh">COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages
  16391. </code></pre>
  16392. <p>To run a specific test, you can specify the whole name structure:</p>
  16393. <pre><code class="language-sh">COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages/parallel/Historical_events_resolve_in_the_correct_order
  16394. </code></pre>
  16395. <p>The above will run a monolithic (single-process) Synapse with SQLite as the database. For other configurations, try:</p>
  16396. <ul>
  16397. <li>Passing <code>POSTGRES=1</code> as an environment variable to use the Postgres database instead.</li>
  16398. <li>Passing <code>WORKERS=1</code> as an environment variable to use a workerised setup instead. This option implies the use of Postgres.
  16399. <ul>
  16400. <li>If setting <code>WORKERS=1</code>, optionally set <code>WORKER_TYPES=</code> to declare which worker
  16401. types you wish to test. A simple comma-delimited string containing the worker types
  16402. defined from the <code>WORKERS_CONFIG</code> template in
  16403. <a href="https://github.com/matrix-org/synapse/blob/develop/docker/configure_workers_and_start.py#L54">here</a>.
  16404. A safe example would be <code>WORKER_TYPES=&quot;federation_inbound, federation_sender, synchrotron&quot;</code>.
  16405. See the <a href="development/../workers.html">worker documentation</a> for additional information on workers.</li>
  16406. </ul>
  16407. </li>
  16408. <li>Passing <code>ASYNCIO_REACTOR=1</code> as an environment variable to use the Twisted asyncio reactor instead of the default one.</li>
  16409. <li>Passing <code>PODMAN=1</code> will use the <a href="https://podman.io/">podman</a> container runtime, instead of docker.</li>
  16410. <li>Passing <code>UNIX_SOCKETS=1</code> will utilise Unix socket functionality for Synapse, Redis, and Postgres(when applicable).</li>
  16411. </ul>
  16412. <p>To increase the log level for the tests, set <code>SYNAPSE_TEST_LOG_LEVEL</code>, e.g:</p>
  16413. <pre><code class="language-sh">SYNAPSE_TEST_LOG_LEVEL=DEBUG COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages
  16414. </code></pre>
  16415. <h3 id="prettier-formatting-with-gotestfmt"><a class="header" href="#prettier-formatting-with-gotestfmt">Prettier formatting with <code>gotestfmt</code></a></h3>
  16416. <p>If you want to format the output of the tests the same way as it looks in CI,
  16417. install <a href="https://github.com/GoTestTools/gotestfmt">gotestfmt</a>.</p>
  16418. <p>You can then use this incantation to format the tests appropriately:</p>
  16419. <pre><code class="language-sh">COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -json | gotestfmt -hide successful-tests
  16420. </code></pre>
  16421. <p>(Remove <code>-hide successful-tests</code> if you don't want to hide successful tests.)</p>
  16422. <h3 id="access-database-for-homeserver-after-complement-test-runs"><a class="header" href="#access-database-for-homeserver-after-complement-test-runs">Access database for homeserver after Complement test runs.</a></h3>
  16423. <p>If you're curious what the database looks like after you run some tests, here are some steps to get you going in Synapse:</p>
  16424. <ol>
  16425. <li>In your Complement test comment out <code>defer deployment.Destroy(t)</code> and replace with <code>defer time.Sleep(2 * time.Hour)</code> to keep the homeserver running after the tests complete</li>
  16426. <li>Start the Complement tests</li>
  16427. <li>Find the name of the container, <code>docker ps -f name=complement_</code> (this will filter for just the Compelement related Docker containers)</li>
  16428. <li>Access the container replacing the name with what you found in the previous step: <code>docker exec -it complement_1_hs_with_application_service.hs1_2 /bin/bash</code></li>
  16429. <li>Install sqlite (database driver), <code>apt-get update &amp;&amp; apt-get install -y sqlite3</code></li>
  16430. <li>Then run <code>sqlite3</code> and open the database <code>.open /conf/homeserver.db</code> (this db path comes from the Synapse homeserver.yaml)</li>
  16431. </ol>
  16432. <h1 id="9-submit-your-patch"><a class="header" href="#9-submit-your-patch">9. Submit your patch.</a></h1>
  16433. <p>Once you're happy with your patch, it's time to prepare a Pull Request.</p>
  16434. <p>To prepare a Pull Request, please:</p>
  16435. <ol>
  16436. <li>verify that <a href="development/contributing_guide.html#test-test-test">all the tests pass</a>, including the coding style;</li>
  16437. <li><a href="development/contributing_guide.html#sign-off">sign off</a> your contribution;</li>
  16438. <li><code>git push</code> your commit to your fork of Synapse;</li>
  16439. <li>on GitHub, <a href="https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request">create the Pull Request</a>;</li>
  16440. <li>add a <a href="development/contributing_guide.html#changelog">changelog entry</a> and push it to your Pull Request;</li>
  16441. <li>that's it for now, a non-draft pull request will automatically request review from the team;</li>
  16442. <li>if you need to update your PR, please avoid rebasing and just add new commits to your branch.</li>
  16443. </ol>
  16444. <h2 id="changelog"><a class="header" href="#changelog">Changelog</a></h2>
  16445. <p>All changes, even minor ones, need a corresponding changelog / newsfragment
  16446. entry. These are managed by <a href="https://github.com/twisted/towncrier">Towncrier</a>.</p>
  16447. <p>To create a changelog entry, make a new file in the <code>changelog.d</code> directory named
  16448. in the format of <code>PRnumber.type</code>. The type can be one of the following:</p>
  16449. <ul>
  16450. <li><code>feature</code></li>
  16451. <li><code>bugfix</code></li>
  16452. <li><code>docker</code> (for updates to the Docker image)</li>
  16453. <li><code>doc</code> (for updates to the documentation)</li>
  16454. <li><code>removal</code> (also used for deprecations)</li>
  16455. <li><code>misc</code> (for internal-only changes)</li>
  16456. </ul>
  16457. <p>This file will become part of our <a href="https://github.com/matrix-org/synapse/blob/master/CHANGES.md">changelog</a> at the next
  16458. release, so the content of the file should be a short description of your
  16459. change in the same style as the rest of the changelog. The file can contain Markdown
  16460. formatting, and must end with a full stop (.) or an exclamation mark (!) for
  16461. consistency.</p>
  16462. <p>Adding credits to the changelog is encouraged, we value your
  16463. contributions and would like to have you shouted out in the release notes!</p>
  16464. <p>For example, a fix in PR #1234 would have its changelog entry in
  16465. <code>changelog.d/1234.bugfix</code>, and contain content like:</p>
  16466. <blockquote>
  16467. <p>The security levels of Florbs are now validated when received
  16468. via the <code>/federation/florb</code> endpoint. Contributed by Jane Matrix.</p>
  16469. </blockquote>
  16470. <p>If there are multiple pull requests involved in a single bugfix/feature/etc,
  16471. then the content for each <code>changelog.d</code> file should be the same. Towncrier will
  16472. merge the matching files together into a single changelog entry when we come to
  16473. release.</p>
  16474. <h3 id="how-do-i-know-what-to-call-the-changelog-file-before-i-create-the-pr"><a class="header" href="#how-do-i-know-what-to-call-the-changelog-file-before-i-create-the-pr">How do I know what to call the changelog file before I create the PR?</a></h3>
  16475. <p>Obviously, you don't know if you should call your newsfile
  16476. <code>1234.bugfix</code> or <code>5678.bugfix</code> until you create the PR, which leads to a
  16477. chicken-and-egg problem.</p>
  16478. <p>There are two options for solving this:</p>
  16479. <ol>
  16480. <li>
  16481. <p>Open the PR without a changelog file, see what number you got, and <em>then</em>
  16482. add the changelog file to your branch, or:</p>
  16483. </li>
  16484. <li>
  16485. <p>Look at the <a href="https://github.com/matrix-org/synapse/issues?q=">list of all
  16486. issues/PRs</a>, add one to the
  16487. highest number you see, and quickly open the PR before somebody else claims
  16488. your number.</p>
  16489. <p><a href="https://github.com/richvdh/scripts/blob/master/next_github_number.sh">This
  16490. script</a>
  16491. might be helpful if you find yourself doing this a lot.</p>
  16492. </li>
  16493. </ol>
  16494. <p>Sorry, we know it's a bit fiddly, but it's <em>really</em> helpful for us when we come
  16495. to put together a release!</p>
  16496. <h3 id="debian-changelog"><a class="header" href="#debian-changelog">Debian changelog</a></h3>
  16497. <p>Changes which affect the debian packaging files (in <code>debian</code>) are an
  16498. exception to the rule that all changes require a <code>changelog.d</code> file.</p>
  16499. <p>In this case, you will need to add an entry to the debian changelog for the
  16500. next release. For this, run the following command:</p>
  16501. <pre><code>dch
  16502. </code></pre>
  16503. <p>This will make up a new version number (if there isn't already an unreleased
  16504. version in flight), and open an editor where you can add a new changelog entry.
  16505. (Our release process will ensure that the version number and maintainer name is
  16506. corrected for the release.)</p>
  16507. <p>If your change affects both the debian packaging <em>and</em> files outside the debian
  16508. directory, you will need both a regular newsfragment <em>and</em> an entry in the
  16509. debian changelog. (Though typically such changes should be submitted as two
  16510. separate pull requests.)</p>
  16511. <h2 id="sign-off"><a class="header" href="#sign-off">Sign off</a></h2>
  16512. <p>In order to have a concrete record that your contribution is intentional
  16513. and you agree to license it under the same terms as the project's license, we've adopted the
  16514. same lightweight approach that the Linux Kernel
  16515. <a href="https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin%3E">submitting patches process</a>,
  16516. <a href="https://github.com/docker/docker/blob/master/CONTRIBUTING.md">Docker</a>, and many other
  16517. projects use: the DCO (<a href="http://developercertificate.org/">Developer Certificate of Origin</a>).
  16518. This is a simple declaration that you wrote
  16519. the contribution or otherwise have the right to contribute it to Matrix:</p>
  16520. <pre><code>Developer Certificate of Origin
  16521. Version 1.1
  16522. Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
  16523. 660 York Street, Suite 102,
  16524. San Francisco, CA 94110 USA
  16525. Everyone is permitted to copy and distribute verbatim copies of this
  16526. license document, but changing it is not allowed.
  16527. Developer's Certificate of Origin 1.1
  16528. By making a contribution to this project, I certify that:
  16529. (a) The contribution was created in whole or in part by me and I
  16530. have the right to submit it under the open source license
  16531. indicated in the file; or
  16532. (b) The contribution is based upon previous work that, to the best
  16533. of my knowledge, is covered under an appropriate open source
  16534. license and I have the right under that license to submit that
  16535. work with modifications, whether created in whole or in part
  16536. by me, under the same open source license (unless I am
  16537. permitted to submit under a different license), as indicated
  16538. in the file; or
  16539. (c) The contribution was provided directly to me by some other
  16540. person who certified (a), (b) or (c) and I have not modified
  16541. it.
  16542. (d) I understand and agree that this project and the contribution
  16543. are public and that a record of the contribution (including all
  16544. personal information I submit with it, including my sign-off) is
  16545. maintained indefinitely and may be redistributed consistent with
  16546. this project or the open source license(s) involved.
  16547. </code></pre>
  16548. <p>If you agree to this for your contribution, then all that's needed is to
  16549. include the line in your commit or pull request comment:</p>
  16550. <pre><code>Signed-off-by: Your Name &lt;your@email.example.org&gt;
  16551. </code></pre>
  16552. <p>We accept contributions under a legally identifiable name, such as
  16553. your name on government documentation or common-law names (names
  16554. claimed by legitimate usage or repute). Unfortunately, we cannot
  16555. accept anonymous contributions at this time.</p>
  16556. <p>Git allows you to add this signoff automatically when using the <code>-s</code>
  16557. flag to <code>git commit</code>, which uses the name and email set in your
  16558. <code>user.name</code> and <code>user.email</code> git configs.</p>
  16559. <h3 id="private-sign-off"><a class="header" href="#private-sign-off">Private Sign off</a></h3>
  16560. <p>If you would like to provide your legal name privately to the Matrix.org
  16561. Foundation (instead of in a public commit or comment), you can do so
  16562. by emailing your legal name and a link to the pull request to
  16563. <a href="mailto:dco@matrix.org?subject=Private%20sign%20off">dco@matrix.org</a>.
  16564. It helps to include &quot;sign off&quot; or similar in the subject line. You will then
  16565. be instructed further.</p>
  16566. <p>Once private sign off is complete, doing so for future contributions will not
  16567. be required.</p>
  16568. <h1 id="10-turn-feedback-into-better-code"><a class="header" href="#10-turn-feedback-into-better-code">10. Turn feedback into better code.</a></h1>
  16569. <p>Once the Pull Request is opened, you will see a few things:</p>
  16570. <ol>
  16571. <li>our automated CI (Continuous Integration) pipeline will run (again) the linters, the unit tests, the integration tests and more;</li>
  16572. <li>one or more of the developers will take a look at your Pull Request and offer feedback.</li>
  16573. </ol>
  16574. <p>From this point, you should:</p>
  16575. <ol>
  16576. <li>Look at the results of the CI pipeline.
  16577. <ul>
  16578. <li>If there is any error, fix the error.</li>
  16579. </ul>
  16580. </li>
  16581. <li>If a developer has requested changes, make these changes and let us know if it is ready for a developer to review again.
  16582. <ul>
  16583. <li>A pull request is a conversation, if you disagree with the suggestions, please respond and discuss it.</li>
  16584. </ul>
  16585. </li>
  16586. <li>Create a new commit with the changes.
  16587. <ul>
  16588. <li>Please do NOT overwrite the history. New commits make the reviewer's life easier.</li>
  16589. <li>Push this commits to your Pull Request.</li>
  16590. </ul>
  16591. </li>
  16592. <li>Back to 1.</li>
  16593. <li>Once the pull request is ready for review again please re-request review from whichever developer did your initial
  16594. review (or leave a comment in the pull request that you believe all required changes have been done).</li>
  16595. </ol>
  16596. <p>Once both the CI and the developers are happy, the patch will be merged into Synapse and released shortly!</p>
  16597. <h1 id="11-find-a-new-issue"><a class="header" href="#11-find-a-new-issue">11. Find a new issue.</a></h1>
  16598. <p>By now, you know the drill!</p>
  16599. <h1 id="notes-for-maintainers-on-merging-prs-etc"><a class="header" href="#notes-for-maintainers-on-merging-prs-etc">Notes for maintainers on merging PRs etc</a></h1>
  16600. <p>There are some notes for those with commit access to the project on how we
  16601. manage git <a href="development/git.html">here</a>.</p>
  16602. <h1 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h1>
  16603. <p>That's it! Matrix is a very open and collaborative project as you might expect
  16604. given our obsession with open communication. If we're going to successfully
  16605. matrix together all the fragmented communication technologies out there we are
  16606. reliant on contributions and collaboration from the community to do so. So
  16607. please get involved - and we hope you have as much fun hacking on Matrix as we
  16608. do!</p>
  16609. <div style="break-before: page; page-break-before: always;"></div><h1 id="code-style"><a class="header" href="#code-style">Code Style</a></h1>
  16610. <h2 id="formatting-tools"><a class="header" href="#formatting-tools">Formatting tools</a></h2>
  16611. <p>The Synapse codebase uses a number of code formatting tools in order to
  16612. quickly and automatically check for formatting (and sometimes logical)
  16613. errors in code.</p>
  16614. <p>The necessary tools are:</p>
  16615. <ul>
  16616. <li><a href="https://black.readthedocs.io/en/stable/">black</a>, a source code formatter;</li>
  16617. <li><a href="https://pycqa.github.io/isort/">isort</a>, which organises each file's imports;</li>
  16618. <li><a href="https://github.com/charliermarsh/ruff">ruff</a>, which can spot common errors; and</li>
  16619. <li><a href="https://mypy.readthedocs.io/en/stable/">mypy</a>, a type checker.</li>
  16620. </ul>
  16621. <p>See <a href="development/contributing_guide.html#run-the-linters">the contributing guide</a> for instructions
  16622. on how to install the above tools and run the linters.</p>
  16623. <p>It's worth noting that modern IDEs and text editors can run these tools
  16624. automatically on save. It may be worth looking into whether this
  16625. functionality is supported in your editor for a more convenient
  16626. development workflow. It is not, however, recommended to run <code>mypy</code>
  16627. on save as it takes a while and can be very resource intensive.</p>
  16628. <h2 id="general-rules"><a class="header" href="#general-rules">General rules</a></h2>
  16629. <ul>
  16630. <li><strong>Naming</strong>:
  16631. <ul>
  16632. <li>Use <code>CamelCase</code> for class and type names</li>
  16633. <li>Use underscores for <code>function_names</code> and <code>variable_names</code>.</li>
  16634. </ul>
  16635. </li>
  16636. <li><strong>Docstrings</strong>: should follow the <a href="https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings">google code
  16637. style</a>.
  16638. See the
  16639. <a href="http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html">examples</a>
  16640. in the sphinx documentation.</li>
  16641. <li><strong>Imports</strong>:
  16642. <ul>
  16643. <li>
  16644. <p>Imports should be sorted by <code>isort</code> as described above.</p>
  16645. </li>
  16646. <li>
  16647. <p>Prefer to import classes and functions rather than packages or
  16648. modules.</p>
  16649. <p>Example:</p>
  16650. <pre><code class="language-python">from synapse.types import UserID
  16651. ...
  16652. user_id = UserID(local, server)
  16653. </code></pre>
  16654. <p>is preferred over:</p>
  16655. <pre><code class="language-python">from synapse import types
  16656. ...
  16657. user_id = types.UserID(local, server)
  16658. </code></pre>
  16659. <p>(or any other variant).</p>
  16660. <p>This goes against the advice in the Google style guide, but it
  16661. means that errors in the name are caught early (at import time).</p>
  16662. </li>
  16663. <li>
  16664. <p>Avoid wildcard imports (<code>from synapse.types import *</code>) and
  16665. relative imports (<code>from .types import UserID</code>).</p>
  16666. </li>
  16667. </ul>
  16668. </li>
  16669. </ul>
  16670. <h2 id="configuration-code-and-documentation-format"><a class="header" href="#configuration-code-and-documentation-format">Configuration code and documentation format</a></h2>
  16671. <p>When adding a configuration option to the code, if several settings are grouped into a single dict, ensure that your code
  16672. correctly handles the top-level option being set to <code>None</code> (as it will be if no sub-options are enabled).</p>
  16673. <p>The <a href="usage/configuration/config_documentation.html">configuration manual</a> acts as a
  16674. reference to Synapse's configuration options for server administrators.
  16675. Remember that many readers will be unfamiliar with YAML and server
  16676. administration in general, so it is important that when you add
  16677. a configuration option the documentation be as easy to understand as possible, which
  16678. includes following a consistent format.</p>
  16679. <p>Some guidelines follow:</p>
  16680. <ul>
  16681. <li>
  16682. <p>Each option should be listed in the config manual with the following format:</p>
  16683. <ul>
  16684. <li>
  16685. <p>The name of the option, prefixed by <code>###</code>. </p>
  16686. </li>
  16687. <li>
  16688. <p>A comment which describes the default behaviour (i.e. what
  16689. happens if the setting is omitted), as well as what the effect
  16690. will be if the setting is changed.</p>
  16691. </li>
  16692. <li>
  16693. <p>An example setting, using backticks to define the code block</p>
  16694. <p>For boolean (on/off) options, convention is that this example
  16695. should be the <em>opposite</em> to the default. For other options, the example should give
  16696. some non-default value which is likely to be useful to the reader.</p>
  16697. </li>
  16698. </ul>
  16699. </li>
  16700. <li>
  16701. <p>There should be a horizontal rule between each option, which can be achieved by adding <code>---</code> before and
  16702. after the option.</p>
  16703. </li>
  16704. <li>
  16705. <p><code>true</code> and <code>false</code> are spelt thus (as opposed to <code>True</code>, etc.)</p>
  16706. </li>
  16707. </ul>
  16708. <p>Example:</p>
  16709. <hr />
  16710. <h3 id="modules-3"><a class="header" href="#modules-3"><code>modules</code></a></h3>
  16711. <p>Use the <code>module</code> sub-option to add a module under <code>modules</code> to extend functionality.
  16712. The <code>module</code> setting then has a sub-option, <code>config</code>, which can be used to define some configuration
  16713. for the <code>module</code>.</p>
  16714. <p>Defaults to none.</p>
  16715. <p>Example configuration:</p>
  16716. <pre><code class="language-yaml">modules:
  16717. - module: my_super_module.MySuperClass
  16718. config:
  16719. do_thing: true
  16720. - module: my_other_super_module.SomeClass
  16721. config: {}
  16722. </code></pre>
  16723. <hr />
  16724. <p>Note that the sample configuration is generated from the synapse code
  16725. and is maintained by a script, <code>scripts-dev/generate_sample_config.sh</code>.
  16726. Making sure that the output from this script matches the desired format
  16727. is left as an exercise for the reader!</p>
  16728. <div style="break-before: page; page-break-before: always;"></div><h1 id="some-notes-on-how-we-do-reviews"><a class="header" href="#some-notes-on-how-we-do-reviews">Some notes on how we do reviews</a></h1>
  16729. <p>The Synapse team works off a shared review queue -- any new pull requests for
  16730. Synapse (or related projects) has a review requested from the entire team. Team
  16731. members should process this queue using the following rules:</p>
  16732. <ul>
  16733. <li>Any high urgency pull requests (e.g. fixes for broken continuous integration
  16734. or fixes for release blockers);</li>
  16735. <li>Follow-up reviews for pull requests which have previously received reviews;</li>
  16736. <li>Any remaining pull requests.</li>
  16737. </ul>
  16738. <p>For the latter two categories above, older pull requests should be prioritised.</p>
  16739. <p>It is explicit that there is no priority given to pull requests from the team
  16740. (vs from the community). If a pull request requires a quick turn around, please
  16741. explicitly communicate this via <a href="https://matrix.to/#/#synapse-dev:matrix.org">#synapse-dev:matrix.org</a>
  16742. or as a comment on the pull request.</p>
  16743. <p>Once an initial review has been completed and the author has made additional changes,
  16744. follow-up reviews should go back to the same reviewer. This helps build a shared
  16745. context and conversation between author and reviewer.</p>
  16746. <p>As a team we aim to keep the number of inflight pull requests to a minimum to ensure
  16747. that ongoing work is finished before starting new work.</p>
  16748. <h2 id="performing-a-review"><a class="header" href="#performing-a-review">Performing a review</a></h2>
  16749. <p>To communicate to the rest of the team the status of each pull request, team
  16750. members should do the following:</p>
  16751. <ul>
  16752. <li>Assign themselves to the pull request (they should be left assigned to the
  16753. pull request until it is merged, closed, or are no longer the reviewer);</li>
  16754. <li>Review the pull request by leaving comments, questions, and suggestions;</li>
  16755. <li>Mark the pull request appropriately (as needing changes or accepted).</li>
  16756. </ul>
  16757. <p>If you are unsure about a particular part of the pull request (or are not confident
  16758. in your understanding of part of the code) then ask questions or request review
  16759. from the team again. When requesting review from the team be sure to leave a comment
  16760. with the rationale on why you're putting it back in the queue.</p>
  16761. <div style="break-before: page; page-break-before: always;"></div><h1 id="synapse-release-cycle"><a class="header" href="#synapse-release-cycle">Synapse Release Cycle</a></h1>
  16762. <p>Releases of Synapse follow a two week release cycle with new releases usually
  16763. occurring on Tuesdays:</p>
  16764. <ul>
  16765. <li>Day 0: Synapse <code>N - 1</code> is released.</li>
  16766. <li>Day 7: Synapse <code>N</code> release candidate 1 is released.</li>
  16767. <li>Days 7 - 13: Synapse <code>N</code> release candidates 2+ are released, if bugs are found.</li>
  16768. <li>Day 14: Synapse <code>N</code> is released.</li>
  16769. </ul>
  16770. <p>Note that this schedule might be modified depending on the availability of the
  16771. Synapse team, e.g. releases may be skipped to avoid holidays.</p>
  16772. <p>Release announcements can be found in the
  16773. <a href="https://matrix.org/category/releases">release category of the Matrix blog</a>.</p>
  16774. <h2 id="bugfix-releases"><a class="header" href="#bugfix-releases">Bugfix releases</a></h2>
  16775. <p>If a bug is found after release that is deemed severe enough (by a combination
  16776. of the impacted users and the impact on those users) then a bugfix release may
  16777. be issued. This may be at any point in the release cycle.</p>
  16778. <h2 id="security-releases"><a class="header" href="#security-releases">Security releases</a></h2>
  16779. <p>Security will sometimes be backported to the previous version and released
  16780. immediately before the next release candidate. An example of this might be:</p>
  16781. <ul>
  16782. <li>Day 0: Synapse N - 1 is released.</li>
  16783. <li>Day 7: Synapse (N - 1).1 is released as Synapse N - 1 + the security fix.</li>
  16784. <li>Day 7: Synapse N release candidate 1 is released (including the security fix).</li>
  16785. </ul>
  16786. <p>Depending on the impact and complexity of security fixes, multiple fixes might
  16787. be held to be released together.</p>
  16788. <p>In some cases, a pre-disclosure of a security release will be issued as a notice
  16789. to Synapse operators that there is an upcoming security release. These can be
  16790. found in the <a href="https://matrix.org/category/security">security category of the Matrix blog</a>.</p>
  16791. <div style="break-before: page; page-break-before: always;"></div><h1 id="some-notes-on-how-we-use-git"><a class="header" href="#some-notes-on-how-we-use-git">Some notes on how we use git</a></h1>
  16792. <h2 id="on-keeping-the-commit-history-clean"><a class="header" href="#on-keeping-the-commit-history-clean">On keeping the commit history clean</a></h2>
  16793. <p>In an ideal world, our git commit history would be a linear progression of
  16794. commits each of which contains a single change building on what came
  16795. before. Here, by way of an arbitrary example, is the top of <code>git log --graph b2dba0607</code>:</p>
  16796. <img src="development/img/git/clean.png" alt="clean git graph" width="500px">
  16797. <p>Note how the commit comment explains clearly what is changing and why. Also
  16798. note the <em>absence</em> of merge commits, as well as the absence of commits called
  16799. things like (to pick a few culprits):
  16800. <a href="https://github.com/matrix-org/synapse/commit/84691da6c">“pep8”</a>, <a href="https://github.com/matrix-org/synapse/commit/474810d9d">“fix broken
  16801. test”</a>,
  16802. <a href="https://github.com/matrix-org/synapse/commit/c9d72e457">“oops”</a>,
  16803. <a href="https://github.com/matrix-org/synapse/commit/836358823">“typo”</a>, or <a href="https://github.com/matrix-org/synapse/commit/707374d5d">“Who's
  16804. the president?”</a>.</p>
  16805. <p>There are a number of reasons why keeping a clean commit history is a good
  16806. thing:</p>
  16807. <ul>
  16808. <li>
  16809. <p>From time to time, after a change lands, it turns out to be necessary to
  16810. revert it, or to backport it to a release branch. Those operations are
  16811. <em>much</em> easier when the change is contained in a single commit.</p>
  16812. </li>
  16813. <li>
  16814. <p>Similarly, it's much easier to answer questions like “is the fix for
  16815. <code>/publicRooms</code> on the release branch?” if that change consists of a single
  16816. commit.</p>
  16817. </li>
  16818. <li>
  16819. <p>Likewise: “what has changed on this branch in the last week?” is much
  16820. clearer without merges and “pep8” commits everywhere.</p>
  16821. </li>
  16822. <li>
  16823. <p>Sometimes we need to figure out where a bug got introduced, or some
  16824. behaviour changed. One way of doing that is with <code>git bisect</code>: pick an
  16825. arbitrary commit between the known good point and the known bad point, and
  16826. see how the code behaves. However, that strategy fails if the commit you
  16827. chose is the middle of someone's epic branch in which they broke the world
  16828. before putting it back together again.</p>
  16829. </li>
  16830. </ul>
  16831. <p>One counterargument is that it is sometimes useful to see how a PR evolved as
  16832. it went through review cycles. This is true, but that information is always
  16833. available via the GitHub UI (or via the little-known <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally">refs/pull
  16834. namespace</a>).</p>
  16835. <p>Of course, in reality, things are more complicated than that. We have release
  16836. branches as well as <code>develop</code> and <code>master</code>, and we deliberately merge changes
  16837. between them. Bugs often slip through and have to be fixed later. That's all
  16838. fine: this not a cast-iron rule which must be obeyed, but an ideal to aim
  16839. towards.</p>
  16840. <h2 id="merges-squashes-rebases-wtf"><a class="header" href="#merges-squashes-rebases-wtf">Merges, squashes, rebases: wtf?</a></h2>
  16841. <p>Ok, so that's what we'd like to achieve. How do we achieve it?</p>
  16842. <p>The TL;DR is: when you come to merge a pull request, you <em>probably</em> want to
  16843. “squash and merge”:</p>
  16844. <p><img src="development/img/git/squash.png" alt="squash and merge" />.</p>
  16845. <p>(This applies whether you are merging your own PR, or that of another
  16846. contributor.)</p>
  16847. <p>“Squash and merge”<sup id="a1"><a href="development/git.html#f1">1</a></sup> takes all of the changes in the
  16848. PR, and bundles them into a single commit. GitHub gives you the opportunity to
  16849. edit the commit message before you confirm, and normally you should do so,
  16850. because the default will be useless (again: <code>* woops typo</code> is not a useful
  16851. thing to keep in the historical record).</p>
  16852. <p>The main problem with this approach comes when you have a series of pull
  16853. requests which build on top of one another: as soon as you squash-merge the
  16854. first PR, you'll end up with a stack of conflicts to resolve in all of the
  16855. others. In general, it's best to avoid this situation in the first place by
  16856. trying not to have multiple related PRs in flight at the same time. Still,
  16857. sometimes that's not possible and doing a regular merge is the lesser evil.</p>
  16858. <p>Another occasion in which a regular merge makes more sense is a PR where you've
  16859. deliberately created a series of commits each of which makes sense in its own
  16860. right. For example: <a href="https://github.com/matrix-org/synapse/pull/6837">a PR which gradually propagates a refactoring operation
  16861. through the codebase</a>, or <a href="https://github.com/matrix-org/synapse/pull/5987">a
  16862. PR which is the culmination of several other
  16863. PRs</a>. In this case the ability
  16864. to figure out when a particular change/bug was introduced could be very useful.</p>
  16865. <p>Ultimately: <strong>this is not a hard-and-fast-rule</strong>. If in doubt, ask yourself “do
  16866. each of the commits I am about to merge make sense in their own right”, but
  16867. remember that we're just doing our best to balance “keeping the commit history
  16868. clean” with other factors.</p>
  16869. <h2 id="git-branching-model"><a class="header" href="#git-branching-model">Git branching model</a></h2>
  16870. <p>A <a href="https://nvie.com/posts/a-successful-git-branching-model/">lot</a>
  16871. <a href="http://scottchacon.com/2011/08/31/github-flow.html">of</a>
  16872. <a href="https://www.endoflineblog.com/gitflow-considered-harmful">words</a> have been
  16873. written in the past about git branching models (no really, <a href="https://martinfowler.com/articles/branching-patterns.html">a
  16874. lot</a>). I tend to
  16875. think the whole thing is overblown. Fundamentally, it's not that
  16876. complicated. Here's how we do it.</p>
  16877. <p>Let's start with a picture:</p>
  16878. <p><img src="development/img/git/branches.jpg" alt="branching model" /></p>
  16879. <p>It looks complicated, but it's really not. There's one basic rule: <em>anyone</em> is
  16880. free to merge from <em>any</em> more-stable branch to <em>any</em> less-stable branch at
  16881. <em>any</em> time<sup id="a2"><a href="development/git.html#f2">2</a></sup>. (The principle behind this is that if a
  16882. change is good enough for the more-stable branch, then it's also good enough go
  16883. put in a less-stable branch.)</p>
  16884. <p>Meanwhile, merging (or squashing, as per the above) from a less-stable to a
  16885. more-stable branch is a deliberate action in which you want to publish a change
  16886. or a set of changes to (some subset of) the world: for example, this happens
  16887. when a PR is landed, or as part of our release process.</p>
  16888. <p>So, what counts as a more- or less-stable branch? A little reflection will show
  16889. that our active branches are ordered thus, from more-stable to less-stable:</p>
  16890. <ul>
  16891. <li><code>master</code> (tracks our last release).</li>
  16892. <li><code>release-vX.Y</code> (the branch where we prepare the next release)<sup
  16893. id="a3"><a href="development/git.html#f3">3</a></sup>.</li>
  16894. <li>PR branches which are targeting the release.</li>
  16895. <li><code>develop</code> (our &quot;mainline&quot; branch containing our bleeding-edge).</li>
  16896. <li>regular PR branches.</li>
  16897. </ul>
  16898. <p>The corollary is: if you have a bugfix that needs to land in both
  16899. <code>release-vX.Y</code> <em>and</em> <code>develop</code>, then you should base your PR on
  16900. <code>release-vX.Y</code>, get it merged there, and then merge from <code>release-vX.Y</code> to
  16901. <code>develop</code>. (If a fix lands in <code>develop</code> and we later need it in a
  16902. release-branch, we can of course cherry-pick it, but landing it in the release
  16903. branch first helps reduce the chance of annoying conflicts.)</p>
  16904. <hr />
  16905. <p><b id="f1">[1]</b>: “Squash and merge” is GitHub's term for this
  16906. operation. Given that there is no merge involved, I'm not convinced it's the
  16907. most intuitive name. <a href="development/git.html#a1">^</a></p>
  16908. <p><b id="f2">[2]</b>: Well, anyone with commit access.<a href="development/git.html#a2">^</a></p>
  16909. <p><b id="f3">[3]</b>: Very, very occasionally (I think this has happened once in
  16910. the history of Synapse), we've had two releases in flight at once. Obviously,
  16911. <code>release-v1.2</code> is more-stable than <code>release-v1.3</code>. <a href="development/git.html#a3">^</a></p>
  16912. <div style="break-before: page; page-break-before: always;"></div><h1 id="synapse-demo-setup"><a class="header" href="#synapse-demo-setup">Synapse demo setup</a></h1>
  16913. <p><strong>DO NOT USE THESE DEMO SERVERS IN PRODUCTION</strong></p>
  16914. <p>Requires you to have a <a href="https://matrix-org.github.io/synapse/develop/development/contributing_guide.html#4-install-the-dependencies">Synapse development environment setup</a>.</p>
  16915. <p>The demo setup allows running three federation Synapse servers, with server
  16916. names <code>localhost:8480</code>, <code>localhost:8481</code>, and <code>localhost:8482</code>.</p>
  16917. <p>You can access them via any Matrix client over HTTP at <code>localhost:8080</code>,
  16918. <code>localhost:8081</code>, and <code>localhost:8082</code> or over HTTPS at <code>localhost:8480</code>,
  16919. <code>localhost:8481</code>, and <code>localhost:8482</code>.</p>
  16920. <p>To enable the servers to communicate, self-signed SSL certificates are generated
  16921. and the servers are configured in a highly insecure way, including:</p>
  16922. <ul>
  16923. <li>Not checking certificates over federation.</li>
  16924. <li>Not verifying keys.</li>
  16925. </ul>
  16926. <p>The servers are configured to store their data under <code>demo/8080</code>, <code>demo/8081</code>, and
  16927. <code>demo/8082</code>. This includes configuration, logs, SQLite databases, and media.</p>
  16928. <p>Note that when joining a public room on a different homeserver via &quot;#foo:bar.net&quot;,
  16929. then you are (in the current implementation) joining a room with room_id &quot;foo&quot;.
  16930. This means that it won't work if your homeserver already has a room with that
  16931. name.</p>
  16932. <h2 id="using-the-demo-scripts"><a class="header" href="#using-the-demo-scripts">Using the demo scripts</a></h2>
  16933. <p>There's three main scripts with straightforward purposes:</p>
  16934. <ul>
  16935. <li><code>start.sh</code> will start the Synapse servers, generating any missing configuration.
  16936. <ul>
  16937. <li>This accepts a single parameter <code>--no-rate-limit</code> to &quot;disable&quot; rate limits
  16938. (they actually still exist, but are very high).</li>
  16939. </ul>
  16940. </li>
  16941. <li><code>stop.sh</code> will stop the Synapse servers.</li>
  16942. <li><code>clean.sh</code> will delete the configuration, databases, log files, etc.</li>
  16943. </ul>
  16944. <p>To start a completely new set of servers, run:</p>
  16945. <pre><code class="language-sh">./demo/stop.sh; ./demo/clean.sh &amp;&amp; ./demo/start.sh
  16946. </code></pre>
  16947. <div style="break-before: page; page-break-before: always;"></div><h1 id="opentracing-2"><a class="header" href="#opentracing-2">OpenTracing</a></h1>
  16948. <h2 id="background"><a class="header" href="#background">Background</a></h2>
  16949. <p>OpenTracing is a semi-standard being adopted by a number of distributed
  16950. tracing platforms. It is a common api for facilitating vendor-agnostic
  16951. tracing instrumentation. That is, we can use the OpenTracing api and
  16952. select one of a number of tracer implementations to do the heavy lifting
  16953. in the background. Our current selected implementation is Jaeger.</p>
  16954. <p>OpenTracing is a tool which gives an insight into the causal
  16955. relationship of work done in and between servers. The servers each track
  16956. events and report them to a centralised server - in Synapse's case:
  16957. Jaeger. The basic unit used to represent events is the span. The span
  16958. roughly represents a single piece of work that was done and the time at
  16959. which it occurred. A span can have child spans, meaning that the work of
  16960. the child had to be completed for the parent span to complete, or it can
  16961. have follow-on spans which represent work that is undertaken as a result
  16962. of the parent but is not depended on by the parent to in order to
  16963. finish.</p>
  16964. <p>Since this is undertaken in a distributed environment a request to
  16965. another server, such as an RPC or a simple GET, can be considered a span
  16966. (a unit or work) for the local server. This causal link is what
  16967. OpenTracing aims to capture and visualise. In order to do this metadata
  16968. about the local server's span, i.e the 'span context', needs to be
  16969. included with the request to the remote.</p>
  16970. <p>It is up to the remote server to decide what it does with the spans it
  16971. creates. This is called the sampling policy and it can be configured
  16972. through Jaeger's settings.</p>
  16973. <p>For OpenTracing concepts see
  16974. <a href="https://opentracing.io/docs/overview/what-is-tracing/">https://opentracing.io/docs/overview/what-is-tracing/</a>.</p>
  16975. <p>For more information about Jaeger's implementation see
  16976. <a href="https://www.jaegertracing.io/docs/">https://www.jaegertracing.io/docs/</a></p>
  16977. <h2 id="setting-up-opentracing"><a class="header" href="#setting-up-opentracing">Setting up OpenTracing</a></h2>
  16978. <p>To receive OpenTracing spans, start up a Jaeger server. This can be done
  16979. using docker like so:</p>
  16980. <pre><code class="language-sh">docker run -d --name jaeger \
  16981. -p 6831:6831/udp \
  16982. -p 6832:6832/udp \
  16983. -p 5778:5778 \
  16984. -p 16686:16686 \
  16985. -p 14268:14268 \
  16986. jaegertracing/all-in-one:1
  16987. </code></pre>
  16988. <p>By default, Synapse will publish traces to Jaeger on localhost.
  16989. If Jaeger is hosted elsewhere, point Synapse to the correct host by setting
  16990. <code>opentracing.jaeger_config.local_agent.reporting_host</code> <a href="usage/configuration/config_documentation.html#opentracing-1">in the Synapse configuration</a>
  16991. or by setting the <code>JAEGER_AGENT_HOST</code> environment variable to the desired address.</p>
  16992. <p>Latest documentation is probably at
  16993. https://www.jaegertracing.io/docs/latest/getting-started.</p>
  16994. <h2 id="enable-opentracing-in-synapse"><a class="header" href="#enable-opentracing-in-synapse">Enable OpenTracing in Synapse</a></h2>
  16995. <p>OpenTracing is not enabled by default. It must be enabled in the
  16996. homeserver config by adding the <code>opentracing</code> option to your config file. You can find
  16997. documentation about how to do this in the <a href="usage/configuration/config_documentation.html#opentracing">config manual under the header 'Opentracing'</a>.
  16998. See below for an example Opentracing configuration: </p>
  16999. <pre><code class="language-yaml">opentracing:
  17000. enabled: true
  17001. homeserver_whitelist:
  17002. - &quot;mytrustedhomeserver.org&quot;
  17003. - &quot;*.myotherhomeservers.com&quot;
  17004. </code></pre>
  17005. <h2 id="homeserver-whitelisting"><a class="header" href="#homeserver-whitelisting">Homeserver whitelisting</a></h2>
  17006. <p>The homeserver whitelist is configured using regular expressions. A list
  17007. of regular expressions can be given and their union will be compared
  17008. when propagating any spans contexts to another homeserver.</p>
  17009. <p>Though it's mostly safe to send and receive span contexts to and from
  17010. untrusted users since span contexts are usually opaque ids it can lead
  17011. to two problems, namely:</p>
  17012. <ul>
  17013. <li>If the span context is marked as sampled by the sending homeserver
  17014. the receiver will sample it. Therefore two homeservers with wildly
  17015. different sampling policies could incur higher sampling counts than
  17016. intended.</li>
  17017. <li>Sending servers can attach arbitrary data to spans, known as
  17018. 'baggage'. For safety this has been disabled in Synapse but that
  17019. doesn't prevent another server sending you baggage which will be
  17020. logged to OpenTracing's logs.</li>
  17021. </ul>
  17022. <h2 id="configuring-jaeger"><a class="header" href="#configuring-jaeger">Configuring Jaeger</a></h2>
  17023. <p>Sampling strategies can be set as in this document:
  17024. <a href="https://www.jaegertracing.io/docs/latest/sampling/">https://www.jaegertracing.io/docs/latest/sampling/</a>.</p>
  17025. <div style="break-before: page; page-break-before: always;"></div><h1 id="synapse-database-schema-files"><a class="header" href="#synapse-database-schema-files">Synapse database schema files</a></h1>
  17026. <p>Synapse's database schema is stored in the <code>synapse.storage.schema</code> module.</p>
  17027. <h2 id="logical-databases"><a class="header" href="#logical-databases">Logical databases</a></h2>
  17028. <p>Synapse supports splitting its datastore across multiple physical databases (which can
  17029. be useful for large installations), and the schema files are therefore split according
  17030. to the logical database they apply to.</p>
  17031. <p>At the time of writing, the following &quot;logical&quot; databases are supported:</p>
  17032. <ul>
  17033. <li><code>state</code> - used to store Matrix room state (more specifically, <code>state_groups</code>,
  17034. their relationships and contents).</li>
  17035. <li><code>main</code> - stores everything else.</li>
  17036. </ul>
  17037. <p>Additionally, the <code>common</code> directory contains schema files for tables which must be
  17038. present on <em>all</em> physical databases.</p>
  17039. <h2 id="synapse-schema-versions"><a class="header" href="#synapse-schema-versions">Synapse schema versions</a></h2>
  17040. <p>Synapse manages its database schema via &quot;schema versions&quot;. These are mainly used to
  17041. help avoid confusion if the Synapse codebase is rolled back after the database is
  17042. updated. They work as follows:</p>
  17043. <ul>
  17044. <li>
  17045. <p>The Synapse codebase defines a constant <code>synapse.storage.schema.SCHEMA_VERSION</code>
  17046. which represents the expectations made about the database by that version. For
  17047. example, as of Synapse v1.36, this is <code>59</code>.</p>
  17048. </li>
  17049. <li>
  17050. <p>The database stores a &quot;compatibility version&quot; in
  17051. <code>schema_compat_version.compat_version</code> which defines the <code>SCHEMA_VERSION</code> of the
  17052. oldest version of Synapse which will work with the database. On startup, if
  17053. <code>compat_version</code> is found to be newer than <code>SCHEMA_VERSION</code>, Synapse will refuse to
  17054. start.</p>
  17055. <p>Synapse automatically updates this field from
  17056. <code>synapse.storage.schema.SCHEMA_COMPAT_VERSION</code>.</p>
  17057. </li>
  17058. <li>
  17059. <p>Whenever a backwards-incompatible change is made to the database format (normally
  17060. via a <code>delta</code> file), <code>synapse.storage.schema.SCHEMA_COMPAT_VERSION</code> is also updated
  17061. so that administrators can not accidentally roll back to a too-old version of Synapse.</p>
  17062. </li>
  17063. </ul>
  17064. <p>Generally, the goal is to maintain compatibility with at least one or two previous
  17065. releases of Synapse, so any substantial change tends to require multiple releases and a
  17066. bit of forward-planning to get right.</p>
  17067. <p>As a worked example: we want to remove the <code>room_stats_historical</code> table. Here is how it
  17068. might pan out.</p>
  17069. <ol>
  17070. <li>
  17071. <p>Replace any code that <em>reads</em> from <code>room_stats_historical</code> with alternative
  17072. implementations, but keep writing to it in case of rollback to an earlier version.
  17073. Also, increase <code>synapse.storage.schema.SCHEMA_VERSION</code>. In this
  17074. instance, there is no existing code which reads from <code>room_stats_historical</code>, so
  17075. our starting point is:</p>
  17076. <p>v1.36.0: <code>SCHEMA_VERSION=59</code>, <code>SCHEMA_COMPAT_VERSION=59</code></p>
  17077. </li>
  17078. <li>
  17079. <p>Next (say in Synapse v1.37.0): remove the code that <em>writes</em> to
  17080. <code>room_stats_historical</code>, but don’t yet remove the table in case of rollback to
  17081. v1.36.0. Again, we increase <code>synapse.storage.schema.SCHEMA_VERSION</code>, but
  17082. because we have not broken compatibility with v1.36, we do not yet update
  17083. <code>SCHEMA_COMPAT_VERSION</code>. We now have:</p>
  17084. <p>v1.37.0: <code>SCHEMA_VERSION=60</code>, <code>SCHEMA_COMPAT_VERSION=59</code>.</p>
  17085. </li>
  17086. <li>
  17087. <p>Later (say in Synapse v1.38.0): we can remove the table altogether. This will
  17088. break compatibility with v1.36.0, so we must update <code>SCHEMA_COMPAT_VERSION</code> accordingly.
  17089. There is no need to update <code>synapse.storage.schema.SCHEMA_VERSION</code>, since there is no
  17090. change to the Synapse codebase here. So we end up with:</p>
  17091. <p>v1.38.0: <code>SCHEMA_VERSION=60</code>, <code>SCHEMA_COMPAT_VERSION=60</code>.</p>
  17092. </li>
  17093. </ol>
  17094. <p>If in doubt about whether to update <code>SCHEMA_VERSION</code> or not, it is generally best to
  17095. lean towards doing so.</p>
  17096. <h2 id="full-schema-dumps"><a class="header" href="#full-schema-dumps">Full schema dumps</a></h2>
  17097. <p>In the <code>full_schemas</code> directories, only the most recently-numbered snapshot is used
  17098. (<code>54</code> at the time of writing). Older snapshots (eg, <code>16</code>) are present for historical
  17099. reference only.</p>
  17100. <h3 id="building-full-schema-dumps"><a class="header" href="#building-full-schema-dumps">Building full schema dumps</a></h3>
  17101. <p>If you want to recreate these schemas, they need to be made from a database that
  17102. has had all background updates run.</p>
  17103. <p>To do so, use <code>scripts-dev/make_full_schema.sh</code>. This will produce new
  17104. <code>full.sql.postgres</code> and <code>full.sql.sqlite</code> files.</p>
  17105. <p>Ensure postgres is installed, then run:</p>
  17106. <pre><code class="language-sh">./scripts-dev/make_full_schema.sh -p postgres_username -o output_dir/
  17107. </code></pre>
  17108. <p>NB at the time of writing, this script predates the split into separate <code>state</code>/<code>main</code>
  17109. databases so will require updates to handle that correctly.</p>
  17110. <h2 id="delta-files"><a class="header" href="#delta-files">Delta files</a></h2>
  17111. <p>Delta files define the steps required to upgrade the database from an earlier version.
  17112. They can be written as either a file containing a series of SQL statements, or a Python
  17113. module.</p>
  17114. <p>Synapse remembers which delta files it has applied to a database (they are stored in the
  17115. <code>applied_schema_deltas</code> table) and will not re-apply them (even if a given file is
  17116. subsequently updated).</p>
  17117. <p>Delta files should be placed in a directory named <code>synapse/storage/schema/&lt;database&gt;/delta/&lt;version&gt;/</code>.
  17118. They are applied in alphanumeric order, so by convention the first two characters
  17119. of the filename should be an integer such as <code>01</code>, to put the file in the right order.</p>
  17120. <h3 id="sql-delta-files"><a class="header" href="#sql-delta-files">SQL delta files</a></h3>
  17121. <p>These should be named <code>*.sql</code>, or — for changes which should only be applied for a
  17122. given database engine — <code>*.sql.posgres</code> or <code>*.sql.sqlite</code>. For example, a delta which
  17123. adds a new column to the <code>foo</code> table might be called <code>01add_bar_to_foo.sql</code>.</p>
  17124. <p>Note that our SQL parser is a bit simple - it understands comments (<code>--</code> and <code>/*...*/</code>),
  17125. but complex statements which require a <code>;</code> in the middle of them (such as <code>CREATE TRIGGER</code>) are beyond it and you'll have to use a Python delta file.</p>
  17126. <h3 id="python-delta-files"><a class="header" href="#python-delta-files">Python delta files</a></h3>
  17127. <p>For more flexibility, a delta file can take the form of a python module. These should
  17128. be named <code>*.py</code>. Note that database-engine-specific modules are not supported here –
  17129. instead you can write <code>if isinstance(database_engine, PostgresEngine)</code> or similar.</p>
  17130. <p>A Python delta module should define either or both of the following functions:</p>
  17131. <pre><code class="language-python">import synapse.config.homeserver
  17132. import synapse.storage.engines
  17133. import synapse.storage.types
  17134. def run_create(
  17135. cur: synapse.storage.types.Cursor,
  17136. database_engine: synapse.storage.engines.BaseDatabaseEngine,
  17137. ) -&gt; None:
  17138. &quot;&quot;&quot;Called whenever an existing or new database is to be upgraded&quot;&quot;&quot;
  17139. ...
  17140. def run_upgrade(
  17141. cur: synapse.storage.types.Cursor,
  17142. database_engine: synapse.storage.engines.BaseDatabaseEngine,
  17143. config: synapse.config.homeserver.HomeServerConfig,
  17144. ) -&gt; None:
  17145. &quot;&quot;&quot;Called whenever an existing database is to be upgraded.&quot;&quot;&quot;
  17146. ...
  17147. </code></pre>
  17148. <h2 id="background-updates-1"><a class="header" href="#background-updates-1">Background updates</a></h2>
  17149. <p>It is sometimes appropriate to perform database migrations as part of a background
  17150. process (instead of blocking Synapse until the migration is done). In particular,
  17151. this is useful for migrating data when adding new columns or tables.</p>
  17152. <p>Pending background updates stored in the <code>background_updates</code> table and are denoted
  17153. by a unique name, the current status (stored in JSON), and some dependency information:</p>
  17154. <ul>
  17155. <li>Whether the update requires a previous update to be complete.</li>
  17156. <li>A rough ordering for which to complete updates.</li>
  17157. </ul>
  17158. <p>A new background updates needs to be added to the <code>background_updates</code> table:</p>
  17159. <pre><code class="language-sql">INSERT INTO background_updates (ordering, update_name, depends_on, progress_json) VALUES
  17160. (7706, 'my_background_update', 'a_previous_background_update' '{}');
  17161. </code></pre>
  17162. <p>And then needs an associated handler in the appropriate datastore:</p>
  17163. <pre><code class="language-python">self.db_pool.updates.register_background_update_handler(
  17164. &quot;my_background_update&quot;,
  17165. update_handler=self._my_background_update,
  17166. )
  17167. </code></pre>
  17168. <p>There are a few types of updates that can be performed, see the <code>BackgroundUpdater</code>:</p>
  17169. <ul>
  17170. <li><code>register_background_update_handler</code>: A generic handler for custom SQL</li>
  17171. <li><code>register_background_index_update</code>: Create an index in the background</li>
  17172. <li><code>register_background_validate_constraint</code>: Validate a constraint in the background
  17173. (PostgreSQL-only)</li>
  17174. <li><code>register_background_validate_constraint_and_delete_rows</code>: Similar to
  17175. <code>register_background_validate_constraint</code>, but deletes rows which don't fit
  17176. the constraint.</li>
  17177. </ul>
  17178. <p>For <code>register_background_update_handler</code>, the generic handler must track progress
  17179. and then finalize the background update:</p>
  17180. <pre><code class="language-python">async def _my_background_update(self, progress: JsonDict, batch_size: int) -&gt; int:
  17181. def _do_something(txn: LoggingTransaction) -&gt; int:
  17182. ...
  17183. self.db_pool.updates._background_update_progress_txn(
  17184. txn, &quot;my_background_update&quot;, {&quot;last_processed&quot;: last_processed}
  17185. )
  17186. return last_processed - prev_last_processed
  17187. num_processed = await self.db_pool.runInteraction(&quot;_do_something&quot;, _do_something)
  17188. await self.db_pool.updates._end_background_update(&quot;my_background_update&quot;)
  17189. return num_processed
  17190. </code></pre>
  17191. <p>Synapse will attempt to rate-limit how often background updates are run via the
  17192. given batch-size and the returned number of processed entries (and how long the
  17193. function took to run). See
  17194. <a href="development/../modules/background_update_controller_callbacks.html">background update controller callbacks</a>.</p>
  17195. <h2 id="boolean-columns"><a class="header" href="#boolean-columns">Boolean columns</a></h2>
  17196. <p>Boolean columns require special treatment, since SQLite treats booleans the
  17197. same as integers.</p>
  17198. <p>Any new boolean column must be added to the <code>BOOLEAN_COLUMNS</code> list in
  17199. <code>synapse/_scripts/synapse_port_db.py</code>. This tells the port script to cast
  17200. the integer value from SQLite to a boolean before writing the value to the
  17201. postgres database.</p>
  17202. <h2 id="event_id-global-uniqueness"><a class="header" href="#event_id-global-uniqueness"><code>event_id</code> global uniqueness</a></h2>
  17203. <p><code>event_id</code>'s can be considered globally unique although there has been a lot of
  17204. debate on this topic in places like
  17205. <a href="https://github.com/matrix-org/matrix-spec-proposals/issues/2779">MSC2779</a> and
  17206. <a href="https://github.com/matrix-org/matrix-spec-proposals/pull/2848">MSC2848</a> which
  17207. has no resolution yet (as of 2022-09-01). There are several places in Synapse
  17208. and even in the Matrix APIs like <a href="https://spec.matrix.org/v1.1/server-server-api/#get_matrixfederationv1eventeventid"><code>GET /_matrix/federation/v1/event/{eventId}</code></a>
  17209. where we assume that event IDs are globally unique.</p>
  17210. <p>When scoping <code>event_id</code> in a database schema, it is often nice to accompany it
  17211. with <code>room_id</code> (<code>PRIMARY KEY (room_id, event_id)</code> and a <code>FOREIGN KEY(room_id) REFERENCES rooms(room_id)</code>) which makes flexible lookups easy. For example it
  17212. makes it very easy to find and clean up everything in a room when it needs to be
  17213. purged (no need to use sub-<code>select</code> query or join from the <code>events</code> table).</p>
  17214. <p>A note on collisions: In room versions <code>1</code> and <code>2</code> it's possible to end up with
  17215. two events with the same <code>event_id</code> (in the same or different rooms). After room
  17216. version <code>3</code>, that can only happen with a hash collision, which we basically hope
  17217. will never happen (SHA256 has a massive big key space).</p>
  17218. <h2 id="worked-examples-of-gradual-migrations"><a class="header" href="#worked-examples-of-gradual-migrations">Worked examples of gradual migrations</a></h2>
  17219. <p>Some migrations need to be performed gradually. A prime example of this is anything
  17220. which would need to do a large table scan — including adding columns, indices or
  17221. <code>NOT NULL</code> constraints to non-empty tables — such a migration should be done as a
  17222. background update where possible, at least on Postgres.
  17223. We can afford to be more relaxed about SQLite databases since they are usually
  17224. used on smaller deployments and SQLite does not support the same concurrent
  17225. DDL operations as Postgres.</p>
  17226. <p>We also typically insist on having at least one Synapse version's worth of
  17227. backwards compatibility, so that administrators can roll back Synapse if an upgrade
  17228. did not go smoothly.</p>
  17229. <p>This sometimes results in having to plan a migration across multiple versions
  17230. of Synapse.</p>
  17231. <p>This section includes an example and may include more in the future.</p>
  17232. <h3 id="transforming-a-column-into-another-one-with-not-null-constraints"><a class="header" href="#transforming-a-column-into-another-one-with-not-null-constraints">Transforming a column into another one, with <code>NOT NULL</code> constraints</a></h3>
  17233. <p>This example illustrates how you would introduce a new column, write data into it
  17234. based on data from an old column and then drop the old column.</p>
  17235. <p>We are aiming for semantic equivalence to:</p>
  17236. <pre><code class="language-sql">ALTER TABLE mytable ADD COLUMN new_column INTEGER;
  17237. UPDATE mytable SET new_column = old_column * 100;
  17238. ALTER TABLE mytable ALTER COLUMN new_column ADD CONSTRAINT NOT NULL;
  17239. ALTER TABLE mytable DROP COLUMN old_column;
  17240. </code></pre>
  17241. <h4 id="synapse-version-n"><a class="header" href="#synapse-version-n">Synapse version <code>N</code></a></h4>
  17242. <pre><code class="language-python">SCHEMA_VERSION = S
  17243. SCHEMA_COMPAT_VERSION = ... # unimportant at this stage
  17244. </code></pre>
  17245. <p><strong>Invariants:</strong></p>
  17246. <ol>
  17247. <li><code>old_column</code> is read by Synapse and written to by Synapse.</li>
  17248. </ol>
  17249. <h4 id="synapse-version-n--1"><a class="header" href="#synapse-version-n--1">Synapse version <code>N + 1</code></a></h4>
  17250. <pre><code class="language-python">SCHEMA_VERSION = S + 1
  17251. SCHEMA_COMPAT_VERSION = ... # unimportant at this stage
  17252. </code></pre>
  17253. <p><strong>Changes:</strong></p>
  17254. <ol>
  17255. <li>
  17256. <pre><code class="language-sql">ALTER TABLE mytable ADD COLUMN new_column INTEGER;
  17257. </code></pre>
  17258. </li>
  17259. </ol>
  17260. <p><strong>Invariants:</strong></p>
  17261. <ol>
  17262. <li><code>old_column</code> is read by Synapse and written to by Synapse.</li>
  17263. <li><code>new_column</code> is written to by Synapse.</li>
  17264. </ol>
  17265. <p><strong>Notes:</strong></p>
  17266. <ol>
  17267. <li><code>new_column</code> can't have a <code>NOT NULL NOT VALID</code> constraint yet, because the previous Synapse version did not write to the new column (since we haven't bumped the <code>SCHEMA_COMPAT_VERSION</code> yet, we still need to be compatible with the previous version).</li>
  17268. </ol>
  17269. <h4 id="synapse-version-n--2"><a class="header" href="#synapse-version-n--2">Synapse version <code>N + 2</code></a></h4>
  17270. <pre><code class="language-python">SCHEMA_VERSION = S + 2
  17271. SCHEMA_COMPAT_VERSION = S + 1 # this signals that we can't roll back to a time before new_column existed
  17272. </code></pre>
  17273. <p><strong>Changes:</strong></p>
  17274. <ol>
  17275. <li>On Postgres, add a <code>NOT VALID</code> constraint to ensure new rows are compliant. <em>SQLite does not have such a construct, but it would be unnecessary anyway since there is no way to concurrently perform this migration on SQLite.</em>
  17276. <pre><code class="language-sql">ALTER TABLE mytable ADD CONSTRAINT CHECK new_column_not_null (new_column IS NOT NULL) NOT VALID;
  17277. </code></pre>
  17278. </li>
  17279. <li>Start a background update to perform migration: it should gradually run e.g.
  17280. <pre><code class="language-sql">UPDATE mytable SET new_column = old_column * 100 WHERE 0 &lt; mytable_id AND mytable_id &lt;= 5;
  17281. </code></pre>
  17282. This background update is technically pointless on SQLite, but you must schedule it anyway so that the <code>portdb</code> script to migrate to Postgres still works.</li>
  17283. <li>Upon completion of the background update, you should run <code>VALIDATE CONSTRAINT</code> on Postgres to turn the <code>NOT VALID</code> constraint into a valid one.
  17284. <pre><code class="language-sql">ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
  17285. </code></pre>
  17286. This will take some time but does <strong>NOT</strong> hold an exclusive lock over the table.</li>
  17287. </ol>
  17288. <p><strong>Invariants:</strong></p>
  17289. <ol>
  17290. <li><code>old_column</code> is read by Synapse and written to by Synapse.</li>
  17291. <li><code>new_column</code> is written to by Synapse and new rows always have a non-<code>NULL</code> value in this field.</li>
  17292. </ol>
  17293. <p><strong>Notes:</strong></p>
  17294. <ol>
  17295. <li>If you wish, you can convert the <code>CHECK (new_column IS NOT NULL)</code> to a <code>NOT NULL</code> constraint free of charge in Postgres by adding the <code>NOT NULL</code> constraint and then dropping the <code>CHECK</code> constraint, because Postgres can statically verify that the <code>NOT NULL</code> constraint is implied by the <code>CHECK</code> constraint without performing a table scan.</li>
  17296. <li>It might be tempting to make version <code>N + 2</code> redundant by moving the background update to <code>N + 1</code> and delaying adding the <code>NOT NULL</code> constraint to <code>N + 3</code>, but that would mean the constraint would always be validated in the foreground in <code>N + 3</code>. Whereas if the <code>N + 2</code> step is kept, the migration in <code>N + 3</code> would be fast in the happy case.</li>
  17297. </ol>
  17298. <h4 id="synapse-version-n--3"><a class="header" href="#synapse-version-n--3">Synapse version <code>N + 3</code></a></h4>
  17299. <pre><code class="language-python">SCHEMA_VERSION = S + 3
  17300. SCHEMA_COMPAT_VERSION = S + 1 # we can't roll back to a time before new_column existed
  17301. </code></pre>
  17302. <p><strong>Changes:</strong></p>
  17303. <ol>
  17304. <li>(Postgres) Update the table to populate values of <code>new_column</code> in case the background update had not completed. Additionally, <code>VALIDATE CONSTRAINT</code> to make the check fully valid.
  17305. <pre><code class="language-sql">-- you ideally want an index on `new_column` or e.g. `(new_column) WHERE new_column IS NULL` first, or perhaps you can find a way to skip this if the `NOT NULL` constraint has already been validated.
  17306. UPDATE mytable SET new_column = old_column * 100 WHERE new_column IS NULL;
  17307. -- this is a no-op if it already ran as part of the background update
  17308. ALTER TABLE mytable VALIDATE CONSTRAINT new_column_not_null;
  17309. </code></pre>
  17310. </li>
  17311. <li>(SQLite) Recreate the table by precisely following <a href="https://www.sqlite.org/lang_altertable.html#otheralter">the 12-step procedure for SQLite table schema changes</a>.
  17312. During this table rewrite, you should recreate <code>new_column</code> as <code>NOT NULL</code> and populate any outstanding <code>NULL</code> values at the same time.
  17313. Unfortunately, you can't drop <code>old_column</code> yet because it must be present for compatibility with the Postgres schema, as needed by <code>portdb</code>.
  17314. (Otherwise you could do this all in one go with SQLite!)</li>
  17315. </ol>
  17316. <p><strong>Invariants:</strong></p>
  17317. <ol>
  17318. <li><code>old_column</code> is written to by Synapse (but no longer read by Synapse!).</li>
  17319. <li><code>new_column</code> is read by Synapse and written to by Synapse. Moreover, all rows have a non-<code>NULL</code> value in this field, as guaranteed by a schema constraint.</li>
  17320. </ol>
  17321. <p><strong>Notes:</strong></p>
  17322. <ol>
  17323. <li>We can't drop <code>old_column</code> yet, or even stop writing to it, because that would break a rollback to the previous version of Synapse.</li>
  17324. <li>Application code can now rely on <code>new_column</code> being populated. The remaining steps are only motivated by the wish to clean-up old columns.</li>
  17325. </ol>
  17326. <h4 id="synapse-version-n--4"><a class="header" href="#synapse-version-n--4">Synapse version <code>N + 4</code></a></h4>
  17327. <pre><code class="language-python">SCHEMA_VERSION = S + 4
  17328. SCHEMA_COMPAT_VERSION = S + 3 # we can't roll back to a time before new_column was entirely non-NULL
  17329. </code></pre>
  17330. <p><strong>Invariants:</strong></p>
  17331. <ol>
  17332. <li><code>old_column</code> exists but is not written to or read from by Synapse.</li>
  17333. <li><code>new_column</code> is read by Synapse and written to by Synapse. Moreover, all rows have a non-<code>NULL</code> value in this field, as guaranteed by a schema constraint.</li>
  17334. </ol>
  17335. <p><strong>Notes:</strong></p>
  17336. <ol>
  17337. <li>We can't drop <code>old_column</code> yet because that would break a rollback to the previous version of Synapse. <br />
  17338. <strong>TODO:</strong> It may be possible to relax this and drop the column straight away as long as the previous version of Synapse detected a rollback occurred and stopped attempting to write to the column. This could possibly be done by checking whether the database's schema compatibility version was <code>S + 3</code>.</li>
  17339. </ol>
  17340. <h4 id="synapse-version-n--5"><a class="header" href="#synapse-version-n--5">Synapse version <code>N + 5</code></a></h4>
  17341. <pre><code class="language-python">SCHEMA_VERSION = S + 5
  17342. SCHEMA_COMPAT_VERSION = S + 4 # we can't roll back to a time before old_column was no longer being touched
  17343. </code></pre>
  17344. <p><strong>Changes:</strong></p>
  17345. <ol>
  17346. <li>
  17347. <pre><code class="language-sql">ALTER TABLE mytable DROP COLUMN old_column;
  17348. </code></pre>
  17349. </li>
  17350. </ol>
  17351. <div style="break-before: page; page-break-before: always;"></div><h1 id="implementing-experimental-features-in-synapse"><a class="header" href="#implementing-experimental-features-in-synapse">Implementing experimental features in Synapse</a></h1>
  17352. <p>It can be desirable to implement &quot;experimental&quot; features which are disabled by
  17353. default and must be explicitly enabled via the Synapse configuration. This is
  17354. applicable for features which:</p>
  17355. <ul>
  17356. <li>Are unstable in the Matrix spec (e.g. those defined by an MSC that has not yet been merged).</li>
  17357. <li>Developers are not confident in their use by general Synapse administrators/users
  17358. (e.g. a feature is incomplete, buggy, performs poorly, or needs further testing).</li>
  17359. </ul>
  17360. <p>Note that this only really applies to features which are expected to be desirable
  17361. to a broad audience. The <a href="development/../modules/index.html">module infrastructure</a> should
  17362. instead be investigated for non-standard features.</p>
  17363. <p>Guarding experimental features behind configuration flags should help with some
  17364. of the following scenarios:</p>
  17365. <ul>
  17366. <li>Ensure that clients do not assume that unstable features exist (failing
  17367. gracefully if they do not).</li>
  17368. <li>Unstable features do not become de-facto standards and can be removed
  17369. aggressively (since only those who have opted-in will be affected).</li>
  17370. <li>Ease finding the implementation of unstable features in Synapse (for future
  17371. removal or stabilization).</li>
  17372. <li>Ease testing a feature (or removal of feature) due to enabling/disabling without
  17373. code changes. It also becomes possible to ask for wider testing, if desired.</li>
  17374. </ul>
  17375. <p>Experimental configuration flags should be disabled by default (requiring Synapse
  17376. administrators to explicitly opt-in), although there are situations where it makes
  17377. sense (from a product point-of-view) to enable features by default. This is
  17378. expected and not an issue.</p>
  17379. <p>It is not a requirement for experimental features to be behind a configuration flag,
  17380. but one should be used if unsure.</p>
  17381. <p>New experimental configuration flags should be added under the <code>experimental</code>
  17382. configuration key (see the <code>synapse.config.experimental</code> file) and either explain
  17383. (briefly) what is being enabled, or include the MSC number.</p>
  17384. <div style="break-before: page; page-break-before: always;"></div><h1 id="managing-dependencies-with-poetry"><a class="header" href="#managing-dependencies-with-poetry">Managing dependencies with Poetry</a></h1>
  17385. <p>This is a quick cheat sheet for developers on how to use <a href="https://python-poetry.org/"><code>poetry</code></a>.</p>
  17386. <h1 id="installing"><a class="header" href="#installing">Installing</a></h1>
  17387. <p>See the <a href="development/contributing_guide.html#4-install-the-dependencies">contributing guide</a>.</p>
  17388. <p>Developers should use Poetry 1.3.2 or higher. If you encounter problems related
  17389. to poetry, please <a href="development/dependencies.html#check-the-version-of-poetry-with-poetry---version">double-check your poetry version</a>.</p>
  17390. <h1 id="background-1"><a class="header" href="#background-1">Background</a></h1>
  17391. <p>Synapse uses a variety of third-party Python packages to function as a homeserver.
  17392. Some of these are direct dependencies, listed in <code>pyproject.toml</code> under the
  17393. <code>[tool.poetry.dependencies]</code> section. The rest are transitive dependencies (the
  17394. things that our direct dependencies themselves depend on, and so on recursively.)</p>
  17395. <p>We maintain a locked list of all our dependencies (transitive included) so that
  17396. we can track exactly which version of each dependency appears in a given release.
  17397. See <a href="https://github.com/matrix-org/synapse/issues/11537#issue-1074469665">here</a>
  17398. for discussion of why we wanted this for Synapse. We chose to use
  17399. <a href="https://python-poetry.org/"><code>poetry</code></a> to manage this locked list; see
  17400. <a href="https://github.com/matrix-org/synapse/issues/11537#issuecomment-1015975819">this comment</a>
  17401. for the reasoning.</p>
  17402. <p>The locked dependencies get included in our &quot;self-contained&quot; releases: namely,
  17403. our docker images and our debian packages. We also use the locked dependencies
  17404. in development and our continuous integration.</p>
  17405. <p>Separately, our &quot;broad&quot; dependencies—the version ranges specified in
  17406. <code>pyproject.toml</code>—are included as metadata in our &quot;sdists&quot; and &quot;wheels&quot; <a href="https://pypi.org/project/matrix-synapse">uploaded
  17407. to PyPI</a>. Installing from PyPI or from
  17408. the Synapse source tree directly will <em>not</em> use the locked dependencies; instead,
  17409. they'll pull in the latest version of each package available at install time.</p>
  17410. <h2 id="example-dependency"><a class="header" href="#example-dependency">Example dependency</a></h2>
  17411. <p>An example may help. We have a broad dependency on
  17412. <a href="https://pypi.org/project/phonenumbers/"><code>phonenumbers</code></a>, as declared in
  17413. this snippet from pyproject.toml <a href="https://github.com/matrix-org/synapse/blob/release-v1.57/pyproject.toml#L133">as of Synapse 1.57</a>:</p>
  17414. <pre><code class="language-toml">[tool.poetry.dependencies]
  17415. # ...
  17416. phonenumbers = &quot;&gt;=8.2.0&quot;
  17417. </code></pre>
  17418. <p>In our lockfile this is
  17419. <a href="https://github.com/matrix-org/synapse/blob/dfc7646504cef3e4ff396c36089e1c6f1b1634de/poetry.lock#L679-L685">pinned</a>
  17420. to version 8.12.44, even though
  17421. <a href="https://pypi.org/project/phonenumbers/#history">newer versions are available</a>.</p>
  17422. <pre><code class="language-toml">[[package]]
  17423. name = &quot;phonenumbers&quot;
  17424. version = &quot;8.12.44&quot;
  17425. description = &quot;Python version of Google's common library for parsing, formatting, storing and validating international phone numbers.&quot;
  17426. category = &quot;main&quot;
  17427. optional = false
  17428. python-versions = &quot;*&quot;
  17429. </code></pre>
  17430. <p>The lockfile also includes a
  17431. <a href="https://github.com/matrix-org/synapse/blob/release-v1.57/poetry.lock#L2178-L2181">cryptographic checksum</a>
  17432. of the sdists and wheels provided for this version of <code>phonenumbers</code>.</p>
  17433. <pre><code class="language-toml">[metadata.files]
  17434. # ...
  17435. phonenumbers = [
  17436. {file = &quot;phonenumbers-8.12.44-py2.py3-none-any.whl&quot;, hash = &quot;sha256:cc1299cf37b309ecab6214297663ab86cb3d64ae37fd5b88e904fe7983a874a6&quot;},
  17437. {file = &quot;phonenumbers-8.12.44.tar.gz&quot;, hash = &quot;sha256:26cfd0257d1704fe2f88caff2caabb70d16a877b1e65b6aae51f9fbbe10aa8ce&quot;},
  17438. ]
  17439. </code></pre>
  17440. <p>We can see this pinned version inside the docker image for that release:</p>
  17441. <pre><code>$ docker pull matrixdotorg/synapse:v1.57.0
  17442. ...
  17443. $ docker run --entrypoint pip matrixdotorg/synapse:v1.57.0 show phonenumbers
  17444. Name: phonenumbers
  17445. Version: 8.12.44
  17446. Summary: Python version of Google's common library for parsing, formatting, storing and validating international phone numbers.
  17447. Home-page: https://github.com/daviddrysdale/python-phonenumbers
  17448. Author: David Drysdale
  17449. Author-email: dmd@lurklurk.org
  17450. License: Apache License 2.0
  17451. Location: /usr/local/lib/python3.9/site-packages
  17452. Requires:
  17453. Required-by: matrix-synapse
  17454. </code></pre>
  17455. <p>Whereas the wheel metadata just contains the broad dependencies:</p>
  17456. <pre><code>$ cd /tmp
  17457. $ wget https://files.pythonhosted.org/packages/ca/5e/d722d572cc5b3092402b783d6b7185901b444427633bd8a6b00ea0dd41b7/matrix_synapse-1.57.0rc1-py3-none-any.whl
  17458. ...
  17459. $ unzip -c matrix_synapse-1.57.0rc1-py3-none-any.whl matrix_synapse-1.57.0rc1.dist-info/METADATA | grep phonenumbers
  17460. Requires-Dist: phonenumbers (&gt;=8.2.0)
  17461. </code></pre>
  17462. <h1 id="tooling-recommendation-direnv"><a class="header" href="#tooling-recommendation-direnv">Tooling recommendation: direnv</a></h1>
  17463. <p><a href="https://direnv.net/"><code>direnv</code></a> is a tool for activating environments in your
  17464. shell inside a given directory. Its support for poetry is unofficial (a
  17465. community wiki recipe only), but works solidly in our experience. We thoroughly
  17466. recommend it for daily use. To use it:</p>
  17467. <ol>
  17468. <li><a href="https://direnv.net/docs/installation.html">Install <code>direnv</code></a> - it's likely
  17469. packaged for your system already.</li>
  17470. <li>Teach direnv about poetry. The <a href="https://github.com/direnv/direnv/wiki/Python#poetry">shell config here</a>
  17471. needs to be added to <code>~/.config/direnv/direnvrc</code> (or more generally <code>$XDG_CONFIG_HOME/direnv/direnvrc</code>).</li>
  17472. <li>Mark the synapse checkout as a poetry project: <code>echo layout poetry &gt; .envrc</code>.</li>
  17473. <li>Convince yourself that you trust this <code>.envrc</code> configuration and project.
  17474. Then formally confirm this to <code>direnv</code> by running <code>direnv allow</code>.</li>
  17475. </ol>
  17476. <p>Then whenever you navigate to the synapse checkout, you should be able to run
  17477. e.g. <code>mypy</code> instead of <code>poetry run mypy</code>; <code>python</code> instead of
  17478. <code>poetry run python</code>; and your shell commands will automatically run in the
  17479. context of poetry's venv, without having to run <code>poetry shell</code> beforehand.</p>
  17480. <h1 id="how-do-i"><a class="header" href="#how-do-i">How do I...</a></h1>
  17481. <h2 id="reset-my-venv-to-the-locked-environment"><a class="header" href="#reset-my-venv-to-the-locked-environment">...reset my venv to the locked environment?</a></h2>
  17482. <pre><code class="language-shell">poetry install --all-extras --sync
  17483. </code></pre>
  17484. <h2 id="delete-everything-and-start-over-from-scratch"><a class="header" href="#delete-everything-and-start-over-from-scratch">...delete everything and start over from scratch?</a></h2>
  17485. <pre><code class="language-shell"># Stop the current virtualenv if active
  17486. $ deactivate
  17487. # Remove all of the files from the current environment.
  17488. # Don't worry, even though it says &quot;all&quot;, this will only
  17489. # remove the Poetry virtualenvs for the current project.
  17490. $ poetry env remove --all
  17491. # Reactivate Poetry shell to create the virtualenv again
  17492. $ poetry shell
  17493. # Install everything again
  17494. $ poetry install --extras all
  17495. </code></pre>
  17496. <h2 id="run-a-command-in-the-poetry-virtualenv"><a class="header" href="#run-a-command-in-the-poetry-virtualenv">...run a command in the <code>poetry</code> virtualenv?</a></h2>
  17497. <p>Use <code>poetry run cmd args</code> when you need the python virtualenv context.
  17498. To avoid typing <code>poetry run</code> all the time, you can run <code>poetry shell</code>
  17499. to start a new shell in the poetry virtualenv context. Within <code>poetry shell</code>,
  17500. <code>python</code>, <code>pip</code>, <code>mypy</code>, <code>trial</code>, etc. are all run inside the project virtualenv
  17501. and isolated from the rest o the system.</p>
  17502. <p>Roughly speaking, the translation from a traditional virtualenv is:</p>
  17503. <ul>
  17504. <li><code>env/bin/activate</code> -&gt; <code>poetry shell</code>, and</li>
  17505. <li><code>deactivate</code> -&gt; close the terminal (Ctrl-D, <code>exit</code>, etc.)</li>
  17506. </ul>
  17507. <p>See also the direnv recommendation above, which makes <code>poetry run</code> and
  17508. <code>poetry shell</code> unnecessary.</p>
  17509. <h2 id="inspect-the-poetry-virtualenv"><a class="header" href="#inspect-the-poetry-virtualenv">...inspect the <code>poetry</code> virtualenv?</a></h2>
  17510. <p>Some suggestions:</p>
  17511. <pre><code class="language-shell"># Current env only
  17512. poetry env info
  17513. # All envs: this allows you to have e.g. a poetry managed venv for Python 3.7,
  17514. # and another for Python 3.10.
  17515. poetry env list --full-path
  17516. poetry run pip list
  17517. </code></pre>
  17518. <p>Note that <code>poetry show</code> describes the abstract <em>lock file</em> rather than your
  17519. on-disk environment. With that said, <code>poetry show --tree</code> can sometimes be
  17520. useful.</p>
  17521. <h2 id="add-a-new-dependency"><a class="header" href="#add-a-new-dependency">...add a new dependency?</a></h2>
  17522. <p>Either:</p>
  17523. <ul>
  17524. <li>manually update <code>pyproject.toml</code>; then <code>poetry lock --no-update</code>; or else</li>
  17525. <li><code>poetry add packagename</code>. See <code>poetry add --help</code>; note the <code>--dev</code>,
  17526. <code>--extras</code> and <code>--optional</code> flags in particular.</li>
  17527. </ul>
  17528. <p>Include the updated <code>pyproject.toml</code> and <code>poetry.lock</code> files in your commit.</p>
  17529. <h2 id="remove-a-dependency"><a class="header" href="#remove-a-dependency">...remove a dependency?</a></h2>
  17530. <p>This is not done often and is untested, but</p>
  17531. <pre><code class="language-shell">poetry remove packagename
  17532. </code></pre>
  17533. <p>ought to do the trick. Alternatively, manually update <code>pyproject.toml</code> and
  17534. <code>poetry lock --no-update</code>. Include the updated <code>pyproject.toml</code> and <code>poetry.lock</code>
  17535. files in your commit.</p>
  17536. <h2 id="update-the-version-range-for-an-existing-dependency"><a class="header" href="#update-the-version-range-for-an-existing-dependency">...update the version range for an existing dependency?</a></h2>
  17537. <p>Best done by manually editing <code>pyproject.toml</code>, then <code>poetry lock --no-update</code>.
  17538. Include the updated <code>pyproject.toml</code> and <code>poetry.lock</code> in your commit.</p>
  17539. <h2 id="update-a-dependency-in-the-locked-environment"><a class="header" href="#update-a-dependency-in-the-locked-environment">...update a dependency in the locked environment?</a></h2>
  17540. <p>Use</p>
  17541. <pre><code class="language-shell">poetry update packagename
  17542. </code></pre>
  17543. <p>to use the latest version of <code>packagename</code> in the locked environment, without
  17544. affecting the broad dependencies listed in the wheel.</p>
  17545. <p>There doesn't seem to be a way to do this whilst locking a <em>specific</em> version of
  17546. <code>packagename</code>. We can workaround this (crudely) as follows:</p>
  17547. <pre><code class="language-shell">poetry add packagename==1.2.3
  17548. # This should update pyproject.lock.
  17549. # Now undo the changes to pyproject.toml. For example
  17550. # git restore pyproject.toml
  17551. # Get poetry to recompute the content-hash of pyproject.toml without changing
  17552. # the locked package versions.
  17553. poetry lock --no-update
  17554. </code></pre>
  17555. <p>Either way, include the updated <code>poetry.lock</code> file in your commit.</p>
  17556. <h2 id="export-a-requirementstxt-file"><a class="header" href="#export-a-requirementstxt-file">...export a <code>requirements.txt</code> file?</a></h2>
  17557. <pre><code class="language-shell">poetry export --extras all
  17558. </code></pre>
  17559. <p>Be wary of bugs in <code>poetry export</code> and <code>pip install -r requirements.txt</code>.</p>
  17560. <h2 id="build-a-test-wheel"><a class="header" href="#build-a-test-wheel">...build a test wheel?</a></h2>
  17561. <p>I usually use</p>
  17562. <pre><code class="language-shell">poetry run pip install build &amp;&amp; poetry run python -m build
  17563. </code></pre>
  17564. <p>because <a href="https://github.com/pypa/build"><code>build</code></a> is a standardish tool which
  17565. doesn't require poetry. (It's what we use in CI too). However, you could try
  17566. <code>poetry build</code> too.</p>
  17567. <h2 id="handle-a-dependabot-pull-request"><a class="header" href="#handle-a-dependabot-pull-request">...handle a Dependabot pull request?</a></h2>
  17568. <p>Synapse uses Dependabot to keep the <code>poetry.lock</code> and <code>Cargo.lock</code> file
  17569. up-to-date with the latest releases of our dependencies. The changelog check is
  17570. omitted for Dependabot PRs; the release script will include them in the
  17571. changelog.</p>
  17572. <p>When reviewing a dependabot PR, ensure that:</p>
  17573. <ul>
  17574. <li>the lockfile changes look reasonable;</li>
  17575. <li>the upstream changelog file (linked in the description) doesn't include any
  17576. breaking changes;</li>
  17577. <li>continuous integration passes.</li>
  17578. </ul>
  17579. <p>In particular, any updates to the type hints (usually packages which start with <code>types-</code>)
  17580. should be safe to merge if linting passes.</p>
  17581. <h1 id="troubleshooting-4"><a class="header" href="#troubleshooting-4">Troubleshooting</a></h1>
  17582. <h2 id="check-the-version-of-poetry-with-poetry---version"><a class="header" href="#check-the-version-of-poetry-with-poetry---version">Check the version of poetry with <code>poetry --version</code>.</a></h2>
  17583. <p>The minimum version of poetry supported by Synapse is 1.3.2.</p>
  17584. <p>It can also be useful to check the version of <code>poetry-core</code> in use. If you've
  17585. installed <code>poetry</code> with <code>pipx</code>, try <code>pipx runpip poetry list | grep poetry-core</code>.</p>
  17586. <h2 id="clear-caches-poetry-cache-clear---all-pypi"><a class="header" href="#clear-caches-poetry-cache-clear---all-pypi">Clear caches: <code>poetry cache clear --all pypi</code>.</a></h2>
  17587. <p>Poetry caches a bunch of information about packages that isn't readily available
  17588. from PyPI. (This is what makes poetry seem slow when doing the first
  17589. <code>poetry install</code>.) Try <code>poetry cache list</code> and <code>poetry cache clear --all &lt;name of cache&gt;</code> to see if that fixes things.</p>
  17590. <h2 id="remove-outdated-egg-info"><a class="header" href="#remove-outdated-egg-info">Remove outdated egg-info</a></h2>
  17591. <p>Delete the <code>matrix_synapse.egg-info/</code> directory from the root of your Synapse
  17592. install.</p>
  17593. <p>This stores some cached information about dependencies and often conflicts with
  17594. letting Poetry do the right thing.</p>
  17595. <h2 id="try---verbose-or---dry-run-arguments"><a class="header" href="#try---verbose-or---dry-run-arguments">Try <code>--verbose</code> or <code>--dry-run</code> arguments.</a></h2>
  17596. <p>Sometimes useful to see what poetry's internal logic is.</p>
  17597. <div style="break-before: page; page-break-before: always;"></div><h1 id="cancellation"><a class="header" href="#cancellation">Cancellation</a></h1>
  17598. <p>Sometimes, requests take a long time to service and clients disconnect
  17599. before Synapse produces a response. To avoid wasting resources, Synapse
  17600. can cancel request processing for select endpoints marked with the
  17601. <code>@cancellable</code> decorator.</p>
  17602. <p>Synapse makes use of Twisted's <code>Deferred.cancel()</code> feature to make
  17603. cancellation work. The <code>@cancellable</code> decorator does nothing by itself
  17604. and merely acts as a flag, signalling to developers and other code alike
  17605. that a method can be cancelled.</p>
  17606. <h2 id="enabling-cancellation-for-an-endpoint"><a class="header" href="#enabling-cancellation-for-an-endpoint">Enabling cancellation for an endpoint</a></h2>
  17607. <ol>
  17608. <li>Check that the endpoint method, and any <code>async</code> functions in its call
  17609. tree handle cancellation correctly. See
  17610. <a href="development/synapse_architecture/cancellation.html#handling-cancellation-correctly">Handling cancellation correctly</a>
  17611. for a list of things to look out for.</li>
  17612. <li>Add the <code>@cancellable</code> decorator to the <code>on_GET/POST/PUT/DELETE</code>
  17613. method. It's not recommended to make non-<code>GET</code> methods cancellable,
  17614. since cancellation midway through some database updates is less
  17615. likely to be handled correctly.</li>
  17616. </ol>
  17617. <h2 id="mechanics"><a class="header" href="#mechanics">Mechanics</a></h2>
  17618. <p>There are two stages to cancellation: downward propagation of a
  17619. <code>cancel()</code> call, followed by upwards propagation of a <code>CancelledError</code>
  17620. out of a blocked <code>await</code>.
  17621. Both Twisted and asyncio have a cancellation mechanism.</p>
  17622. <table><thead><tr><th></th><th>Method</th><th>Exception</th><th>Exception inherits from</th></tr></thead><tbody>
  17623. <tr><td>Twisted</td><td><code>Deferred.cancel()</code></td><td><code>twisted.internet.defer.CancelledError</code></td><td><code>Exception</code> (!)</td></tr>
  17624. <tr><td>asyncio</td><td><code>Task.cancel()</code></td><td><code>asyncio.CancelledError</code></td><td><code>BaseException</code></td></tr>
  17625. </tbody></table>
  17626. <h3 id="deferredcancel"><a class="header" href="#deferredcancel">Deferred.cancel()</a></h3>
  17627. <p>When Synapse starts handling a request, it runs the async method
  17628. responsible for handling it using <code>defer.ensureDeferred</code>, which returns
  17629. a <code>Deferred</code>. For example:</p>
  17630. <pre><code class="language-python">def do_something() -&gt; Deferred[None]:
  17631. ...
  17632. @cancellable
  17633. async def on_GET() -&gt; Tuple[int, JsonDict]:
  17634. d = make_deferred_yieldable(do_something())
  17635. await d
  17636. return 200, {}
  17637. request = defer.ensureDeferred(on_GET())
  17638. </code></pre>
  17639. <p>When a client disconnects early, Synapse checks for the presence of the
  17640. <code>@cancellable</code> decorator on <code>on_GET</code>. Since <code>on_GET</code> is cancellable,
  17641. <code>Deferred.cancel()</code> is called on the <code>Deferred</code> from
  17642. <code>defer.ensureDeferred</code>, ie. <code>request</code>. Twisted knows which <code>Deferred</code>
  17643. <code>request</code> is waiting on and passes the <code>cancel()</code> call on to <code>d</code>.</p>
  17644. <p>The <code>Deferred</code> being waited on, <code>d</code>, may have its own handling for
  17645. <code>cancel()</code> and pass the call on to other <code>Deferred</code>s.</p>
  17646. <p>Eventually, a <code>Deferred</code> handles the <code>cancel()</code> call by resolving itself
  17647. with a <code>CancelledError</code>.</p>
  17648. <h3 id="cancellederror"><a class="header" href="#cancellederror">CancelledError</a></h3>
  17649. <p>The <code>CancelledError</code> gets raised out of the <code>await</code> and bubbles up, as
  17650. per normal Python exception handling.</p>
  17651. <h2 id="handling-cancellation-correctly"><a class="header" href="#handling-cancellation-correctly">Handling cancellation correctly</a></h2>
  17652. <p>In general, when writing code that might be subject to cancellation, two
  17653. things must be considered:</p>
  17654. <ul>
  17655. <li>The effect of <code>CancelledError</code>s raised out of <code>await</code>s.</li>
  17656. <li>The effect of <code>Deferred</code>s being <code>cancel()</code>ed.</li>
  17657. </ul>
  17658. <p>Examples of code that handles cancellation incorrectly include:</p>
  17659. <ul>
  17660. <li><code>try-except</code> blocks which swallow <code>CancelledError</code>s.</li>
  17661. <li>Code that shares the same <code>Deferred</code>, which may be cancelled, between
  17662. multiple requests.</li>
  17663. <li>Code that starts some processing that's exempt from cancellation, but
  17664. uses a logging context from cancellable code. The logging context
  17665. will be finished upon cancellation, while the uncancelled processing
  17666. is still using it.</li>
  17667. </ul>
  17668. <p>Some common patterns are listed below in more detail.</p>
  17669. <h3 id="async-function-calls"><a class="header" href="#async-function-calls"><code>async</code> function calls</a></h3>
  17670. <p>Most functions in Synapse are relatively straightforward from a
  17671. cancellation standpoint: they don't do anything with <code>Deferred</code>s and
  17672. purely call and <code>await</code> other <code>async</code> functions.</p>
  17673. <p>An <code>async</code> function handles cancellation correctly if its own code
  17674. handles cancellation correctly and all the async function it calls
  17675. handle cancellation correctly. For example:</p>
  17676. <pre><code class="language-python">async def do_two_things() -&gt; None:
  17677. check_something()
  17678. await do_something()
  17679. await do_something_else()
  17680. </code></pre>
  17681. <p><code>do_two_things</code> handles cancellation correctly if <code>do_something</code> and
  17682. <code>do_something_else</code> handle cancellation correctly.</p>
  17683. <p>That is, when checking whether a function handles cancellation
  17684. correctly, its implementation and all its <code>async</code> function calls need to
  17685. be checked, recursively.</p>
  17686. <p>As <code>check_something</code> is not <code>async</code>, it does not need to be checked.</p>
  17687. <h3 id="cancellederrors"><a class="header" href="#cancellederrors">CancelledErrors</a></h3>
  17688. <p>Because Twisted's <code>CancelledError</code>s are <code>Exception</code>s, it's easy to
  17689. accidentally catch and suppress them. Care must be taken to ensure that
  17690. <code>CancelledError</code>s are allowed to propagate upwards.</p>
  17691. <table width="100%">
  17692. <tr>
  17693. <td width="50%" valign="top">
  17694. <p><strong>Bad</strong>:</p>
  17695. <pre><code class="language-python">try:
  17696. await do_something()
  17697. except Exception:
  17698. # `CancelledError` gets swallowed here.
  17699. logger.info(...)
  17700. </code></pre>
  17701. </td>
  17702. <td width="50%" valign="top">
  17703. <p><strong>Good</strong>:</p>
  17704. <pre><code class="language-python">try:
  17705. await do_something()
  17706. except CancelledError:
  17707. raise
  17708. except Exception:
  17709. logger.info(...)
  17710. </code></pre>
  17711. </td>
  17712. </tr>
  17713. <tr>
  17714. <td width="50%" valign="top">
  17715. <p><strong>OK</strong>:</p>
  17716. <pre><code class="language-python">try:
  17717. check_something()
  17718. # A `CancelledError` won't ever be raised here.
  17719. except Exception:
  17720. logger.info(...)
  17721. </code></pre>
  17722. </td>
  17723. <td width="50%" valign="top">
  17724. <p><strong>Good</strong>:</p>
  17725. <pre><code class="language-python">try:
  17726. await do_something()
  17727. except ValueError:
  17728. logger.info(...)
  17729. </code></pre>
  17730. </td>
  17731. </tr>
  17732. </table>
  17733. <h4 id="defergatherresults"><a class="header" href="#defergatherresults">defer.gatherResults</a></h4>
  17734. <p><code>defer.gatherResults</code> produces a <code>Deferred</code> which:</p>
  17735. <ul>
  17736. <li>broadcasts <code>cancel()</code> calls to every <code>Deferred</code> being waited on.</li>
  17737. <li>wraps the first exception it sees in a <code>FirstError</code>.</li>
  17738. </ul>
  17739. <p>Together, this means that <code>CancelledError</code>s will be wrapped in
  17740. a <code>FirstError</code> unless unwrapped. Such <code>FirstError</code>s are liable to be
  17741. swallowed, so they must be unwrapped.</p>
  17742. <table width="100%">
  17743. <tr>
  17744. <td width="50%" valign="top">
  17745. <p><strong>Bad</strong>:</p>
  17746. <pre><code class="language-python">async def do_something() -&gt; None:
  17747. await make_deferred_yieldable(
  17748. defer.gatherResults([...], consumeErrors=True)
  17749. )
  17750. try:
  17751. await do_something()
  17752. except CancelledError:
  17753. raise
  17754. except Exception:
  17755. # `FirstError(CancelledError)` gets swallowed here.
  17756. logger.info(...)
  17757. </code></pre>
  17758. </td>
  17759. <td width="50%" valign="top">
  17760. <p><strong>Good</strong>:</p>
  17761. <pre><code class="language-python">async def do_something() -&gt; None:
  17762. await make_deferred_yieldable(
  17763. defer.gatherResults([...], consumeErrors=True)
  17764. ).addErrback(unwrapFirstError)
  17765. try:
  17766. await do_something()
  17767. except CancelledError:
  17768. raise
  17769. except Exception:
  17770. logger.info(...)
  17771. </code></pre>
  17772. </td>
  17773. </tr>
  17774. </table>
  17775. <h3 id="creation-of-deferreds"><a class="header" href="#creation-of-deferreds">Creation of <code>Deferred</code>s</a></h3>
  17776. <p>If a function creates a <code>Deferred</code>, the effect of cancelling it must be considered. <code>Deferred</code>s that get shared are likely to have unintended behaviour when cancelled.</p>
  17777. <table width="100%">
  17778. <tr>
  17779. <td width="50%" valign="top">
  17780. <p><strong>Bad</strong>:</p>
  17781. <pre><code class="language-python">cache: Dict[str, Deferred[None]] = {}
  17782. def wait_for_room(room_id: str) -&gt; Deferred[None]:
  17783. deferred = cache.get(room_id)
  17784. if deferred is None:
  17785. deferred = Deferred()
  17786. cache[room_id] = deferred
  17787. # `deferred` can have multiple waiters.
  17788. # All of them will observe a `CancelledError`
  17789. # if any one of them is cancelled.
  17790. return make_deferred_yieldable(deferred)
  17791. # Request 1
  17792. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17793. # Request 2
  17794. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17795. </code></pre>
  17796. </td>
  17797. <td width="50%" valign="top">
  17798. <p><strong>Good</strong>:</p>
  17799. <pre><code class="language-python">cache: Dict[str, Deferred[None]] = {}
  17800. def wait_for_room(room_id: str) -&gt; Deferred[None]:
  17801. deferred = cache.get(room_id)
  17802. if deferred is None:
  17803. deferred = Deferred()
  17804. cache[room_id] = deferred
  17805. # `deferred` will never be cancelled now.
  17806. # A `CancelledError` will still come out of
  17807. # the `await`.
  17808. # `delay_cancellation` may also be used.
  17809. return make_deferred_yieldable(stop_cancellation(deferred))
  17810. # Request 1
  17811. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17812. # Request 2
  17813. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17814. </code></pre>
  17815. </td>
  17816. </tr>
  17817. <tr>
  17818. <td width="50%" valign="top">
  17819. </td>
  17820. <td width="50%" valign="top">
  17821. <p><strong>Good</strong>:</p>
  17822. <pre><code class="language-python">cache: Dict[str, List[Deferred[None]]] = {}
  17823. def wait_for_room(room_id: str) -&gt; Deferred[None]:
  17824. if room_id not in cache:
  17825. cache[room_id] = []
  17826. # Each request gets its own `Deferred` to wait on.
  17827. deferred = Deferred()
  17828. cache[room_id]].append(deferred)
  17829. return make_deferred_yieldable(deferred)
  17830. # Request 1
  17831. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17832. # Request 2
  17833. await wait_for_room(&quot;!aAAaaAaaaAAAaAaAA:matrix.org&quot;)
  17834. </code></pre>
  17835. </td>
  17836. </table>
  17837. <h3 id="uncancelled-processing"><a class="header" href="#uncancelled-processing">Uncancelled processing</a></h3>
  17838. <p>Some <code>async</code> functions may kick off some <code>async</code> processing which is
  17839. intentionally protected from cancellation, by <code>stop_cancellation</code> or
  17840. other means. If the <code>async</code> processing inherits the logcontext of the
  17841. request which initiated it, care must be taken to ensure that the
  17842. logcontext is not finished before the <code>async</code> processing completes.</p>
  17843. <table width="100%">
  17844. <tr>
  17845. <td width="50%" valign="top">
  17846. <p><strong>Bad</strong>:</p>
  17847. <pre><code class="language-python">cache: Optional[ObservableDeferred[None]] = None
  17848. async def do_something_else(
  17849. to_resolve: Deferred[None]
  17850. ) -&gt; None:
  17851. await ...
  17852. logger.info(&quot;done!&quot;)
  17853. to_resolve.callback(None)
  17854. async def do_something() -&gt; None:
  17855. if not cache:
  17856. to_resolve = Deferred()
  17857. cache = ObservableDeferred(to_resolve)
  17858. # `do_something_else` will never be cancelled and
  17859. # can outlive the `request-1` logging context.
  17860. run_in_background(do_something_else, to_resolve)
  17861. await make_deferred_yieldable(cache.observe())
  17862. with LoggingContext(&quot;request-1&quot;):
  17863. await do_something()
  17864. </code></pre>
  17865. </td>
  17866. <td width="50%" valign="top">
  17867. <p><strong>Good</strong>:</p>
  17868. <pre><code class="language-python">cache: Optional[ObservableDeferred[None]] = None
  17869. async def do_something_else(
  17870. to_resolve: Deferred[None]
  17871. ) -&gt; None:
  17872. await ...
  17873. logger.info(&quot;done!&quot;)
  17874. to_resolve.callback(None)
  17875. async def do_something() -&gt; None:
  17876. if not cache:
  17877. to_resolve = Deferred()
  17878. cache = ObservableDeferred(to_resolve)
  17879. run_in_background(do_something_else, to_resolve)
  17880. # We'll wait until `do_something_else` is
  17881. # done before raising a `CancelledError`.
  17882. await make_deferred_yieldable(
  17883. delay_cancellation(cache.observe())
  17884. )
  17885. else:
  17886. await make_deferred_yieldable(cache.observe())
  17887. with LoggingContext(&quot;request-1&quot;):
  17888. await do_something()
  17889. </code></pre>
  17890. </td>
  17891. </tr>
  17892. <tr>
  17893. <td width="50%">
  17894. <p><strong>OK</strong>:</p>
  17895. <pre><code class="language-python">cache: Optional[ObservableDeferred[None]] = None
  17896. async def do_something_else(
  17897. to_resolve: Deferred[None]
  17898. ) -&gt; None:
  17899. await ...
  17900. logger.info(&quot;done!&quot;)
  17901. to_resolve.callback(None)
  17902. async def do_something() -&gt; None:
  17903. if not cache:
  17904. to_resolve = Deferred()
  17905. cache = ObservableDeferred(to_resolve)
  17906. # `do_something_else` will get its own independent
  17907. # logging context. `request-1` will not count any
  17908. # metrics from `do_something_else`.
  17909. run_as_background_process(
  17910. &quot;do_something_else&quot;,
  17911. do_something_else,
  17912. to_resolve,
  17913. )
  17914. await make_deferred_yieldable(cache.observe())
  17915. with LoggingContext(&quot;request-1&quot;):
  17916. await do_something()
  17917. </code></pre>
  17918. </td>
  17919. <td width="50%">
  17920. </td>
  17921. </tr>
  17922. </table>
  17923. <div style="break-before: page; page-break-before: always;"></div><h1 id="log-contexts"><a class="header" href="#log-contexts">Log Contexts</a></h1>
  17924. <p>To help track the processing of individual requests, synapse uses a
  17925. '<code>log context</code>' to track which request it is handling at any given
  17926. moment. This is done via a thread-local variable; a <code>logging.Filter</code> is
  17927. then used to fish the information back out of the thread-local variable
  17928. and add it to each log record.</p>
  17929. <p>Logcontexts are also used for CPU and database accounting, so that we
  17930. can track which requests were responsible for high CPU use or database
  17931. activity.</p>
  17932. <p>The <code>synapse.logging.context</code> module provides facilities for managing
  17933. the current log context (as well as providing the <code>LoggingContextFilter</code>
  17934. class).</p>
  17935. <p>Asynchronous functions make the whole thing complicated, so this document describes
  17936. how it all works, and how to write code which follows the rules.</p>
  17937. <p>In this document, &quot;awaitable&quot; refers to any object which can be <code>await</code>ed. In the context of
  17938. Synapse, that normally means either a coroutine or a Twisted
  17939. <a href="https://twistedmatrix.com/documents/current/api/twisted.internet.defer.Deferred.html"><code>Deferred</code></a>.</p>
  17940. <h2 id="logcontexts-without-asynchronous-code"><a class="header" href="#logcontexts-without-asynchronous-code">Logcontexts without asynchronous code</a></h2>
  17941. <p>In the absence of any asynchronous voodoo, things are simple enough. As with
  17942. any code of this nature, the rule is that our function should leave
  17943. things as it found them:</p>
  17944. <pre><code class="language-python">from synapse.logging import context # omitted from future snippets
  17945. def handle_request(request_id):
  17946. request_context = context.LoggingContext()
  17947. calling_context = context.set_current_context(request_context)
  17948. try:
  17949. request_context.request = request_id
  17950. do_request_handling()
  17951. logger.debug(&quot;finished&quot;)
  17952. finally:
  17953. context.set_current_context(calling_context)
  17954. def do_request_handling():
  17955. logger.debug(&quot;phew&quot;) # this will be logged against request_id
  17956. </code></pre>
  17957. <p>LoggingContext implements the context management methods, so the above
  17958. can be written much more succinctly as:</p>
  17959. <pre><code class="language-python">def handle_request(request_id):
  17960. with context.LoggingContext() as request_context:
  17961. request_context.request = request_id
  17962. do_request_handling()
  17963. logger.debug(&quot;finished&quot;)
  17964. def do_request_handling():
  17965. logger.debug(&quot;phew&quot;)
  17966. </code></pre>
  17967. <h2 id="using-logcontexts-with-awaitables"><a class="header" href="#using-logcontexts-with-awaitables">Using logcontexts with awaitables</a></h2>
  17968. <p>Awaitables break the linear flow of code so that there is no longer a single entry point
  17969. where we should set the logcontext and a single exit point where we should remove it.</p>
  17970. <p>Consider the example above, where <code>do_request_handling</code> needs to do some
  17971. blocking operation, and returns an awaitable:</p>
  17972. <pre><code class="language-python">async def handle_request(request_id):
  17973. with context.LoggingContext() as request_context:
  17974. request_context.request = request_id
  17975. await do_request_handling()
  17976. logger.debug(&quot;finished&quot;)
  17977. </code></pre>
  17978. <p>In the above flow:</p>
  17979. <ul>
  17980. <li>The logcontext is set</li>
  17981. <li><code>do_request_handling</code> is called, and returns an awaitable</li>
  17982. <li><code>handle_request</code> awaits the awaitable</li>
  17983. <li>Execution of <code>handle_request</code> is suspended</li>
  17984. </ul>
  17985. <p>So we have stopped processing the request (and will probably go on to
  17986. start processing the next), without clearing the logcontext.</p>
  17987. <p>To circumvent this problem, synapse code assumes that, wherever you have
  17988. an awaitable, you will want to <code>await</code> it. To that end, wherever
  17989. functions return awaitables, we adopt the following conventions:</p>
  17990. <p><strong>Rules for functions returning awaitables:</strong></p>
  17991. <blockquote>
  17992. <ul>
  17993. <li>If the awaitable is already complete, the function returns with the
  17994. same logcontext it started with.</li>
  17995. <li>If the awaitable is incomplete, the function clears the logcontext
  17996. before returning; when the awaitable completes, it restores the
  17997. logcontext before running any callbacks.</li>
  17998. </ul>
  17999. </blockquote>
  18000. <p>That sounds complicated, but actually it means a lot of code (including
  18001. the example above) &quot;just works&quot;. There are two cases:</p>
  18002. <ul>
  18003. <li>
  18004. <p>If <code>do_request_handling</code> returns a completed awaitable, then the
  18005. logcontext will still be in place. In this case, execution will
  18006. continue immediately after the <code>await</code>; the &quot;finished&quot; line will
  18007. be logged against the right context, and the <code>with</code> block restores
  18008. the original context before we return to the caller.</p>
  18009. </li>
  18010. <li>
  18011. <p>If the returned awaitable is incomplete, <code>do_request_handling</code> clears
  18012. the logcontext before returning. The logcontext is therefore clear
  18013. when <code>handle_request</code> <code>await</code>s the awaitable.</p>
  18014. <p>Once <code>do_request_handling</code>'s awaitable completes, it will reinstate
  18015. the logcontext, before running the second half of <code>handle_request</code>,
  18016. so again the &quot;finished&quot; line will be logged against the right context,
  18017. and the <code>with</code> block restores the original context.</p>
  18018. </li>
  18019. </ul>
  18020. <p>As an aside, it's worth noting that <code>handle_request</code> follows our rules</p>
  18021. <ul>
  18022. <li>though that only matters if the caller has its own logcontext which it
  18023. cares about.</li>
  18024. </ul>
  18025. <p>The following sections describe pitfalls and helpful patterns when
  18026. implementing these rules.</p>
  18027. <h2 id="always-await-your-awaitables"><a class="header" href="#always-await-your-awaitables">Always await your awaitables</a></h2>
  18028. <p>Whenever you get an awaitable back from a function, you should <code>await</code> on
  18029. it as soon as possible. Do not pass go; do not do any logging; do not
  18030. call any other functions.</p>
  18031. <pre><code class="language-python">async def fun():
  18032. logger.debug(&quot;starting&quot;)
  18033. await do_some_stuff() # just like this
  18034. coro = more_stuff()
  18035. result = await coro # also fine, of course
  18036. return result
  18037. </code></pre>
  18038. <p>Provided this pattern is followed all the way back up to the callchain
  18039. to where the logcontext was set, this will make things work out ok:
  18040. provided <code>do_some_stuff</code> and <code>more_stuff</code> follow the rules above, then
  18041. so will <code>fun</code>.</p>
  18042. <p>It's all too easy to forget to <code>await</code>: for instance if we forgot that
  18043. <code>do_some_stuff</code> returned an awaitable, we might plough on regardless. This
  18044. leads to a mess; it will probably work itself out eventually, but not
  18045. before a load of stuff has been logged against the wrong context.
  18046. (Normally, other things will break, more obviously, if you forget to
  18047. <code>await</code>, so this tends not to be a major problem in practice.)</p>
  18048. <p>Of course sometimes you need to do something a bit fancier with your
  18049. awaitable - not all code follows the linear A-then-B-then-C pattern.
  18050. Notes on implementing more complex patterns are in later sections.</p>
  18051. <h2 id="where-you-create-a-new-awaitable-make-it-follow-the-rules"><a class="header" href="#where-you-create-a-new-awaitable-make-it-follow-the-rules">Where you create a new awaitable, make it follow the rules</a></h2>
  18052. <p>Most of the time, an awaitable comes from another synapse function.
  18053. Sometimes, though, we need to make up a new awaitable, or we get an awaitable
  18054. back from external code. We need to make it follow our rules.</p>
  18055. <p>The easy way to do it is by using <code>context.make_deferred_yieldable</code>. Suppose we want to implement
  18056. <code>sleep</code>, which returns a deferred which will run its callbacks after a
  18057. given number of seconds. That might look like:</p>
  18058. <pre><code class="language-python"># not a logcontext-rules-compliant function
  18059. def get_sleep_deferred(seconds):
  18060. d = defer.Deferred()
  18061. reactor.callLater(seconds, d.callback, None)
  18062. return d
  18063. </code></pre>
  18064. <p>That doesn't follow the rules, but we can fix it by calling it through
  18065. <code>context.make_deferred_yieldable</code>:</p>
  18066. <pre><code class="language-python">async def sleep(seconds):
  18067. return await context.make_deferred_yieldable(get_sleep_deferred(seconds))
  18068. </code></pre>
  18069. <h2 id="fire-and-forget"><a class="header" href="#fire-and-forget">Fire-and-forget</a></h2>
  18070. <p>Sometimes you want to fire off a chain of execution, but not wait for
  18071. its result. That might look a bit like this:</p>
  18072. <pre><code class="language-python">async def do_request_handling():
  18073. await foreground_operation()
  18074. # *don't* do this
  18075. background_operation()
  18076. logger.debug(&quot;Request handling complete&quot;)
  18077. async def background_operation():
  18078. await first_background_step()
  18079. logger.debug(&quot;Completed first step&quot;)
  18080. await second_background_step()
  18081. logger.debug(&quot;Completed second step&quot;)
  18082. </code></pre>
  18083. <p>The above code does a couple of steps in the background after
  18084. <code>do_request_handling</code> has finished. The log lines are still logged
  18085. against the <code>request_context</code> logcontext, which may or may not be
  18086. desirable. There are two big problems with the above, however. The first
  18087. problem is that, if <code>background_operation</code> returns an incomplete
  18088. awaitable, it will expect its caller to <code>await</code> immediately, so will have
  18089. cleared the logcontext. In this example, that means that 'Request
  18090. handling complete' will be logged without any context.</p>
  18091. <p>The second problem, which is potentially even worse, is that when the
  18092. awaitable returned by <code>background_operation</code> completes, it will restore
  18093. the original logcontext. There is nothing waiting on that awaitable, so
  18094. the logcontext will leak into the reactor and possibly get attached to
  18095. some arbitrary future operation.</p>
  18096. <p>There are two potential solutions to this.</p>
  18097. <p>One option is to surround the call to <code>background_operation</code> with a
  18098. <code>PreserveLoggingContext</code> call. That will reset the logcontext before
  18099. starting <code>background_operation</code> (so the context restored when the
  18100. deferred completes will be the empty logcontext), and will restore the
  18101. current logcontext before continuing the foreground process:</p>
  18102. <pre><code class="language-python">async def do_request_handling():
  18103. await foreground_operation()
  18104. # start background_operation off in the empty logcontext, to
  18105. # avoid leaking the current context into the reactor.
  18106. with PreserveLoggingContext():
  18107. background_operation()
  18108. # this will now be logged against the request context
  18109. logger.debug(&quot;Request handling complete&quot;)
  18110. </code></pre>
  18111. <p>Obviously that option means that the operations done in
  18112. <code>background_operation</code> would be not be logged against a logcontext
  18113. (though that might be fixed by setting a different logcontext via a
  18114. <code>with LoggingContext(...)</code> in <code>background_operation</code>).</p>
  18115. <p>The second option is to use <code>context.run_in_background</code>, which wraps a
  18116. function so that it doesn't reset the logcontext even when it returns
  18117. an incomplete awaitable, and adds a callback to the returned awaitable to
  18118. reset the logcontext. In other words, it turns a function that follows
  18119. the Synapse rules about logcontexts and awaitables into one which behaves
  18120. more like an external function --- the opposite operation to that
  18121. described in the previous section. It can be used like this:</p>
  18122. <pre><code class="language-python">async def do_request_handling():
  18123. await foreground_operation()
  18124. context.run_in_background(background_operation)
  18125. # this will now be logged against the request context
  18126. logger.debug(&quot;Request handling complete&quot;)
  18127. </code></pre>
  18128. <h2 id="passing-synapse-deferreds-into-third-party-functions"><a class="header" href="#passing-synapse-deferreds-into-third-party-functions">Passing synapse deferreds into third-party functions</a></h2>
  18129. <p>A typical example of this is where we want to collect together two or
  18130. more awaitables via <code>defer.gatherResults</code>:</p>
  18131. <pre><code class="language-python">a1 = operation1()
  18132. a2 = operation2()
  18133. a3 = defer.gatherResults([a1, a2])
  18134. </code></pre>
  18135. <p>This is really a variation of the fire-and-forget problem above, in that
  18136. we are firing off <code>a1</code> and <code>a2</code> without awaiting on them. The difference
  18137. is that we now have third-party code attached to their callbacks. Anyway
  18138. either technique given in the <a href="log_contexts.html#fire-and-forget">Fire-and-forget</a>
  18139. section will work.</p>
  18140. <p>Of course, the new awaitable returned by <code>gather</code> needs to be
  18141. wrapped in order to make it follow the logcontext rules before we can
  18142. yield it, as described in <a href="log_contexts.html#where-you-create-a-new-awaitable-make-it-follow-the-rules">Where you create a new awaitable, make it
  18143. follow the
  18144. rules</a>.</p>
  18145. <p>So, option one: reset the logcontext before starting the operations to
  18146. be gathered:</p>
  18147. <pre><code class="language-python">async def do_request_handling():
  18148. with PreserveLoggingContext():
  18149. a1 = operation1()
  18150. a2 = operation2()
  18151. result = await defer.gatherResults([a1, a2])
  18152. </code></pre>
  18153. <p>In this case particularly, though, option two, of using
  18154. <code>context.run_in_background</code> almost certainly makes more sense, so that
  18155. <code>operation1</code> and <code>operation2</code> are both logged against the original
  18156. logcontext. This looks like:</p>
  18157. <pre><code class="language-python">async def do_request_handling():
  18158. a1 = context.run_in_background(operation1)
  18159. a2 = context.run_in_background(operation2)
  18160. result = await make_deferred_yieldable(defer.gatherResults([a1, a2]))
  18161. </code></pre>
  18162. <h2 id="a-note-on-garbage-collection-of-awaitable-chains"><a class="header" href="#a-note-on-garbage-collection-of-awaitable-chains">A note on garbage-collection of awaitable chains</a></h2>
  18163. <p>It turns out that our logcontext rules do not play nicely with awaitable
  18164. chains which get orphaned and garbage-collected.</p>
  18165. <p>Imagine we have some code that looks like this:</p>
  18166. <pre><code class="language-python">listener_queue = []
  18167. def on_something_interesting():
  18168. for d in listener_queue:
  18169. d.callback(&quot;foo&quot;)
  18170. async def await_something_interesting():
  18171. new_awaitable = defer.Deferred()
  18172. listener_queue.append(new_awaitable)
  18173. with PreserveLoggingContext():
  18174. await new_awaitable
  18175. </code></pre>
  18176. <p>Obviously, the idea here is that we have a bunch of things which are
  18177. waiting for an event. (It's just an example of the problem here, but a
  18178. relatively common one.)</p>
  18179. <p>Now let's imagine two further things happen. First of all, whatever was
  18180. waiting for the interesting thing goes away. (Perhaps the request times
  18181. out, or something <em>even more</em> interesting happens.)</p>
  18182. <p>Secondly, let's suppose that we decide that the interesting thing is
  18183. never going to happen, and we reset the listener queue:</p>
  18184. <pre><code class="language-python">def reset_listener_queue():
  18185. listener_queue.clear()
  18186. </code></pre>
  18187. <p>So, both ends of the awaitable chain have now dropped their references,
  18188. and the awaitable chain is now orphaned, and will be garbage-collected at
  18189. some point. Note that <code>await_something_interesting</code> is a coroutine,
  18190. which Python implements as a generator function. When Python
  18191. garbage-collects generator functions, it gives them a chance to
  18192. clean up by making the <code>await</code> (or <code>yield</code>) raise a <code>GeneratorExit</code>
  18193. exception. In our case, that means that the <code>__exit__</code> handler of
  18194. <code>PreserveLoggingContext</code> will carefully restore the request context, but
  18195. there is now nothing waiting for its return, so the request context is
  18196. never cleared.</p>
  18197. <p>To reiterate, this problem only arises when <em>both</em> ends of a awaitable
  18198. chain are dropped. Dropping the the reference to an awaitable you're
  18199. supposed to be awaiting is bad practice, so this doesn't
  18200. actually happen too much. Unfortunately, when it does happen, it will
  18201. lead to leaked logcontexts which are incredibly hard to track down.</p>
  18202. <div style="break-before: page; page-break-before: always;"></div><h1 id="replication-architecture"><a class="header" href="#replication-architecture">Replication Architecture</a></h1>
  18203. <h2 id="motivation"><a class="header" href="#motivation">Motivation</a></h2>
  18204. <p>We'd like to be able to split some of the work that synapse does into
  18205. multiple python processes. In theory multiple synapse processes could
  18206. share a single postgresql database and we'd scale up by running more
  18207. synapse processes. However much of synapse assumes that only one process
  18208. is interacting with the database, both for assigning unique identifiers
  18209. when inserting into tables, notifying components about new updates, and
  18210. for invalidating its caches.</p>
  18211. <p>So running multiple copies of the current code isn't an option. One way
  18212. to run multiple processes would be to have a single writer process and
  18213. multiple reader processes connected to the same database. In order to do
  18214. this we'd need a way for the reader process to invalidate its in-memory
  18215. caches when an update happens on the writer. One way to do this is for
  18216. the writer to present an append-only log of updates which the readers
  18217. can consume to invalidate their caches and to push updates to listening
  18218. clients or pushers.</p>
  18219. <p>Synapse already stores much of its data as an append-only log so that it
  18220. can correctly respond to <code>/sync</code> requests so the amount of code changes
  18221. needed to expose the append-only log to the readers should be fairly
  18222. minimal.</p>
  18223. <h2 id="architecture"><a class="header" href="#architecture">Architecture</a></h2>
  18224. <h3 id="the-replication-protocol"><a class="header" href="#the-replication-protocol">The Replication Protocol</a></h3>
  18225. <p>See <a href="tcp_replication.html">the TCP replication documentation</a>.</p>
  18226. <h3 id="the-tcp-replication-module"><a class="header" href="#the-tcp-replication-module">The TCP Replication Module</a></h3>
  18227. <p>Information about how the tcp replication module is structured, including how
  18228. the classes interact, can be found in
  18229. <code>synapse/replication/tcp/__init__.py</code></p>
  18230. <div style="break-before: page; page-break-before: always;"></div><h2 id="streams"><a class="header" href="#streams">Streams</a></h2>
  18231. <p>Synapse has a concept of &quot;streams&quot;, which are roughly described in <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/storage/util/id_generators.py"><code>id_generators.py</code></a>.
  18232. Generally speaking, streams are a series of notifications that something in Synapse's database has changed that the application might need to respond to.
  18233. For example:</p>
  18234. <ul>
  18235. <li>The events stream reports new events (PDUs) that Synapse creates, or that Synapse accepts from another homeserver.</li>
  18236. <li>The account data stream reports changes to users' <a href="https://spec.matrix.org/v1.7/client-server-api/#client-config">account data</a>.</li>
  18237. <li>The to-device stream reports when a device has a new <a href="https://spec.matrix.org/v1.7/client-server-api/#send-to-device-messaging">to-device message</a>.</li>
  18238. </ul>
  18239. <p>See <a href="https://github.com/matrix-org/synapse/blob/develop/synapse/replication/tcp/streams/__init__.py"><code>synapse.replication.tcp.streams</code></a> for the full list of streams.</p>
  18240. <p>It is very helpful to understand the streams mechanism when working on any part of Synapse that needs to respond to changes—especially if those changes are made by different workers.
  18241. To that end, let's describe streams formally, paraphrasing from the docstring of <a href="https://github.com/matrix-org/synapse/blob/a719b703d9bd0dade2565ddcad0e2f3a7a9d4c37/synapse/storage/util/id_generators.py#L96"><code>AbstractStreamIdGenerator</code></a>.</p>
  18242. <h3 id="definition"><a class="header" href="#definition">Definition</a></h3>
  18243. <p>A stream is an append-only log <code>T1, T2, ..., Tn, ...</code> of facts<sup class="footnote-reference"><a href="#1">1</a></sup> which grows over time.
  18244. Only &quot;writers&quot; can add facts to a stream, and there may be multiple writers.</p>
  18245. <p>Each fact has an ID, called its &quot;stream ID&quot;.
  18246. Readers should only process facts in ascending stream ID order.</p>
  18247. <p>Roughly speaking, each stream is backed by a database table.
  18248. It should have a <code>stream_id</code> (or similar) bigint column holding stream IDs, plus additional columns as necessary to describe the fact.
  18249. Typically, a fact is expressed with a single row in its backing table.<sup class="footnote-reference"><a href="#2">2</a></sup>
  18250. Within a stream, no two facts may have the same stream_id.</p>
  18251. <blockquote>
  18252. <p><em>Aside</em>. Some additional notes on streams' backing tables.</p>
  18253. <ol>
  18254. <li>Rich would like to <a href="https://github.com/matrix-org/synapse/issues/13456">ditch the backing tables</a>.</li>
  18255. <li>The backing tables may have other uses.
  18256. &gt; For example, the events table serves backs the events stream, and is read when processing new events.
  18257. &gt; But old rows are read from the table all the time, whenever Synapse needs to lookup some facts about an event.</li>
  18258. <li>Rich suspects that sometimes the stream is backed by multiple tables, so the stream proper is the union of those tables.</li>
  18259. </ol>
  18260. </blockquote>
  18261. <p>Stream writers can &quot;reserve&quot; a stream ID, and then later mark it as having being completed.
  18262. Stream writers need to track the completion of each stream fact.
  18263. In the happy case, completion means a fact has been written to the stream table.
  18264. But unhappy cases (e.g. transaction rollback due to an error) also count as completion.
  18265. Once completed, the rows written with that stream ID are fixed, and no new rows
  18266. will be inserted with that ID.</p>
  18267. <h3 id="current-stream-id"><a class="header" href="#current-stream-id">Current stream ID</a></h3>
  18268. <p>For any given stream reader (including writers themselves), we may define a per-writer current stream ID:</p>
  18269. <blockquote>
  18270. <p>A current stream ID <em>for a writer W</em> is the largest stream ID such that
  18271. all transactions added by W with equal or smaller ID have completed.</p>
  18272. </blockquote>
  18273. <p>Similarly, there is a &quot;linear&quot; notion of current stream ID:</p>
  18274. <blockquote>
  18275. <p>A &quot;linear&quot; current stream ID is the largest stream ID such that
  18276. all facts (added by any writer) with equal or smaller ID have completed.</p>
  18277. </blockquote>
  18278. <p>Because different stream readers A and B learn about new facts at different times, A and B may disagree about current stream IDs.
  18279. Put differently: we should think of stream readers as being independent of each other, proceeding through a stream of facts at different rates.</p>
  18280. <p>The above definition does not give a unique current stream ID, in fact there can
  18281. be a range of current stream IDs. Synapse uses both the minimum and maximum IDs
  18282. for different purposes. Most often the maximum is used, as its generally
  18283. beneficial for workers to advance their IDs as soon as possible. However, the
  18284. minimum is used in situations where e.g. another worker is going to wait until
  18285. the stream advances past a position.</p>
  18286. <p><strong>NB.</strong> For both senses of &quot;current&quot;, that if a writer opens a transaction that never completes, the current stream ID will never advance beyond that writer's last written stream ID.</p>
  18287. <p>For single-writer streams, the per-writer current ID and the linear current ID are the same.
  18288. Both senses of current ID are monotonic, but they may &quot;skip&quot; or jump over IDs because facts complete out of order.</p>
  18289. <p><em>Example</em>.
  18290. Consider a single-writer stream which is initially at ID 1.</p>
  18291. <table><thead><tr><th>Action</th><th>Current stream ID</th><th>Notes</th></tr></thead><tbody>
  18292. <tr><td></td><td>1</td><td></td></tr>
  18293. <tr><td>Reserve 2</td><td>1</td><td></td></tr>
  18294. <tr><td>Reserve 3</td><td>1</td><td></td></tr>
  18295. <tr><td>Complete 3</td><td>1</td><td>current ID unchanged, waiting for 2 to complete</td></tr>
  18296. <tr><td>Complete 2</td><td>3</td><td>current ID jumps from 1 -&gt; 3</td></tr>
  18297. <tr><td>Reserve 4</td><td>3</td><td></td></tr>
  18298. <tr><td>Reserve 5</td><td>3</td><td></td></tr>
  18299. <tr><td>Reserve 6</td><td>3</td><td></td></tr>
  18300. <tr><td>Complete 5</td><td>3</td><td></td></tr>
  18301. <tr><td>Complete 4</td><td>5</td><td>current ID jumps 3-&gt;5, even though 6 is pending</td></tr>
  18302. <tr><td>Complete 6</td><td>6</td><td></td></tr>
  18303. </tbody></table>
  18304. <h3 id="multi-writer-streams"><a class="header" href="#multi-writer-streams">Multi-writer streams</a></h3>
  18305. <p>There are two ways to view a multi-writer stream.</p>
  18306. <ol>
  18307. <li>Treat it as a collection of distinct single-writer streams, one
  18308. for each writer.</li>
  18309. <li>Treat it as a single stream.</li>
  18310. </ol>
  18311. <p>The single stream (option 2) is conceptually simpler, and easier to represent (a single stream id).
  18312. However, it requires each reader to know about the entire set of writers, to ensures that readers don't erroneously advance their current stream position too early and miss a fact from an unknown writer.
  18313. In contrast, multiple parallel streams (option 1) are more complex, requiring more state to represent (map from writer to stream id).
  18314. The payoff for doing so is that readers can &quot;peek&quot; ahead to facts that completed on one writer no matter the state of the others, reducing latency.</p>
  18315. <p>Note that a multi-writer stream can be viewed in both ways.
  18316. For example, the events stream is treated as multiple single-writer streams (option 1) by the sync handler, so that events are sent to clients as soon as possible.
  18317. But the background process that works through events treats them as a single linear stream.</p>
  18318. <p>Another useful example is the cache invalidation stream.
  18319. The facts this stream holds are instructions to &quot;you should now invalidate these cache entries&quot;.
  18320. We only ever treat this as a multiple single-writer streams as there is no important ordering between cache invalidations.
  18321. (Invalidations are self-contained facts; and the invalidations commute/are idempotent).</p>
  18322. <h3 id="writing-to-streams"><a class="header" href="#writing-to-streams">Writing to streams</a></h3>
  18323. <p>Writers need to track:</p>
  18324. <ul>
  18325. <li>track their current position (i.e. its own per-writer stream ID).</li>
  18326. <li>their facts currently awaiting completion.</li>
  18327. </ul>
  18328. <p>At startup,</p>
  18329. <ul>
  18330. <li>the current position of that writer can be found by querying the database (which suggests that facts need to be written to the database atomically, in a transaction); and</li>
  18331. <li>there are no facts awaiting completion.</li>
  18332. </ul>
  18333. <p>To reserve a stream ID, call <a href="https://www.postgresql.org/docs/current/functions-sequence.html"><code>nextval</code></a> on the appropriate postgres sequence.</p>
  18334. <p>To write a fact to the stream: insert the appropriate rows to the appropriate backing table.</p>
  18335. <p>To complete a fact, first remove it from your map of facts currently awaiting completion.
  18336. Then, if no earlier fact is awaiting completion, the writer can advance its current position in that stream.
  18337. Upon doing so it should emit an <code>RDATA</code> message<sup class="footnote-reference"><a href="#3">3</a></sup>, once for every fact between the old and the new stream ID.</p>
  18338. <h3 id="subscribing-to-streams"><a class="header" href="#subscribing-to-streams">Subscribing to streams</a></h3>
  18339. <p>Readers need to track the current position of every writer.</p>
  18340. <p>At startup, they can find this by contacting each writer with a <code>REPLICATE</code> message,
  18341. requesting that all writers reply describing their current position in their streams.
  18342. Writers reply with a <code>POSITION</code> message.</p>
  18343. <p>To learn about new facts, readers should listen for <code>RDATA</code> messages and process them to respond to the new fact.
  18344. The <code>RDATA</code> itself is not a self-contained representation of the fact;
  18345. readers will have to query the stream tables for the full details.
  18346. Readers must also advance their record of the writer's current position for that stream.</p>
  18347. <h1 id="summary"><a class="header" href="#summary">Summary</a></h1>
  18348. <p>In a nutshell: we have an append-only log with a &quot;buffer/scratchpad&quot; at the end where we have to wait for the sequence to be linear and contiguous.</p>
  18349. <hr />
  18350. <div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
  18351. <p>we use the word <em>fact</em> here for two reasons.
  18352. Firstly, the word &quot;event&quot; is already heavily overloaded (PDUs, EDUs, account data, ...) and we don't need to make that worse.
  18353. Secondly, &quot;fact&quot; emphasises that the things we append to a stream cannot change after the fact.</p>
  18354. </div>
  18355. <div class="footnote-definition" id="2"><sup class="footnote-definition-label">2</sup>
  18356. <p>A fact might be expressed with 0 rows, e.g. if we opened a transaction to persist an event, but failed and rolled the transaction back before marking the fact as completed.
  18357. In principle a fact might be expressed with 2 or more rows; if so, each of those rows should share the fact's stream ID.</p>
  18358. </div>
  18359. <div class="footnote-definition" id="3"><sup class="footnote-definition-label">3</sup>
  18360. <p>This communication used to happen directly with the writers <a href="development/synapse_architecture/../../tcp_replication.html">over TCP</a>;
  18361. nowadays it's done via Redis's Pubsub.</p>
  18362. </div>
  18363. <div style="break-before: page; page-break-before: always;"></div><h1 id="tcp-replication"><a class="header" href="#tcp-replication">TCP Replication</a></h1>
  18364. <h2 id="motivation-1"><a class="header" href="#motivation-1">Motivation</a></h2>
  18365. <p>Previously the workers used an HTTP long poll mechanism to get updates
  18366. from the master, which had the problem of causing a lot of duplicate
  18367. work on the server. This TCP protocol replaces those APIs with the aim
  18368. of increased efficiency.</p>
  18369. <h2 id="overview-3"><a class="header" href="#overview-3">Overview</a></h2>
  18370. <p>The protocol is based on fire and forget, line based commands. An
  18371. example flow would be (where '&gt;' indicates master to worker and
  18372. '&lt;' worker to master flows):</p>
  18373. <pre><code>&gt; SERVER example.com
  18374. &lt; REPLICATE
  18375. &gt; POSITION events master 53 53
  18376. &gt; RDATA events master 54 [&quot;$foo1:bar.com&quot;, ...]
  18377. &gt; RDATA events master 55 [&quot;$foo4:bar.com&quot;, ...]
  18378. </code></pre>
  18379. <p>The example shows the server accepting a new connection and sending its identity
  18380. with the <code>SERVER</code> command, followed by the client server to respond with the
  18381. position of all streams. The server then periodically sends <code>RDATA</code> commands
  18382. which have the format <code>RDATA &lt;stream_name&gt; &lt;instance_name&gt; &lt;token&gt; &lt;row&gt;</code>, where
  18383. the format of <code>&lt;row&gt;</code> is defined by the individual streams. The
  18384. <code>&lt;instance_name&gt;</code> is the name of the Synapse process that generated the data
  18385. (usually &quot;master&quot;). We expect an RDATA for every row in the DB.</p>
  18386. <p>Error reporting happens by either the client or server sending an ERROR
  18387. command, and usually the connection will be closed.</p>
  18388. <p>Since the protocol is a simple line based, its possible to manually
  18389. connect to the server using a tool like netcat. A few things should be
  18390. noted when manually using the protocol:</p>
  18391. <ul>
  18392. <li>The federation stream is only available if federation sending has
  18393. been disabled on the main process.</li>
  18394. <li>The server will only time connections out that have sent a <code>PING</code>
  18395. command. If a ping is sent then the connection will be closed if no
  18396. further commands are received within 15s. Both the client and
  18397. server protocol implementations will send an initial PING on
  18398. connection and ensure at least one command every 5s is sent (not
  18399. necessarily <code>PING</code>).</li>
  18400. <li><code>RDATA</code> commands <em>usually</em> include a numeric token, however if the
  18401. stream has multiple rows to replicate per token the server will send
  18402. multiple <code>RDATA</code> commands, with all but the last having a token of
  18403. <code>batch</code>. See the documentation on <code>commands.RdataCommand</code> for
  18404. further details.</li>
  18405. </ul>
  18406. <h2 id="architecture-1"><a class="header" href="#architecture-1">Architecture</a></h2>
  18407. <p>The basic structure of the protocol is line based, where the initial
  18408. word of each line specifies the command. The rest of the line is parsed
  18409. based on the command. For example, the RDATA command is defined as:</p>
  18410. <pre><code>RDATA &lt;stream_name&gt; &lt;instance_name&gt; &lt;token&gt; &lt;row_json&gt;
  18411. </code></pre>
  18412. <p>(Note that &lt;row_json&gt; may contains spaces, but cannot contain
  18413. newlines.)</p>
  18414. <p>Blank lines are ignored.</p>
  18415. <h3 id="keep-alives"><a class="header" href="#keep-alives">Keep alives</a></h3>
  18416. <p>Both sides are expected to send at least one command every 5s or so, and
  18417. should send a <code>PING</code> command if necessary. If either side do not receive
  18418. a command within e.g. 15s then the connection should be closed.</p>
  18419. <p>Because the server may be connected to manually using e.g. netcat, the
  18420. timeouts aren't enabled until an initial <code>PING</code> command is seen. Both
  18421. the client and server implementations below send a <code>PING</code> command
  18422. immediately on connection to ensure the timeouts are enabled.</p>
  18423. <p>This ensures that both sides can quickly realize if the tcp connection
  18424. has gone and handle the situation appropriately.</p>
  18425. <h3 id="start-up"><a class="header" href="#start-up">Start up</a></h3>
  18426. <p>When a new connection is made, the server:</p>
  18427. <ul>
  18428. <li>Sends a <code>SERVER</code> command, which includes the identity of the server,
  18429. allowing the client to detect if its connected to the expected
  18430. server</li>
  18431. <li>Sends a <code>PING</code> command as above, to enable the client to time out
  18432. connections promptly.</li>
  18433. </ul>
  18434. <p>The client:</p>
  18435. <ul>
  18436. <li>Sends a <code>NAME</code> command, allowing the server to associate a human
  18437. friendly name with the connection. This is optional.</li>
  18438. <li>Sends a <code>PING</code> as above</li>
  18439. <li>Sends a <code>REPLICATE</code> to get the current position of all streams.</li>
  18440. <li>On receipt of a <code>SERVER</code> command, checks that the server name
  18441. matches the expected server name.</li>
  18442. </ul>
  18443. <h3 id="error-handling"><a class="header" href="#error-handling">Error handling</a></h3>
  18444. <p>If either side detects an error it can send an <code>ERROR</code> command and close
  18445. the connection.</p>
  18446. <p>If the client side loses the connection to the server it should
  18447. reconnect, following the steps above.</p>
  18448. <h3 id="congestion"><a class="header" href="#congestion">Congestion</a></h3>
  18449. <p>If the server sends messages faster than the client can consume them the
  18450. server will first buffer a (fairly large) number of commands and then
  18451. disconnect the client. This ensures that we don't queue up an unbounded
  18452. number of commands in memory and gives us a potential opportunity to
  18453. squawk loudly. When/if the client recovers it can reconnect to the
  18454. server and ask for missed messages.</p>
  18455. <h3 id="reliability"><a class="header" href="#reliability">Reliability</a></h3>
  18456. <p>In general the replication stream should be considered an unreliable
  18457. transport since e.g. commands are not resent if the connection
  18458. disappears.</p>
  18459. <p>The exception to that are the replication streams, i.e. RDATA commands,
  18460. since these include tokens which can be used to restart the stream on
  18461. connection errors.</p>
  18462. <p>The client should keep track of the token in the last RDATA command
  18463. received for each stream so that on reconnection it can start streaming
  18464. from the correct place. Note: not all RDATA have valid tokens due to
  18465. batching. See <code>RdataCommand</code> for more details.</p>
  18466. <h3 id="example-5"><a class="header" href="#example-5">Example</a></h3>
  18467. <p>An example interaction is shown below. Each line is prefixed with '&gt;'
  18468. or '&lt;' to indicate which side is sending, these are <em>not</em> included on
  18469. the wire:</p>
  18470. <pre><code>* connection established *
  18471. &gt; SERVER localhost:8823
  18472. &gt; PING 1490197665618
  18473. &lt; NAME synapse.app.appservice
  18474. &lt; PING 1490197665618
  18475. &lt; REPLICATE
  18476. &gt; POSITION events master 1 1
  18477. &gt; POSITION backfill master 1 1
  18478. &gt; POSITION caches master 1 1
  18479. &gt; RDATA caches master 2 [&quot;get_user_by_id&quot;,[&quot;@01register-user:localhost:8823&quot;],1490197670513]
  18480. &gt; RDATA events master 14 [&quot;$149019767112vOHxz:localhost:8823&quot;,
  18481. &quot;!AFDCvgApUmpdfVjIXm:localhost:8823&quot;,&quot;m.room.guest_access&quot;,&quot;&quot;,null]
  18482. &lt; PING 1490197675618
  18483. &gt; ERROR server stopping
  18484. * connection closed by server *
  18485. </code></pre>
  18486. <p>The <code>POSITION</code> command sent by the server is used to set the clients
  18487. position without needing to send data with the <code>RDATA</code> command.</p>
  18488. <p>An example of a batched set of <code>RDATA</code> is:</p>
  18489. <pre><code>&gt; RDATA caches master batch [&quot;get_user_by_id&quot;,[&quot;@test:localhost:8823&quot;],1490197670513]
  18490. &gt; RDATA caches master batch [&quot;get_user_by_id&quot;,[&quot;@test2:localhost:8823&quot;],1490197670513]
  18491. &gt; RDATA caches master batch [&quot;get_user_by_id&quot;,[&quot;@test3:localhost:8823&quot;],1490197670513]
  18492. &gt; RDATA caches master 54 [&quot;get_user_by_id&quot;,[&quot;@test4:localhost:8823&quot;],1490197670513]
  18493. </code></pre>
  18494. <p>In this case the client shouldn't advance their caches token until it
  18495. sees the the last <code>RDATA</code>.</p>
  18496. <h3 id="list-of-commands"><a class="header" href="#list-of-commands">List of commands</a></h3>
  18497. <p>The list of valid commands, with which side can send it: server (S) or
  18498. client (C):</p>
  18499. <h4 id="server-s"><a class="header" href="#server-s">SERVER (S)</a></h4>
  18500. <p>Sent at the start to identify which server the client is talking to</p>
  18501. <h4 id="rdata-s"><a class="header" href="#rdata-s">RDATA (S)</a></h4>
  18502. <p>A single update in a stream</p>
  18503. <h4 id="position-s"><a class="header" href="#position-s">POSITION (S)</a></h4>
  18504. <p>On receipt of a POSITION command clients should check if they have missed any
  18505. updates, and if so then fetch them out of band. Sent in response to a
  18506. REPLICATE command (but can happen at any time).</p>
  18507. <p>The POSITION command includes the source of the stream. Currently all streams
  18508. are written by a single process (usually &quot;master&quot;). If fetching missing
  18509. updates via HTTP API, rather than via the DB, then processes should make the
  18510. request to the appropriate process.</p>
  18511. <p>Two positions are included, the &quot;new&quot; position and the last position sent respectively.
  18512. This allows servers to tell instances that the positions have advanced but no
  18513. data has been written, without clients needlessly checking to see if they
  18514. have missed any updates. Instances will only fetch stuff if there is a gap between
  18515. their current position and the given last position.</p>
  18516. <h4 id="error-s-c"><a class="header" href="#error-s-c">ERROR (S, C)</a></h4>
  18517. <p>There was an error</p>
  18518. <h4 id="ping-s-c"><a class="header" href="#ping-s-c">PING (S, C)</a></h4>
  18519. <p>Sent periodically to ensure the connection is still alive</p>
  18520. <h4 id="name-c"><a class="header" href="#name-c">NAME (C)</a></h4>
  18521. <p>Sent at the start by client to inform the server who they are</p>
  18522. <h4 id="replicate-c"><a class="header" href="#replicate-c">REPLICATE (C)</a></h4>
  18523. <p>Asks the server for the current position of all streams.</p>
  18524. <h4 id="user_sync-c"><a class="header" href="#user_sync-c">USER_SYNC (C)</a></h4>
  18525. <p>A user has started or stopped syncing on this process.</p>
  18526. <h4 id="clear_user_sync-c"><a class="header" href="#clear_user_sync-c">CLEAR_USER_SYNC (C)</a></h4>
  18527. <p>The server should clear all associated user sync data from the worker.</p>
  18528. <p>This is used when a worker is shutting down.</p>
  18529. <h4 id="federation_ack-c"><a class="header" href="#federation_ack-c">FEDERATION_ACK (C)</a></h4>
  18530. <p>Acknowledge receipt of some federation data</p>
  18531. <h3 id="remote_server_up-s-c"><a class="header" href="#remote_server_up-s-c">REMOTE_SERVER_UP (S, C)</a></h3>
  18532. <p>Inform other processes that a remote server may have come back online.</p>
  18533. <p>See <code>synapse/replication/tcp/commands.py</code> for a detailed description and
  18534. the format of each command.</p>
  18535. <h3 id="cache-invalidation-stream"><a class="header" href="#cache-invalidation-stream">Cache Invalidation Stream</a></h3>
  18536. <p>The cache invalidation stream is used to inform workers when they need
  18537. to invalidate any of their caches in the data store. This is done by
  18538. streaming all cache invalidations done on master down to the workers,
  18539. assuming that any caches on the workers also exist on the master.</p>
  18540. <p>Each individual cache invalidation results in a row being sent down
  18541. replication, which includes the cache name (the name of the function)
  18542. and they key to invalidate. For example:</p>
  18543. <pre><code>&gt; RDATA caches master 550953771 [&quot;get_user_by_id&quot;, [&quot;@bob:example.com&quot;], 1550574873251]
  18544. </code></pre>
  18545. <p>Alternatively, an entire cache can be invalidated by sending down a <code>null</code>
  18546. instead of the key. For example:</p>
  18547. <pre><code>&gt; RDATA caches master 550953772 [&quot;get_user_by_id&quot;, null, 1550574873252]
  18548. </code></pre>
  18549. <p>However, there are times when a number of caches need to be invalidated
  18550. at the same time with the same key. To reduce traffic we batch those
  18551. invalidations into a single poke by defining a special cache name that
  18552. workers understand to mean to expand to invalidate the correct caches.</p>
  18553. <p>Currently the special cache names are declared in
  18554. <code>synapse/storage/_base.py</code> and are:</p>
  18555. <ol>
  18556. <li><code>cs_cache_fake</code> ─ invalidates caches that depend on the current
  18557. state</li>
  18558. </ol>
  18559. <div style="break-before: page; page-break-before: always;"></div><h1 id="how-do-faster-joins-work"><a class="header" href="#how-do-faster-joins-work">How do faster joins work?</a></h1>
  18560. <p>This is a work-in-progress set of notes with two goals:</p>
  18561. <ul>
  18562. <li>act as a reference, explaining how Synapse implements faster joins; and</li>
  18563. <li>record the rationale behind our choices.</li>
  18564. </ul>
  18565. <p>See also <a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3902">MSC3902</a>.</p>
  18566. <p>The key idea is described by <a href="https://github.com/matrix-org/matrix-spec-proposals/pull/3706">MSC3706</a>. This allows servers to
  18567. request a lightweight response to the federation <code>/send_join</code> endpoint.
  18568. This is called a <strong>faster join</strong>, also known as a <strong>partial join</strong>. In these
  18569. notes we'll usually use the word &quot;partial&quot; as it matches the database schema.</p>
  18570. <h2 id="overview-processing-events-in-a-partially-joined-room"><a class="header" href="#overview-processing-events-in-a-partially-joined-room">Overview: processing events in a partially-joined room</a></h2>
  18571. <p>The response to a partial join consists of</p>
  18572. <ul>
  18573. <li>the requested join event <code>J</code>,</li>
  18574. <li>a list of the servers in the room (according to the state before <code>J</code>),</li>
  18575. <li>a subset of the state of the room before <code>J</code>,</li>
  18576. <li>the full auth chain of that state subset.</li>
  18577. </ul>
  18578. <p>Synapse marks the room as partially joined by adding a row to the database table
  18579. <code>partial_state_rooms</code>. It also marks the join event <code>J</code> as &quot;partially stated&quot;,
  18580. meaning that we have neither received nor computed the full state before/after
  18581. <code>J</code>. This is done by adding a row to <code>partial_state_events</code>.</p>
  18582. <details><summary>DB schema</summary>
  18583. <pre><code>matrix=&gt; \d partial_state_events
  18584. Table &quot;matrix.partial_state_events&quot;
  18585. Column │ Type │ Collation │ Nullable │ Default
  18586. ══════════╪══════╪═══════════╪══════════╪═════════
  18587. room_id │ text │ │ not null │
  18588. event_id │ text │ │ not null │
  18589. matrix=&gt; \d partial_state_rooms
  18590. Table &quot;matrix.partial_state_rooms&quot;
  18591. Column │ Type │ Collation │ Nullable │ Default
  18592. ════════════════════════╪════════╪═══════════╪══════════╪═════════
  18593. room_id │ text │ │ not null │
  18594. device_lists_stream_id │ bigint │ │ not null │ 0
  18595. join_event_id │ text │ │ │
  18596. joined_via │ text │ │ │
  18597. matrix=&gt; \d partial_state_rooms_servers
  18598. Table &quot;matrix.partial_state_rooms_servers&quot;
  18599. Column │ Type │ Collation │ Nullable │ Default
  18600. ═════════════╪══════╪═══════════╪══════════╪═════════
  18601. room_id │ text │ │ not null │
  18602. server_name │ text │ │ not null │
  18603. </code></pre>
  18604. <p>Indices, foreign-keys and check constraints are omitted for brevity.</p>
  18605. </details>
  18606. <p>While partially joined to a room, Synapse receives events <code>E</code> from remote
  18607. homeservers as normal, and can create events at the request of its local users.
  18608. However, we run into trouble when we enforce the <a href="https://spec.matrix.org/v1.5/server-server-api/#checks-performed-on-receipt-of-a-pdu">checks on an event</a>.</p>
  18609. <blockquote>
  18610. <ol>
  18611. <li>Is a valid event, otherwise it is dropped. For an event to be valid, it
  18612. must contain a room_id, and it must comply with the event format of that
  18613. room version.</li>
  18614. <li>Passes signature checks, otherwise it is dropped.</li>
  18615. <li>Passes hash checks, otherwise it is redacted before being processed further.</li>
  18616. <li>Passes authorization rules based on the event’s auth events, otherwise it
  18617. is rejected.</li>
  18618. <li><strong>Passes authorization rules based on the state before the event, otherwise
  18619. it is rejected.</strong></li>
  18620. <li><strong>Passes authorization rules based on the current state of the room,
  18621. otherwise it is “soft failed”.</strong></li>
  18622. </ol>
  18623. </blockquote>
  18624. <p>We can enforce checks 1--4 without any problems.
  18625. But we cannot enforce checks 5 or 6 with complete certainty, since Synapse does
  18626. not know the full state before <code>E</code>, nor that of the room.</p>
  18627. <h3 id="partial-state"><a class="header" href="#partial-state">Partial state</a></h3>
  18628. <p>Instead, we make a best-effort approximation.
  18629. While the room is considered partially joined, Synapse tracks the &quot;partial
  18630. state&quot; before events.
  18631. This works in a similar way as regular state:</p>
  18632. <ul>
  18633. <li>The partial state before <code>J</code> is that given to us by the partial join response.</li>
  18634. <li>The partial state before an event <code>E</code> is the resolution of the partial states
  18635. after each of <code>E</code>'s <code>prev_event</code>s.</li>
  18636. <li>If <code>E</code> is rejected or a message event, the partial state after <code>E</code> is the
  18637. partial state before <code>E</code>.</li>
  18638. <li>Otherwise, the partial state after <code>E</code> is the partial state before <code>E</code>, plus
  18639. <code>E</code> itself.</li>
  18640. </ul>
  18641. <p>More concisely, partial state propagates just like full state; the only
  18642. difference is that we &quot;seed&quot; it with an incomplete initial state.
  18643. Synapse records that we have only calculated partial state for this event with
  18644. a row in <code>partial_state_events</code>.</p>
  18645. <p>While the room remains partially stated, check 5 on incoming events to that
  18646. room becomes:</p>
  18647. <blockquote>
  18648. <ol start="5">
  18649. <li>Passes authorization rules based on <strong>the resolution between the partial
  18650. state before <code>E</code> and <code>E</code>'s auth events.</strong> If the event fails to pass
  18651. authorization rules, it is rejected.</li>
  18652. </ol>
  18653. </blockquote>
  18654. <p>Additionally, check 6 is deleted: no soft-failures are enforced.</p>
  18655. <p>While partially joined, the current partial state of the room is defined as the
  18656. resolution across the partial states after all forward extremities in the room.</p>
  18657. <p><em>Remark.</em> Events with partial state are <em>not</em> considered
  18658. <a href="development/synapse_architecture/../room-dag-concepts.html#outliers">outliers</a>.</p>
  18659. <h3 id="approximation-error"><a class="header" href="#approximation-error">Approximation error</a></h3>
  18660. <p>Using partial state means the auth checks can fail in a few different ways<sup class="footnote-reference"><a href="#2">1</a></sup>.</p>
  18661. <div class="footnote-definition" id="2"><sup class="footnote-definition-label">1</sup>
  18662. <p>Is this exhaustive?</p>
  18663. </div>
  18664. <ul>
  18665. <li>We may erroneously accept an incoming event in check 5 based on partial state
  18666. when it would have been rejected based on full state, or vice versa.</li>
  18667. <li>This means that an event could erroneously be added to the current partial
  18668. state of the room when it would not be present in the full state of the room,
  18669. or vice versa.</li>
  18670. <li>Additionally, we may have skipped soft-failing an event that would have been
  18671. soft-failed based on full state.</li>
  18672. </ul>
  18673. <p>(Note that the discrepancies described in the last two bullets are user-visible.)</p>
  18674. <p>This means that we have to be very careful when we want to lookup pieces of room
  18675. state in a partially-joined room. Our approximation of the state may be
  18676. incorrect or missing. But we can make some educated guesses. If</p>
  18677. <ul>
  18678. <li>our partial state is likely to be correct, or</li>
  18679. <li>the consequences of our partial state being incorrect are minor,</li>
  18680. </ul>
  18681. <p>then we proceed as normal, and let the resync process fix up any mistakes (see
  18682. below).</p>
  18683. <p>When is our partial state likely to be correct?</p>
  18684. <ul>
  18685. <li>It's more accurate the closer we are to the partial join event. (So we should
  18686. ideally complete the resync as soon as possible.)</li>
  18687. <li>Non-member events: we will have received them as part of the partial join
  18688. response, if they were part of the room state at that point. We may
  18689. incorrectly accept or reject updates to that state (at first because we lack
  18690. remote membership information; later because of compounding errors), so these
  18691. can become incorrect over time.</li>
  18692. <li>Local members' memberships: we are the only ones who can create join and
  18693. knock events for our users. We can't be completely confident in the
  18694. correctness of bans, invites and kicks from other homeservers, but the resync
  18695. process should correct any mistakes.</li>
  18696. <li>Remote members' memberships: we did not receive these in the /send_join
  18697. response, so we have essentially no idea if these are correct or not.</li>
  18698. </ul>
  18699. <p>In short, we deem it acceptable to trust the partial state for non-membership
  18700. and local membership events. For remote membership events, we wait for the
  18701. resync to complete, at which point we have the full state of the room and can
  18702. proceed as normal.</p>
  18703. <h3 id="fixing-the-approximation-with-a-resync"><a class="header" href="#fixing-the-approximation-with-a-resync">Fixing the approximation with a resync</a></h3>
  18704. <p>The partial-state approximation is only a temporary affair. In the background,
  18705. synapse beings a &quot;resync&quot; process. This is a continuous loop, starting at the
  18706. partial join event and proceeding downwards through the event graph. For each
  18707. <code>E</code> seen in the room since partial join, Synapse will fetch </p>
  18708. <ul>
  18709. <li>the event ids in the state of the room before <code>E</code>, via
  18710. <a href="https://spec.matrix.org/v1.5/server-server-api/#get_matrixfederationv1state_idsroomid"><code>/state_ids</code></a>;</li>
  18711. <li>the event ids in the full auth chain of <code>E</code>, included in the <code>/state_ids</code>
  18712. response; and</li>
  18713. <li>any events from the previous two bullets that Synapse hasn't persisted, via
  18714. <a href="https://spec.matrix.org/v1.5/server-server-api/#get_matrixfederationv1stateroomid">`/state</a>.</li>
  18715. </ul>
  18716. <p>This means Synapse has (or can compute) the full state before <code>E</code>, which allows
  18717. Synapse to properly authorise or reject <code>E</code>. At this point ,the event
  18718. is considered to have &quot;full state&quot; rather than &quot;partial state&quot;. We record this
  18719. by removing <code>E</code> from the <code>partial_state_events</code> table.</p>
  18720. <p>[<strong>TODO:</strong> Does Synapse persist a new state group for the full state
  18721. before <code>E</code>, or do we alter the (partial-)state group in-place? Are state groups
  18722. ever marked as partially-stated? ]</p>
  18723. <p>This scheme means it is possible for us to have accepted and sent an event to
  18724. clients, only to reject it during the resync. From a client's perspective, the
  18725. effect is similar to a retroactive
  18726. state change due to state resolution---i.e. a &quot;state reset&quot;.<sup class="footnote-reference"><a href="#3">2</a></sup></p>
  18727. <div class="footnote-definition" id="3"><sup class="footnote-definition-label">2</sup>
  18728. <p>Clients should refresh caches to detect such a change. Rumour has it that
  18729. sliding sync will fix this.</p>
  18730. </div>
  18731. <p>When all events since the join <code>J</code> have been fully-stated, the room resync
  18732. process is complete. We record this by removing the room from
  18733. <code>partial_state_rooms</code>.</p>
  18734. <h2 id="faster-joins-on-workers"><a class="header" href="#faster-joins-on-workers">Faster joins on workers</a></h2>
  18735. <p>For the time being, the resync process happens on the master worker.
  18736. A new replication stream <code>un_partial_stated_room</code> is added. Whenever a resync
  18737. completes and a partial-state room becomes fully stated, a new message is sent
  18738. into that stream containing the room ID.</p>
  18739. <h2 id="notes-on-specific-cases"><a class="header" href="#notes-on-specific-cases">Notes on specific cases</a></h2>
  18740. <blockquote>
  18741. <p><strong>NB.</strong> The notes below are rough. Some of them are hidden under <code>&lt;details&gt;</code>
  18742. disclosures because they have yet to be implemented in mainline Synapse.</p>
  18743. </blockquote>
  18744. <h3 id="creating-events-during-a-partial-join"><a class="header" href="#creating-events-during-a-partial-join">Creating events during a partial join</a></h3>
  18745. <p>When sending out messages during a partial join, we assume our partial state is
  18746. accurate and proceed as normal. For this to have any hope of succeeding at all,
  18747. our partial state must contain an entry for each of the (type, state key) pairs
  18748. <a href="https://spec.matrix.org/v1.3/rooms/v10/#authorization-rules">specified by the auth rules</a>:</p>
  18749. <ul>
  18750. <li><code>m.room.create</code></li>
  18751. <li><code>m.room.join_rules</code></li>
  18752. <li><code>m.room.power_levels</code></li>
  18753. <li><code>m.room.third_party_invite</code></li>
  18754. <li><code>m.room.member</code></li>
  18755. </ul>
  18756. <p>The first four of these should be present in the state before <code>J</code> that is given
  18757. to us in the partial join response; only membership events are omitted. In order
  18758. for us to consider the user joined, we must have their membership event. That
  18759. means the only possible omission is the target's membership in an invite, kick
  18760. or ban.</p>
  18761. <p>The worst possibility is that we locally invite someone who is banned according to
  18762. the full state, because we lack their ban in our current partial state. The rest
  18763. of the federation---at least, those who are fully joined---should correctly
  18764. enforce the <a href="https://spec.matrix.org/v1.3/client-server-api/#room-membership">membership transition constraints</a>. So any the erroneous invite should be ignored by fully-joined
  18765. homeservers and resolved by the resync for partially-joined homeservers.</p>
  18766. <p>In more generality, there are two problems we're worrying about here:</p>
  18767. <ul>
  18768. <li>We might create an event that is valid under our partial state, only to later
  18769. find out that is actually invalid according to the full state.</li>
  18770. <li>Or: we might refuse to create an event that is invalid under our partial
  18771. state, even though it would be perfectly valid under the full state.</li>
  18772. </ul>
  18773. <p>However we expect such problems to be unlikely in practise, because</p>
  18774. <ul>
  18775. <li>We trust that the room has sensible power levels, e.g. that bad actors with
  18776. high power levels are demoted before their ban.</li>
  18777. <li>We trust that the resident server provides us up-to-date power levels, join
  18778. rules, etc.</li>
  18779. <li>State changes in rooms are relatively infrequent, and the resync period is
  18780. relatively quick.</li>
  18781. </ul>
  18782. <h4 id="sending-out-the-event-over-federation"><a class="header" href="#sending-out-the-event-over-federation">Sending out the event over federation</a></h4>
  18783. <p><strong>TODO:</strong> needs prose fleshing out.</p>
  18784. <p>Normally: send out in a fed txn to all HSes in the room.
  18785. We only know that some HSes were in the room at some point. Wat do.
  18786. Send it out to the list of servers from the first join.
  18787. <strong>TODO</strong> what do we do here if we have full state?
  18788. If the prev event was created by us, we can risk sending it to the wrong HS. (Motivation: privacy concern of the content. Not such a big deal for a public room or an encrypted room. But non-encrypted invite-only...)
  18789. But don't want to send out sensitive data in other HS's events in this way.</p>
  18790. <p>Suppose we discover after resync that we shouldn't have sent out one our events (not a prev_event) to a target HS. Not much we can do.
  18791. What about if we didn't send them an event but shouldn't've?
  18792. E.g. what if someone joined from a new HS shortly after you did? We wouldn't talk to them.
  18793. Could imagine sending out the &quot;Missed&quot; events after the resync but... painful to work out what they should have seen if they joined/left.
  18794. Instead, just send them the latest event (if they're still in the room after resync) and let them backfill.(?)</p>
  18795. <ul>
  18796. <li>Don't do this currently.</li>
  18797. <li>If anyone who has received our messages sends a message to a HS we missed, they can backfill our messages</li>
  18798. <li>Gap: rooms which are infrequently used and take a long time to resync.</li>
  18799. </ul>
  18800. <h3 id="joining-after-a-partial-join"><a class="header" href="#joining-after-a-partial-join">Joining after a partial join</a></h3>
  18801. <p><strong>NB.</strong> Not yet implemented.</p>
  18802. <details>
  18803. <p><strong>TODO:</strong> needs prose fleshing out. Liase with Matthieu. Explain why /send_join
  18804. (Rich was surprised we didn't just create it locally. Answer: to try and avoid
  18805. a join which then gets rejected after resync.)</p>
  18806. <p>We don't know for sure that any join we create would be accepted.
  18807. E.g. the joined user might have been banned; the join rules might have changed in a way that we didn't realise... some way in which the partial state was mistaken.
  18808. Instead, do another partial make-join/send-join handshake to confirm that the join works.</p>
  18809. <ul>
  18810. <li>Probably going to get a bunch of duplicate state events and auth events.... but the point of partial joins is that these should be small. Many are already persisted = good.</li>
  18811. <li>What if the second send_join response includes a different list of reisdent HSes? Could ignore it.
  18812. <ul>
  18813. <li>Could even have a special flag that says &quot;just make me a join&quot;, i.e. don't bother giving me state or servers in room. Deffo want the auth chain tho.</li>
  18814. </ul>
  18815. </li>
  18816. <li>SQ: wrt device lists it's a lot safer to ignore it!!!!!</li>
  18817. <li>What if the state at the second join is inconsistent with what we have? Ignore it?</li>
  18818. </ul>
  18819. </details>
  18820. <h3 id="leaving-and-kicks-and-bans-after-a-partial-join"><a class="header" href="#leaving-and-kicks-and-bans-after-a-partial-join">Leaving (and kicks and bans) after a partial join</a></h3>
  18821. <p><strong>NB.</strong> Not yet implemented.</p>
  18822. <details>
  18823. <p>When you're fully joined to a room, to have <code>U</code> leave a room their homeserver
  18824. needs to</p>
  18825. <ul>
  18826. <li>create a new leave event for <code>U</code> which will be accepted by other homeservers,
  18827. and</li>
  18828. <li>send that event <code>U</code> out to the homeservers in the federation.</li>
  18829. </ul>
  18830. <p>When is a leave event accepted? See
  18831. <a href="https://spec.matrix.org/v1.5/rooms/v10/#authorization-rules">v10 auth rules</a>:</p>
  18832. <blockquote>
  18833. <ol start="4">
  18834. <li>If type is m.room.member: [...]
  18835. &gt;
  18836. &gt; 5. If membership is leave:
  18837. &gt;
  18838. &gt; 1. If the sender matches state_key, allow if and only if that user’s current membership state is invite, join, or knock.
  18839. 2. [...]</li>
  18840. </ol>
  18841. </blockquote>
  18842. <p>I think this means that (well-formed!) self-leaves are governed entirely by
  18843. 4.5.1. This means that if we correctly calculate state which says that <code>U</code> is
  18844. invited, joined or knocked and include it in the leave's auth events, our event
  18845. is accepted by checks 4 and 5 on incoming events.</p>
  18846. <blockquote>
  18847. <ol start="4">
  18848. <li>Passes authorization rules based on the event’s auth events, otherwise
  18849. &gt; it is rejected.</li>
  18850. <li>Passes authorization rules based on the state before the event, otherwise
  18851. &gt; it is rejected.</li>
  18852. </ol>
  18853. </blockquote>
  18854. <p>The only way to fail check 6 is if the receiving server's current state of the
  18855. room says that <code>U</code> is banned, has left, or has no membership event. But this is
  18856. fine: the receiving server already thinks that <code>U</code> isn't in the room.</p>
  18857. <blockquote>
  18858. <ol start="6">
  18859. <li>Passes authorization rules based on the current state of the room,
  18860. &gt; otherwise it is “soft failed”.</li>
  18861. </ol>
  18862. </blockquote>
  18863. <p>For the second point (publishing the leave event), the best thing we can do is
  18864. to is publish to all HSes we know to be currently in the room. If they miss that
  18865. event, they might send us traffic in the room that we don't care about. This is
  18866. a problem with leaving after a &quot;full&quot; join; we don't seek to fix this with
  18867. partial joins.</p>
  18868. <p>(With that said: there's nothing machine-readable in the /send response. I don't
  18869. think we can deduce &quot;destination has left the room&quot; from a failure to /send an
  18870. event into that room?)</p>
  18871. <h4 id="can-we-still-do-this-during-a-partial-join"><a class="header" href="#can-we-still-do-this-during-a-partial-join">Can we still do this during a partial join?</a></h4>
  18872. <p>We can create leave events and can choose what gets included in our auth events,
  18873. so we can be sure that we pass check 4 on incoming events. For check 5, we might
  18874. have an incorrect view of the state before an event.
  18875. The only way we might erroneously think a leave is valid is if</p>
  18876. <ul>
  18877. <li>the partial state before the leave has <code>U</code> joined, invited or knocked, but</li>
  18878. <li>the full state before the leave has <code>U</code> banned, left or not present,</li>
  18879. </ul>
  18880. <p>in which case the leave doesn't make anything worse: other HSes already consider
  18881. us as not in the room, and will continue to do so after seeing the leave.</p>
  18882. <p>The remaining obstacle is then: can we safely broadcast the leave event? We may
  18883. miss servers or incorrectly think that a server is in the room. Or the
  18884. destination server may be offline and miss the transaction containing our leave
  18885. event.This should self-heal when they see an event whose <code>prev_events</code> descends
  18886. from our leave.</p>
  18887. <p>Another option we considered was to use federation <code>/send_leave</code> to ask a
  18888. fully-joined server to send out the event on our behalf. But that introduces
  18889. complexity without much benefit. Besides, as Rich put it,</p>
  18890. <blockquote>
  18891. <p>sending out leaves is pretty best-effort currently</p>
  18892. </blockquote>
  18893. <p>so this is probably good enough as-is.</p>
  18894. <h4 id="cleanup-after-the-last-leave"><a class="header" href="#cleanup-after-the-last-leave">Cleanup after the last leave</a></h4>
  18895. <p><strong>TODO</strong>: what cleanup is necessary? Is it all just nice-to-have to save unused
  18896. work?</p>
  18897. </details>
  18898. <div style="break-before: page; page-break-before: always;"></div><h1 id="internal-documentation"><a class="header" href="#internal-documentation">Internal Documentation</a></h1>
  18899. <p>This section covers implementation documentation for various parts of Synapse.</p>
  18900. <p>If a developer is planning to make a change to a feature of Synapse, it can be useful for
  18901. general documentation of how that feature is implemented to be available. This saves the
  18902. developer time in place of needing to understand how the feature works by reading the
  18903. code.</p>
  18904. <p>Documentation that would be more useful for the perspective of a system administrator,
  18905. rather than a developer who's intending to change to code, should instead be placed
  18906. under the Usage section of the documentation.</p>
  18907. <div style="break-before: page; page-break-before: always;"></div><h1 id="how-to-test-saml-as-a-developer-without-a-server"><a class="header" href="#how-to-test-saml-as-a-developer-without-a-server">How to test SAML as a developer without a server</a></h1>
  18908. <p>https://fujifish.github.io/samling/samling.html (https://github.com/fujifish/samling) is a great resource for being able to tinker with the
  18909. SAML options within Synapse without needing to deploy and configure a complicated software stack.</p>
  18910. <p>To make Synapse (and therefore Element) use it:</p>
  18911. <ol>
  18912. <li>Use the samling.html URL above or deploy your own and visit the IdP Metadata tab.</li>
  18913. <li>Copy the XML to your clipboard.</li>
  18914. <li>On your Synapse server, create a new file <code>samling.xml</code> next to your <code>homeserver.yaml</code> with
  18915. the XML from step 2 as the contents.</li>
  18916. <li>Edit your <code>homeserver.yaml</code> to include:
  18917. <pre><code class="language-yaml">saml2_config:
  18918. sp_config:
  18919. allow_unknown_attributes: true # Works around a bug with AVA Hashes: https://github.com/IdentityPython/pysaml2/issues/388
  18920. metadata:
  18921. local: [&quot;samling.xml&quot;]
  18922. </code></pre>
  18923. </li>
  18924. <li>Ensure that your <code>homeserver.yaml</code> has a setting for <code>public_baseurl</code>:
  18925. <pre><code class="language-yaml">public_baseurl: http://localhost:8080/
  18926. </code></pre>
  18927. </li>
  18928. <li>Run <code>apt-get install xmlsec1</code> and <code>pip install --upgrade --force 'pysaml2&gt;=4.5.0'</code> to ensure
  18929. the dependencies are installed and ready to go.</li>
  18930. <li>Restart Synapse.</li>
  18931. </ol>
  18932. <p>Then in Element:</p>
  18933. <ol>
  18934. <li>Visit the login page and point Element towards your homeserver using the <code>public_baseurl</code> above.</li>
  18935. <li>Click the Single Sign-On button.</li>
  18936. <li>On the samling page, enter a Name Identifier and add a SAML Attribute for <code>uid=your_localpart</code>.
  18937. The response must also be signed.</li>
  18938. <li>Click &quot;Next&quot;.</li>
  18939. <li>Click &quot;Post Response&quot; (change nothing).</li>
  18940. <li>You should be logged in.</li>
  18941. </ol>
  18942. <p>If you try and repeat this process, you may be automatically logged in using the information you
  18943. gave previously. To fix this, open your developer console (<code>F12</code> or <code>Ctrl+Shift+I</code>) while on the
  18944. samling page and clear the site data. In Chrome, this will be a button on the Application tab.</p>
  18945. <div style="break-before: page; page-break-before: always;"></div><h1 id="how-to-test-cas-as-a-developer-without-a-server"><a class="header" href="#how-to-test-cas-as-a-developer-without-a-server">How to test CAS as a developer without a server</a></h1>
  18946. <p>The <a href="https://github.com/jbittel/django-mama-cas">django-mama-cas</a> project is an
  18947. easy to run CAS implementation built on top of Django.</p>
  18948. <h2 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h2>
  18949. <ol>
  18950. <li>Create a new virtualenv: <code>python3 -m venv &lt;your virtualenv&gt;</code></li>
  18951. <li>Activate your virtualenv: <code>source /path/to/your/virtualenv/bin/activate</code></li>
  18952. <li>Install Django and django-mama-cas:
  18953. <pre><code class="language-sh">python -m pip install &quot;django&lt;3&quot; &quot;django-mama-cas==2.4.0&quot;
  18954. </code></pre>
  18955. </li>
  18956. <li>Create a Django project in the current directory:
  18957. <pre><code class="language-sh">django-admin startproject cas_test .
  18958. </code></pre>
  18959. </li>
  18960. <li>Follow the <a href="https://django-mama-cas.readthedocs.io/en/latest/installation.html#configuring">install directions</a> for django-mama-cas</li>
  18961. <li>Setup the SQLite database: <code>python manage.py migrate</code></li>
  18962. <li>Create a user:
  18963. <pre><code class="language-sh">python manage.py createsuperuser
  18964. </code></pre>
  18965. <ol>
  18966. <li>Use whatever you want as the username and password.</li>
  18967. <li>Leave the other fields blank.</li>
  18968. </ol>
  18969. </li>
  18970. <li>Use the built-in Django test server to serve the CAS endpoints on port 8000:
  18971. <pre><code class="language-sh">python manage.py runserver
  18972. </code></pre>
  18973. </li>
  18974. </ol>
  18975. <p>You should now have a Django project configured to serve CAS authentication with
  18976. a single user created.</p>
  18977. <h2 id="configure-synapse-and-element-to-use-cas"><a class="header" href="#configure-synapse-and-element-to-use-cas">Configure Synapse (and Element) to use CAS</a></h2>
  18978. <ol>
  18979. <li>Modify your <code>homeserver.yaml</code> to enable CAS and point it to your locally
  18980. running Django test server:
  18981. <pre><code class="language-yaml">cas_config:
  18982. enabled: true
  18983. server_url: &quot;http://localhost:8000&quot;
  18984. service_url: &quot;http://localhost:8081&quot;
  18985. #displayname_attribute: name
  18986. #required_attributes:
  18987. # name: value
  18988. </code></pre>
  18989. </li>
  18990. <li>Restart Synapse.</li>
  18991. </ol>
  18992. <p>Note that the above configuration assumes the homeserver is running on port 8081
  18993. and that the CAS server is on port 8000, both on localhost.</p>
  18994. <h2 id="testing-the-configuration"><a class="header" href="#testing-the-configuration">Testing the configuration</a></h2>
  18995. <p>Then in Element:</p>
  18996. <ol>
  18997. <li>Visit the login page with a Element pointing at your homeserver.</li>
  18998. <li>Click the Single Sign-On button.</li>
  18999. <li>Login using the credentials created with <code>createsuperuser</code>.</li>
  19000. <li>You should be logged in.</li>
  19001. </ol>
  19002. <p>If you want to repeat this process you'll need to manually logout first:</p>
  19003. <ol>
  19004. <li>http://localhost:8000/admin/</li>
  19005. <li>Click &quot;logout&quot; in the top right.</li>
  19006. </ol>
  19007. <div style="break-before: page; page-break-before: always;"></div><h1 id="room-dag-concepts"><a class="header" href="#room-dag-concepts">Room DAG concepts</a></h1>
  19008. <h2 id="edges"><a class="header" href="#edges">Edges</a></h2>
  19009. <p>The word &quot;edge&quot; comes from graph theory lingo. An edge is just a connection
  19010. between two events. In Synapse, we connect events by specifying their
  19011. <code>prev_events</code>. A subsequent event points back at a previous event.</p>
  19012. <pre><code>A (oldest) &lt;---- B &lt;---- C (most recent)
  19013. </code></pre>
  19014. <h2 id="depth-and-stream-ordering"><a class="header" href="#depth-and-stream-ordering">Depth and stream ordering</a></h2>
  19015. <p>Events are normally sorted by <code>(topological_ordering, stream_ordering)</code> where
  19016. <code>topological_ordering</code> is just <code>depth</code>. In other words, we first sort by <code>depth</code>
  19017. and then tie-break based on <code>stream_ordering</code>. <code>depth</code> is incremented as new
  19018. messages are added to the DAG. Normally, <code>stream_ordering</code> is an auto
  19019. incrementing integer, but backfilled events start with <code>stream_ordering=-1</code> and decrement.</p>
  19020. <hr />
  19021. <ul>
  19022. <li><code>/sync</code> returns things in the order they arrive at the server (<code>stream_ordering</code>).</li>
  19023. <li><code>/messages</code> (and <code>/backfill</code> in the federation API) return them in the order determined by the event graph <code>(topological_ordering, stream_ordering)</code>.</li>
  19024. </ul>
  19025. <p>The general idea is that, if you're following a room in real-time (i.e.
  19026. <code>/sync</code>), you probably want to see the messages as they arrive at your server,
  19027. rather than skipping any that arrived late; whereas if you're looking at a
  19028. historical section of timeline (i.e. <code>/messages</code>), you want to see the best
  19029. representation of the state of the room as others were seeing it at the time.</p>
  19030. <h2 id="outliers"><a class="header" href="#outliers">Outliers</a></h2>
  19031. <p>We mark an event as an <code>outlier</code> when we haven't figured out the state for the
  19032. room at that point in the DAG yet. They are &quot;floating&quot; events that we haven't
  19033. yet correlated to the DAG.</p>
  19034. <p>Outliers typically arise when we fetch the auth chain or state for a given
  19035. event. When that happens, we just grab the events in the state/auth chain,
  19036. without calculating the state at those events, or backfilling their
  19037. <code>prev_events</code>. Since we don't have the state at any events fetched in that
  19038. way, we mark them as outliers.</p>
  19039. <p>So, typically, we won't have the <code>prev_events</code> of an <code>outlier</code> in the database,
  19040. (though it's entirely possible that we <em>might</em> have them for some other
  19041. reason). Other things that make outliers different from regular events:</p>
  19042. <ul>
  19043. <li>
  19044. <p>We don't have state for them, so there should be no entry in
  19045. <code>event_to_state_groups</code> for an outlier. (In practice this isn't always
  19046. the case, though I'm not sure why: see https://github.com/matrix-org/synapse/issues/12201).</p>
  19047. </li>
  19048. <li>
  19049. <p>We don't record entries for them in the <code>event_edges</code>,
  19050. <code>event_forward_extremeties</code> or <code>event_backward_extremities</code> tables.</p>
  19051. </li>
  19052. </ul>
  19053. <p>Since outliers are not tied into the DAG, they do not normally form part of the
  19054. timeline sent down to clients via <code>/sync</code> or <code>/messages</code>; however there is an
  19055. exception:</p>
  19056. <h3 id="out-of-band-membership-events"><a class="header" href="#out-of-band-membership-events">Out-of-band membership events</a></h3>
  19057. <p>A special case of outlier events are some membership events for federated rooms
  19058. that we aren't full members of. For example:</p>
  19059. <ul>
  19060. <li>invites received over federation, before we join the room</li>
  19061. <li><em>rejections</em> for said invites</li>
  19062. <li>knock events for rooms that we would like to join but have not yet joined.</li>
  19063. </ul>
  19064. <p>In all the above cases, we don't have the state for the room, which is why they
  19065. are treated as outliers. They are a bit special though, in that they are
  19066. proactively sent to clients via <code>/sync</code>.</p>
  19067. <h2 id="forward-extremity"><a class="header" href="#forward-extremity">Forward extremity</a></h2>
  19068. <p>Most-recent-in-time events in the DAG which are not referenced by any other
  19069. events' <code>prev_events</code> yet. (In this definition, outliers, rejected events, and
  19070. soft-failed events don't count.)</p>
  19071. <p>The forward extremities of a room (or at least, a subset of them, if there are
  19072. more than ten) are used as the <code>prev_events</code> when the next event is sent.</p>
  19073. <p>The &quot;current state&quot; of a room (ie: the state which would be used if we
  19074. generated a new event) is, therefore, the resolution of the room states
  19075. at each of the forward extremities.</p>
  19076. <h2 id="backward-extremity"><a class="header" href="#backward-extremity">Backward extremity</a></h2>
  19077. <p>The current marker of where we have backfilled up to and will generally be the
  19078. <code>prev_events</code> of the oldest-in-time events we have in the DAG. This gives a starting point when
  19079. backfilling history.</p>
  19080. <p>Note that, unlike forward extremities, we typically don't have any backward
  19081. extremity events themselves in the database - or, if we do, they will be &quot;outliers&quot; (see
  19082. above). Either way, we don't expect to have the room state at a backward extremity.</p>
  19083. <p>When we persist a non-outlier event, if it was previously a backward extremity,
  19084. we clear it as a backward extremity and set all of its <code>prev_events</code> as the new
  19085. backward extremities if they aren't already persisted as non-outliers. This
  19086. therefore keeps the backward extremities up-to-date.</p>
  19087. <h2 id="state-groups"><a class="header" href="#state-groups">State groups</a></h2>
  19088. <p>For every non-outlier event we need to know the state at that event. Instead of
  19089. storing the full state for each event in the DB (i.e. a <code>event_id -&gt; state</code>
  19090. mapping), which is <em>very</em> space inefficient when state doesn't change, we
  19091. instead assign each different set of state a &quot;state group&quot; and then have
  19092. mappings of <code>event_id -&gt; state_group</code> and <code>state_group -&gt; state</code>.</p>
  19093. <h3 id="stage-group-edges"><a class="header" href="#stage-group-edges">Stage group edges</a></h3>
  19094. <p>TODO: <code>state_group_edges</code> is a further optimization...
  19095. notes from @Azrenbeth, https://pastebin.com/seUGVGeT</p>
  19096. <div style="break-before: page; page-break-before: always;"></div><h1 id="auth-chain-difference-algorithm"><a class="header" href="#auth-chain-difference-algorithm">Auth Chain Difference Algorithm</a></h1>
  19097. <p>The auth chain difference algorithm is used by V2 state resolution, where a
  19098. naive implementation can be a significant source of CPU and DB usage.</p>
  19099. <h3 id="definitions"><a class="header" href="#definitions">Definitions</a></h3>
  19100. <p>A <em>state set</em> is a set of state events; e.g. the input of a state resolution
  19101. algorithm is a collection of state sets.</p>
  19102. <p>The <em>auth chain</em> of a set of events are all the events' auth events and <em>their</em>
  19103. auth events, recursively (i.e. the events reachable by walking the graph induced
  19104. by an event's auth events links).</p>
  19105. <p>The <em>auth chain difference</em> of a collection of state sets is the union minus the
  19106. intersection of the sets of auth chains corresponding to the state sets, i.e an
  19107. event is in the auth chain difference if it is reachable by walking the auth
  19108. event graph from at least one of the state sets but not from <em>all</em> of the state
  19109. sets.</p>
  19110. <h2 id="breadth-first-walk-algorithm"><a class="header" href="#breadth-first-walk-algorithm">Breadth First Walk Algorithm</a></h2>
  19111. <p>A way of calculating the auth chain difference without calculating the full auth
  19112. chains for each state set is to do a parallel breadth first walk (ordered by
  19113. depth) of each state set's auth chain. By tracking which events are reachable
  19114. from each state set we can finish early if every pending event is reachable from
  19115. every state set.</p>
  19116. <p>This can work well for state sets that have a small auth chain difference, but
  19117. can be very inefficient for larger differences. However, this algorithm is still
  19118. used if we don't have a chain cover index for the room (e.g. because we're in
  19119. the process of indexing it).</p>
  19120. <h2 id="chain-cover-index"><a class="header" href="#chain-cover-index">Chain Cover Index</a></h2>
  19121. <p>Synapse computes auth chain differences by pre-computing a &quot;chain cover&quot; index
  19122. for the auth chain in a room, allowing us to efficiently make reachability queries
  19123. like &quot;is event <code>A</code> in the auth chain of event <code>B</code>?&quot;. We could do this with an index
  19124. that tracks all pairs <code>(A, B)</code> such that <code>A</code> is in the auth chain of <code>B</code>. However, this
  19125. would be prohibitively large, scaling poorly as the room accumulates more state
  19126. events.</p>
  19127. <p>Instead, we break down the graph into <em>chains</em>. A chain is a subset of a DAG
  19128. with the following property: for any pair of events <code>E</code> and <code>F</code> in the chain,
  19129. the chain contains a path <code>E -&gt; F</code> or a path <code>F -&gt; E</code>. This forces a chain to be
  19130. linear (without forks), e.g. <code>E -&gt; F -&gt; G -&gt; ... -&gt; H</code>. Each event in the chain
  19131. is given a <em>sequence number</em> local to that chain. The oldest event <code>E</code> in the
  19132. chain has sequence number 1. If <code>E</code> has a child <code>F</code> in the chain, then <code>F</code> has
  19133. sequence number 2. If <code>E</code> has a grandchild <code>G</code> in the chain, then <code>G</code> has
  19134. sequence number 3; and so on.</p>
  19135. <p>Synapse ensures that each persisted event belongs to exactly one chain, and
  19136. tracks how the chains are connected to one another. This allows us to
  19137. efficiently answer reachability queries. Doing so uses less storage than
  19138. tracking reachability on an event-by-event basis, particularly when we have
  19139. fewer and longer chains. See</p>
  19140. <blockquote>
  19141. <p>Jagadish, H. (1990). <a href="https://doi.org/10.1145/99935.99944">A compression technique to materialize transitive closure</a>.
  19142. <em>ACM Transactions on Database Systems (TODS)</em>, 15*(4)*, 558-598.</p>
  19143. </blockquote>
  19144. <p>for the original idea or</p>
  19145. <blockquote>
  19146. <p>Y. Chen, Y. Chen, <a href="https://doi.org/10.1109/ICDE.2008.4497498">An efficient algorithm for answering graph
  19147. reachability queries</a>,
  19148. in: 2008 IEEE 24th International Conference on Data Engineering, April 2008,
  19149. pp. 893–902. (PDF available via <a href="https://scholar.google.com/scholar?q=Y.%20Chen,%20Y.%20Chen,%20An%20efficient%20algorithm%20for%20answering%20graph%20reachability%20queries,%20in:%202008%20IEEE%2024th%20International%20Conference%20on%20Data%20Engineering,%20April%202008,%20pp.%20893902.">Google Scholar</a>.)</p>
  19150. </blockquote>
  19151. <p>for a more modern take.</p>
  19152. <p>In practical terms, the chain cover assigns every event a
  19153. <em>chain ID</em> and <em>sequence number</em> (e.g. <code>(5,3)</code>), and maintains a map of <em>links</em>
  19154. between events in chains (e.g. <code>(5,3) -&gt; (2,4)</code>) such that <code>A</code> is reachable by <code>B</code>
  19155. (i.e. <code>A</code> is in the auth chain of <code>B</code>) if and only if either:</p>
  19156. <ol>
  19157. <li><code>A</code> and <code>B</code> have the same chain ID and <code>A</code>'s sequence number is less than <code>B</code>'s
  19158. sequence number; or</li>
  19159. <li>there is a link <code>L</code> between <code>B</code>'s chain ID and <code>A</code>'s chain ID such that
  19160. <code>L.start_seq_no</code> &lt;= <code>B.seq_no</code> and <code>A.seq_no</code> &lt;= <code>L.end_seq_no</code>.</li>
  19161. </ol>
  19162. <p>There are actually two potential implementations, one where we store links from
  19163. each chain to every other reachable chain (the transitive closure of the links
  19164. graph), and one where we remove redundant links (the transitive reduction of the
  19165. links graph) e.g. if we have chains <code>C3 -&gt; C2 -&gt; C1</code> then the link <code>C3 -&gt; C1</code>
  19166. would not be stored. Synapse uses the former implementation so that it doesn't
  19167. need to recurse to test reachability between chains. This trades-off extra storage
  19168. in order to save CPU cycles and DB queries.</p>
  19169. <h3 id="example-6"><a class="header" href="#example-6">Example</a></h3>
  19170. <p>An example auth graph would look like the following, where chains have been
  19171. formed based on type/state_key and are denoted by colour and are labelled with
  19172. <code>(chain ID, sequence number)</code>. Links are denoted by the arrows (links in grey
  19173. are those that would be remove in the second implementation described above).</p>
  19174. <p><img src="auth_chain_diff.dot.png" alt="Example" /></p>
  19175. <p>Note that we don't include all links between events and their auth events, as
  19176. most of those links would be redundant. For example, all events point to the
  19177. create event, but each chain only needs the one link from it's base to the
  19178. create event.</p>
  19179. <h2 id="using-the-index"><a class="header" href="#using-the-index">Using the Index</a></h2>
  19180. <p>This index can be used to calculate the auth chain difference of the state sets
  19181. by looking at the chain ID and sequence numbers reachable from each state set:</p>
  19182. <ol>
  19183. <li>For every state set lookup the chain ID/sequence numbers of each state event</li>
  19184. <li>Use the index to find all chains and the maximum sequence number reachable
  19185. from each state set.</li>
  19186. <li>The auth chain difference is then all events in each chain that have sequence
  19187. numbers between the maximum sequence number reachable from <em>any</em> state set and
  19188. the minimum reachable by <em>all</em> state sets (if any).</li>
  19189. </ol>
  19190. <p>Note that steps 2 is effectively calculating the auth chain for each state set
  19191. (in terms of chain IDs and sequence numbers), and step 3 is calculating the
  19192. difference between the union and intersection of the auth chains.</p>
  19193. <h3 id="worked-example"><a class="header" href="#worked-example">Worked Example</a></h3>
  19194. <p>For example, given the above graph, we can calculate the difference between
  19195. state sets consisting of:</p>
  19196. <ol>
  19197. <li><code>S1</code>: Alice's invite <code>(4,1)</code> and Bob's second join <code>(2,2)</code>; and</li>
  19198. <li><code>S2</code>: Alice's second join <code>(4,3)</code> and Bob's first join <code>(2,1)</code>.</li>
  19199. </ol>
  19200. <p>Using the index we see that the following auth chains are reachable from each
  19201. state set:</p>
  19202. <ol>
  19203. <li><code>S1</code>: <code>(1,1)</code>, <code>(2,2)</code>, <code>(3,1)</code> &amp; <code>(4,1)</code></li>
  19204. <li><code>S2</code>: <code>(1,1)</code>, <code>(2,1)</code>, <code>(3,2)</code> &amp; <code>(4,3)</code></li>
  19205. </ol>
  19206. <p>And so, for each the ranges that are in the auth chain difference:</p>
  19207. <ol>
  19208. <li>Chain 1: None, (since everything can reach the create event).</li>
  19209. <li>Chain 2: The range <code>(1, 2]</code> (i.e. just <code>2</code>), as <code>1</code> is reachable by all state
  19210. sets and the maximum reachable is <code>2</code> (corresponding to Bob's second join).</li>
  19211. <li>Chain 3: Similarly the range <code>(1, 2]</code> (corresponding to the second power
  19212. level).</li>
  19213. <li>Chain 4: The range <code>(1, 3]</code> (corresponding to both of Alice's joins).</li>
  19214. </ol>
  19215. <p>So the final result is: Bob's second join <code>(2,2)</code>, the second power level
  19216. <code>(3,2)</code> and both of Alice's joins <code>(4,2)</code> &amp; <code>(4,3)</code>.</p>
  19217. <div style="break-before: page; page-break-before: always;"></div><h1 id="media-repository"><a class="header" href="#media-repository">Media Repository</a></h1>
  19218. <p><em>Synapse implementation-specific details for the media repository</em></p>
  19219. <p>The media repository</p>
  19220. <ul>
  19221. <li>stores avatars, attachments and their thumbnails for media uploaded by local
  19222. users.</li>
  19223. <li>caches avatars, attachments and their thumbnails for media uploaded by remote
  19224. users.</li>
  19225. <li>caches resources and thumbnails used for URL previews.</li>
  19226. </ul>
  19227. <p>All media in Matrix can be identified by a unique
  19228. <a href="https://spec.matrix.org/latest/client-server-api/#matrix-content-mxc-uris">MXC URI</a>,
  19229. consisting of a server name and media ID:</p>
  19230. <pre><code>mxc://&lt;server-name&gt;/&lt;media-id&gt;
  19231. </code></pre>
  19232. <h2 id="local-media"><a class="header" href="#local-media">Local Media</a></h2>
  19233. <p>Synapse generates 24 character media IDs for content uploaded by local users.
  19234. These media IDs consist of upper and lowercase letters and are case-sensitive.
  19235. Other homeserver implementations may generate media IDs differently.</p>
  19236. <p>Local media is recorded in the <code>local_media_repository</code> table, which includes
  19237. metadata such as MIME types, upload times and file sizes.
  19238. Note that this table is shared by the URL cache, which has a different media ID
  19239. scheme.</p>
  19240. <h3 id="paths"><a class="header" href="#paths">Paths</a></h3>
  19241. <p>A file with media ID <code>aabbcccccccccccccccccccc</code> and its <code>128x96</code> <code>image/jpeg</code>
  19242. thumbnail, created by scaling, would be stored at:</p>
  19243. <pre><code>local_content/aa/bb/cccccccccccccccccccc
  19244. local_thumbnails/aa/bb/cccccccccccccccccccc/128-96-image-jpeg-scale
  19245. </code></pre>
  19246. <h2 id="remote-media"><a class="header" href="#remote-media">Remote Media</a></h2>
  19247. <p>When media from a remote homeserver is requested from Synapse, it is assigned
  19248. a local <code>filesystem_id</code>, with the same format as locally-generated media IDs,
  19249. as described above.</p>
  19250. <p>A record of remote media is stored in the <code>remote_media_cache</code> table, which
  19251. can be used to map remote MXC URIs (server names and media IDs) to local
  19252. <code>filesystem_id</code>s.</p>
  19253. <h3 id="paths-1"><a class="header" href="#paths-1">Paths</a></h3>
  19254. <p>A file from <code>matrix.org</code> with <code>filesystem_id</code> <code>aabbcccccccccccccccccccc</code> and its
  19255. <code>128x96</code> <code>image/jpeg</code> thumbnail, created by scaling, would be stored at:</p>
  19256. <pre><code>remote_content/matrix.org/aa/bb/cccccccccccccccccccc
  19257. remote_thumbnail/matrix.org/aa/bb/cccccccccccccccccccc/128-96-image-jpeg-scale
  19258. </code></pre>
  19259. <p>Older thumbnails may omit the thumbnailing method:</p>
  19260. <pre><code>remote_thumbnail/matrix.org/aa/bb/cccccccccccccccccccc/128-96-image-jpeg
  19261. </code></pre>
  19262. <p>Note that <code>remote_thumbnail/</code> does not have an <code>s</code>.</p>
  19263. <h2 id="url-previews-1"><a class="header" href="#url-previews-1">URL Previews</a></h2>
  19264. <p>When generating previews for URLs, Synapse may download and cache various
  19265. resources, including images. These resources are assigned temporary media IDs
  19266. of the form <code>yyyy-mm-dd_aaaaaaaaaaaaaaaa</code>, where <code>yyyy-mm-dd</code> is the current
  19267. date and <code>aaaaaaaaaaaaaaaa</code> is a random sequence of 16 case-sensitive letters.</p>
  19268. <p>The metadata for these cached resources is stored in the
  19269. <code>local_media_repository</code> and <code>local_media_repository_url_cache</code> tables.</p>
  19270. <p>Resources for URL previews are deleted after a few days.</p>
  19271. <h3 id="paths-2"><a class="header" href="#paths-2">Paths</a></h3>
  19272. <p>The file with media ID <code>yyyy-mm-dd_aaaaaaaaaaaaaaaa</code> and its <code>128x96</code>
  19273. <code>image/jpeg</code> thumbnail, created by scaling, would be stored at:</p>
  19274. <pre><code>url_cache/yyyy-mm-dd/aaaaaaaaaaaaaaaa
  19275. url_cache_thumbnails/yyyy-mm-dd/aaaaaaaaaaaaaaaa/128-96-image-jpeg-scale
  19276. </code></pre>
  19277. <div style="break-before: page; page-break-before: always;"></div><h1 id="room-and-user-statistics"><a class="header" href="#room-and-user-statistics">Room and User Statistics</a></h1>
  19278. <p>Synapse maintains room and user statistics in various tables. These can be used
  19279. for administrative purposes but are also used when generating the public room
  19280. directory.</p>
  19281. <h1 id="synapse-developer-documentation"><a class="header" href="#synapse-developer-documentation">Synapse Developer Documentation</a></h1>
  19282. <h2 id="high-level-concepts"><a class="header" href="#high-level-concepts">High-Level Concepts</a></h2>
  19283. <h3 id="definitions-1"><a class="header" href="#definitions-1">Definitions</a></h3>
  19284. <ul>
  19285. <li><strong>subject</strong>: Something we are tracking stats about – currently a room or user.</li>
  19286. <li><strong>current row</strong>: An entry for a subject in the appropriate current statistics
  19287. table. Each subject can have only one.</li>
  19288. </ul>
  19289. <h3 id="overview-4"><a class="header" href="#overview-4">Overview</a></h3>
  19290. <p>Stats correspond to the present values. Current rows contain the most up-to-date
  19291. statistics for a room. Each subject can only have one entry.</p>
  19292. <div style="break-before: page; page-break-before: always;"></div><h1 id="deprecation-policy-for-platform-dependencies"><a class="header" href="#deprecation-policy-for-platform-dependencies">Deprecation Policy for Platform Dependencies</a></h1>
  19293. <p>Synapse has a number of platform dependencies, including Python, Rust,
  19294. PostgreSQL and SQLite. This document outlines the policy towards which versions
  19295. we support, and when we drop support for versions in the future.</p>
  19296. <h2 id="policy"><a class="header" href="#policy">Policy</a></h2>
  19297. <p>Synapse follows the upstream support life cycles for Python and PostgreSQL,
  19298. i.e. when a version reaches End of Life Synapse will withdraw support for that
  19299. version in future releases.</p>
  19300. <p>Details on the upstream support life cycles for Python and PostgreSQL are
  19301. documented at <a href="https://endoflife.date/python">https://endoflife.date/python</a> and
  19302. <a href="https://endoflife.date/postgresql">https://endoflife.date/postgresql</a>.</p>
  19303. <p>A Rust compiler is required to build Synapse from source. For any given release
  19304. the minimum required version may be bumped up to a recent Rust version, and so
  19305. people building from source should ensure they can fetch recent versions of Rust
  19306. (e.g. by using <a href="https://rustup.rs/">rustup</a>).</p>
  19307. <p>The oldest supported version of SQLite is the version
  19308. <a href="https://packages.debian.org/bullseye/libsqlite3-0">provided</a> by
  19309. <a href="https://wiki.debian.org/DebianOldStable">Debian oldstable</a>.</p>
  19310. <h2 id="context"><a class="header" href="#context">Context</a></h2>
  19311. <p>It is important for system admins to have a clear understanding of the platform
  19312. requirements of Synapse and its deprecation policies so that they can
  19313. effectively plan upgrading their infrastructure ahead of time. This is
  19314. especially important in contexts where upgrading the infrastructure requires
  19315. auditing and approval from a security team, or where otherwise upgrading is a
  19316. long process.</p>
  19317. <p>By following the upstream support life cycles Synapse can ensure that its
  19318. dependencies continue to get security patches, while not requiring system admins
  19319. to constantly update their platform dependencies to the latest versions.</p>
  19320. <p>For Rust, the situation is a bit different given that a) the Rust foundation
  19321. does not generally support older Rust versions, and b) the library ecosystem
  19322. generally bump their minimum support Rust versions frequently. In general, the
  19323. Synapse team will try to avoid updating the dependency on Rust to the absolute
  19324. latest version, but introducing a formal policy is hard given the constraints of
  19325. the ecosystem.</p>
  19326. <p>On a similar note, SQLite does not generally have a concept of &quot;supported
  19327. release&quot;; bugfixes are published for the latest minor release only. We chose to
  19328. track Debian's oldstable as this is relatively conservative, predictably updated
  19329. and is consistent with the <code>.deb</code> packages released by Matrix.org.</p>
  19330. <div style="break-before: page; page-break-before: always;"></div><h2 id="summary-of-performance-impact-of-running-on-resource-constrained-devices-such-as-sbcs"><a class="header" href="#summary-of-performance-impact-of-running-on-resource-constrained-devices-such-as-sbcs">Summary of performance impact of running on resource constrained devices such as SBCs</a></h2>
  19331. <p>I've been running my homeserver on a cubietruck at home now for some time and am often replying to statements like &quot;you need loads of ram to join large rooms&quot; with &quot;it works fine for me&quot;. I thought it might be useful to curate a summary of the issues you're likely to run into to help as a scaling-down guide, maybe highlight these for development work or end up as documentation. It seems that once you get up to about 4x1.5GHz arm64 4GiB these issues are no longer a problem.</p>
  19332. <ul>
  19333. <li><strong>Platform</strong>: 2x1GHz armhf 2GiB ram <a href="https://wiki.debian.org/CheapServerBoxHardware">Single-board computers</a>, SSD, postgres.</li>
  19334. </ul>
  19335. <h3 id="presence-1"><a class="header" href="#presence-1">Presence</a></h3>
  19336. <p>This is the main reason people have a poor matrix experience on resource constrained homeservers. Element web will frequently be saying the server is offline while the python process will be pegged at 100% cpu. This feature is used to tell when other users are active (have a client app in the foreground) and therefore more likely to respond, but requires a lot of network activity to maintain even when nobody is talking in a room.</p>
  19337. <p><img src="https://user-images.githubusercontent.com/71895/94848963-a47a3580-041c-11eb-8b6e-acb772b4259e.png" alt="Screenshot_2020-10-01_19-29-46" /></p>
  19338. <p>While synapse does have some performance issues with presence <a href="https://github.com/matrix-org/synapse/issues/3971">#3971</a>, the fundamental problem is that this is an easy feature to implement for a centralised service at nearly no overhead, but federation makes it combinatorial <a href="https://github.com/matrix-org/synapse/issues/8055">#8055</a>. There is also a client-side config option which disables the UI and idle tracking <a href="https://github.com/vector-im/element-web/blob/v1.7.8/config.sample.json#L45">enable_presence_by_hs_url</a> to blacklist the largest instances but I didn't notice much difference, so I recommend disabling the feature entirely at the server level as well.</p>
  19339. <h3 id="joining"><a class="header" href="#joining">Joining</a></h3>
  19340. <p>Joining a &quot;large&quot;, federated room will initially fail with the below message in Element web, but waiting a while (10-60mins) and trying again will succeed without any issue. What counts as &quot;large&quot; is not message history, user count, connections to homeservers or even a simple count of the state events, it is instead how long the state resolution algorithm takes. However, each of those numbers are reasonable proxies, so we can use them as estimates since user count is one of the few things you see before joining.</p>
  19341. <p><img src="https://user-images.githubusercontent.com/71895/94945781-18771500-04d3-11eb-8419-83c2da73a341.png" alt="Screenshot_2020-10-02_17-15-06" /></p>
  19342. <p>This is <a href="https://github.com/matrix-org/synapse/issues/1211">#1211</a> and will also hopefully be mitigated by peeking <a href="https://github.com/matrix-org/matrix-doc/pull/2753">matrix-org/matrix-doc#2753</a> so at least you don't need to wait for a join to complete before finding out if it's the kind of room you want. Note that you should first disable presence, otherwise it'll just make the situation worse <a href="https://github.com/matrix-org/synapse/issues/3120">#3120</a>. There is a lot of database interaction too, so make sure you've <a href="other/../postgres.html">migrated your data</a> from the default sqlite to postgresql. Personally, I recommend patience - once the initial join is complete there's rarely any issues with actually interacting with the room, but if you like you can just block &quot;large&quot; rooms entirely.</p>
  19343. <h3 id="sessions"><a class="header" href="#sessions">Sessions</a></h3>
  19344. <p>Anything that requires modifying the device list <a href="https://github.com/matrix-org/synapse/issues/7721">#7721</a> will take a while to propagate, again taking the client &quot;Offline&quot; until it's complete. This includes signing in and out, editing the public name and verifying e2ee. The main mitigation I recommend is to keep long-running sessions open e.g. by using Firefox SSB &quot;Use this site in App mode&quot; or Chromium PWA &quot;Install Element&quot;.</p>
  19345. <h3 id="recommended-configuration"><a class="header" href="#recommended-configuration">Recommended configuration</a></h3>
  19346. <p>Put the below in a new file at /etc/matrix-synapse/conf.d/sbc.yaml to override the defaults in homeserver.yaml.</p>
  19347. <pre><code># Disable presence tracking, which is currently fairly resource intensive
  19348. # More info: https://github.com/matrix-org/synapse/issues/9478
  19349. use_presence: false
  19350. # Set a small complexity limit, preventing users from joining large rooms
  19351. # which may be resource-intensive to remain a part of.
  19352. #
  19353. # Note that this will not prevent users from joining smaller rooms that
  19354. # eventually become complex.
  19355. limit_remote_rooms:
  19356. enabled: true
  19357. complexity: 3.0
  19358. # Database configuration
  19359. database:
  19360. # Use postgres for the best performance
  19361. name: psycopg2
  19362. args:
  19363. user: matrix-synapse
  19364. # Generate a long, secure password using a password manager
  19365. password: hunter2
  19366. database: matrix-synapse
  19367. host: localhost
  19368. </code></pre>
  19369. <p>Currently the complexity is measured by <a href="https://github.com/matrix-org/synapse/blob/v1.20.1/synapse/storage/databases/main/events_worker.py#L986">current_state_events / 500</a>. You can find join times and your most complex rooms like this:</p>
  19370. <pre><code>admin@homeserver:~$ zgrep '/client/r0/join/' /var/log/matrix-synapse/homeserver.log* | awk '{print $18, $25}' | sort --human-numeric-sort
  19371. 29.922sec/-0.002sec /_matrix/client/r0/join/%23debian-fasttrack%3Apoddery.com
  19372. 182.088sec/0.003sec /_matrix/client/r0/join/%23decentralizedweb-general%3Amatrix.org
  19373. 911.625sec/-570.847sec /_matrix/client/r0/join/%23synapse%3Amatrix.org
  19374. admin@homeserver:~$ sudo --user postgres psql matrix-synapse --command 'select canonical_alias, joined_members, current_state_events from room_stats_state natural join room_stats_current where canonical_alias is not null order by current_state_events desc fetch first 5 rows only'
  19375. canonical_alias | joined_members | current_state_events
  19376. -------------------------------+----------------+----------------------
  19377. #_oftc_#debian:matrix.org | 871 | 52355
  19378. #matrix:matrix.org | 6379 | 10684
  19379. #irc:matrix.org | 461 | 3751
  19380. #decentralizedweb-general:matrix.org | 997 | 1509
  19381. #whatsapp:maunium.net | 554 | 854
  19382. </code></pre>
  19383. </main>
  19384. <nav class="nav-wrapper" aria-label="Page navigation">
  19385. <!-- Mobile navigation buttons -->
  19386. <div style="clear: both"></div>
  19387. </nav>
  19388. </div>
  19389. </div>
  19390. <nav class="nav-wide-wrapper" aria-label="Page navigation">
  19391. </nav>
  19392. </div>
  19393. <script type="text/javascript">
  19394. window.playground_copyable = true;
  19395. </script>
  19396. <script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
  19397. <script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
  19398. <script src="searcher.js" type="text/javascript" charset="utf-8"></script>
  19399. <script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
  19400. <script src="highlight.js" type="text/javascript" charset="utf-8"></script>
  19401. <script src="book.js" type="text/javascript" charset="utf-8"></script>
  19402. <!-- Custom JS scripts -->
  19403. <script type="text/javascript" src="docs/website_files/table-of-contents.js"></script>
  19404. <script type="text/javascript" src="docs/website_files/version-picker.js"></script>
  19405. <script type="text/javascript" src="docs/website_files/version.js"></script>
  19406. <script type="text/javascript">
  19407. window.addEventListener('load', function() {
  19408. window.setTimeout(window.print, 100);
  19409. });
  19410. </script>
  19411. </body>
  19412. </html>