Introducing automatic remediation policies with Cloudflare CASB

Post Syndicated from Michael Leslie original https://blog.cloudflare.com/casb-policies/

Today, we’re making Cloudflare CASB more powerful than ever by introducing automatic remediation policies. This means security teams can now design event-driven logic to revoke risky file shares and dispatch custom webhooks, without manual intervention.

When we launched Cloudflare CASB, a cloud access security broker, we wanted to provide security teams complete visibility into the posture of their SaaS applications before misconfigurations became incidents. With a quick, clientless integration, CASB surfaces risks like overshared files, dormant admin keys and tokens, OAuth apps with excessive permissions — continuously, across users in the organization.

For years, SaaS Security Posture Management (SSPM) tools such as Cloudflare CASB have functioned as a passive alarm system. Most SSPM tools tell you what’s wrong but do not help you fix the issue, placing the burden on administrators to manage an ever-growing to-do list. A single misconfigured file-sharing policy across a Google Workspace tenant can generate thousands of findings in seconds, and even a disciplined team faces a window between detection and remediation measured in hours or days — more than enough time for a sensitive file to be downloaded, forwarded, or indexed. 

With automatic remediation policies, CASB customers can now configure the actions that should be invoked immediately after a new finding is identified.

Shifting from reactive to proactive

When we launched manual remediation actions earlier this year, we gave security teams the ability to resolve misconfigurations directly from the Cloudflare dashboard. This removed the need for customers to log in to multiple SaaS portals to take action on the security and content findings detected by Cloudflare CASB. Still, this required a human to confirm and initiate each individual remediation — even if they’d seen this exact finding type before. 

CASB policies are a native automation engine built directly into Cloudflare One that takes action the moment a finding is detected. Security teams define their response logic once, whether that is revoking access to a file share, dispatching a webhook to your security operations center (SOC), or forwarding the event to a security orchestration, automation and response platform (SOAR). The engine handles matches automatically by executing the customer-configured action.

As an example, many organizations implement controls that prohibit files from being shared publicly. However, they may apply an exception to users and groups in their marketing department who are frequently required to collaborate with external parties. SSPMs allow their customers to be alerted of any files that are shared publicly in violation of their policy. With many solutions, this permitted behavior lands in a queue with hundreds of possible violations, forcing administrators to take action on each individual instance. 

CASB policies are designed for exactly this scenario. Rather than waiting for a human to see and act on a finding, automation fires the moment detection happens. The public share is revoked within minutes, keeping the backlog of findings clean and clear.

How CASB policies work

At their core, CASB policies are automated workflows that tell our scanning service what action to take when a new finding is detected. From there, the configured policy will tell CASB to either trigger a remediation action, send a webhook, or both. This gives organizations the flexibility to rely on native CASB remediation capabilities or their own internal automation services and communication channels — without having to take action in disparate platforms or create their own event processing system.

How we built it

The architecture behind CASB policies is built entirely on the Cloudflare developer platform — the same platform available to every Cloudflare customer.

When a finding is detected, the findings engine enqueues an orchestration message to a Cloudflare Queue. A Worker consumer then checks whether a policy configuration matches the incoming finding. If a match exists, it creates the corresponding job and hands it to the remediations pipeline, which runs on Cloudflare Workflows for durable, fault-tolerant execution. That means jobs survive process restarts and retries are handled automatically.

Cloudflare Workflows also handle third-party API rate limits gracefully. If a vendor returns a rate limit error, the Workflow pauses for the appropriate backoff window and retries without dropping the job. Our target from detection to completed remediation is five minutes or less.

How to create policies

To get started, navigate to the Cloudflare dashboard and create your first policy. Policies can include both a remediation and a webhook action, but at a minimum: 

  • Select the vendor. Select the vendor and integration or tenant this policy should apply to.
  • Select the integration. You can hand-select specific integrations or set it to apply to all integrations for the selected vendor. 
  • Choose a finding type. Select the CASB finding type that should fire the policy. 
  • Choose an action. Once a trigger is selected, the available actions for that finding type are shown. There are two categories:
    • Run remediations. First-party actions Cloudflare performs directly against the SaaS integration API. CASB currently supports remediation actions for Microsoft and Google Workspace file/folder finding types. Note that this may require upgrading permissions on integrations to read/write.
    • Send webhooks. Send finding details to configured webhook destinations such as Slack, Microsoft Teams, Jira, ServiceNow, Tines, or any custom HTTP endpoint your team uses.

Example webhook format

Maintaining visibility and compliance

Each policy action produces two categories of logs, visible under Insights in Cloudflare One. 

Admin Activity logs. These capture changes to a policy definition: who created it, who edited it, who disabled it, and when. If a policy was turned off and a risk slipped through, this audit trail surfaces a timeline of the event.

Cloud & SaaS Security policies logs. This new class of logs captures the runtime outcome of policy invocations. This includes details like which finding triggered the policy, which file was acted on, whether it succeeded or failed, and the specific error if it did not — for example, a 401 Unauthorized or an API rate limit response from the vendor. 

For compliance use cases, the execution log is the proof of fix. It ties a specific finding, like an overshared file (e.g. Q4_Financials.pdf), to a specific automated action and event timestamp. 

Get started

Customers can find CASB Policies in the Cloud & SaaS findings section of the dashboard today. Connect or update your Microsoft 365 or Google Workspace integration to Read-Write permissions, and create your first remediation policy. 

In the coming weeks, we’ll also be adding support for Custom Findings to CASB. Different organizations have unique needs when it comes to detection, and we want to give customers the ability to augment or define finding logic to fit those needs. 

New to Cloudflare One? Sign up for 50 free seats to get started with CASB, or talk to our team about a deployment at scale. For full setup instructions, visit our developer documentation.

Остани до края

Post Syndicated from Надежда Цекулова original https://www.toest.bg/ostani-do-kraya/

Остани до края

Концепцията, че майката е не просто обгрижващ възрастен, а източник на обич за бебето или малкото дете и ключов посредник между него и света, е описана научно за първи път през 40-те години на ХХ век. Тогава редица наблюдения на педиатри и психиатри водят до идеята, че дори безупречното задоволяване на медицинските и физиологичните нужди на едно бебе или малко дете не може да предотврати негативите от институционалните грижи и че връзката с обгрижващите възрастни всъщност е неделима част от развитието на детето. Оттогава теорията е изследвана и прецизирана през годините и днес стои в основите на семейно ориентираните грижи, включително в практиките, които насърчават родителското присъствие по време на болнично лечение на деца.

В България обаче все още често нуждата от лечение става причина за разделяне на семейства. Това се превръща в особено сериозен етичен въпрос, когато става дума за продължително лечение или за грижи в края на живота. Причините са сложни и обхващат както остарялата и неподходяща инфраструктура, така и остарелите практики и нагласи. 

Зад всички сложни проблеми обаче стоят човешки истории. В случая – най-тежките, които героите на тези истории са преживели.


Елица*

Срещам се с родителите на Елица пред входа на центъра за настаняване от семеен тип, в който тя живее, а те я посещават почти всекидневно. Носят голяма чанта с вещи – активна гимнастика, играчки, консумативи. Познах родителите отдалеч, макар никога да не ги бях виждала. 

Елица е на две години. Дълго чакано дете от следена под лупа бременност. Ражда се обаче с множество проблеми, които изискват както редица активни медицински интервенции, така и постоянни специални грижи. 

До последно смятахме, че всичко ще е наред. Бяха ни казали само, че може да е с по-ниско тегло. Първия път, когато ми я дадоха, я бяха повили и почти нищо не се виждаше от нея. По-късно я взеха и едва тогава разбрах всичко,

разказва майката. Елица има лицеви изменения, които са добре познати на медицината. На популярен език се наричат заешка устна и вълча уста. Наред с тези иначе решими проблеми обаче момиченцето има аномалии на опорно-двигателния апарат, както и на вътрешните органи, заради които лекарите прогнозират, че ще живее не повече от две седмици. 

„Бяхме в шок“, споделя баща ѝ. 

Двете седмици обаче отминават, бебето преживява животоспасяваща коремна операция и след още известно време, прекарано в отделението по неонатология, социалните препоръчват, а съдът решава официално да изведат Елица от семейството и да я настанят в Център за настаняване от семеен тип. Аргументът е, че там може да се полагат медицински грижи за деца в тежко състояние и момиченцето ще има шанс да наддаде на тегло, да се стабилизира и да се извършат поредица от операции, които да направят живота му възможен. Центърът за настаняване е в друг град, на около 200 км от дома на семейството. „Ходехме да я видим всеки вторник“, припомня си бащата. „Освен един, когато имаше грип. Тогава я видяхме само през стъклото“, допълва майката. 

Просто добави радост. Какво са съвременните палиативни грижи за деца

Разполагаме със здравна система, която все още не успява да се пречупи така, че да осигури детство там, където заболяването е отнело почти всичко друго. Как изглеждат детските палиативни грижи в България? Първи текст от новата поредица на Надежда Цекулова за детските палиативни грижи.

Докато ми разказват историята си, родителите си играят и паралелно говорят с малката Елица. Тя не изглежда като повечето двегодишни деца. През носа ѝ минава тръбичка – това е сондата, през която се влива специалната медицинска храна. Момиченцето е по-малко, едва около 7 килограма, а ръцете и крачетата му не са развити както на повечето му връстници. 

Но когато баща му говори – тихо и бавно – то го слуша с огромно внимание. 

Питам ги дали ги разпознава. „О, да. И не само това. Преди идвахме вечер след работа, към 5 часа. Сестрите казват, че като наближи този час, започва да се върти“, разказва бащата. „Чака ни“, пояснява майката и започва да закача детето: „За теб говорим, мамо…“

Как си говорят Елица и нейните родители – малък момент на нежност в едно кратко аудио:

Разговорът ни се провежда в центъра за настаняване от семеен тип, в който Елица е преместена преди около година от по-далечния град. Този е само на няколко километра от селото на родителите, а екипът подкрепя семейството да бъде заедно колкото може повече. С активното им съдействие родителите получават разрешение от Отдела за закрила на детето дъщеря им да гостува в семейния им дом. И все пак посещенията на Елица в дома на собственото ѝ семейство са рядкост. Надеждата на родителите е, че дъщеря им ще укрепне достатъчно, за да бъде оперирана и да започне да се храни без сонда – това е пътят ѝ към прибиране у дома. 

„Гледането е тежко“, отбелязва някак неочаквано майката, а бащата допълва: „Проблемът е, че за деца с тежки увреждания няма много варианти – например дневен център, където да можеш да го заведеш през деня… и може би ще бъде много трудно…“ 

Ще бъде много трудно, аз вече съм го осъзнала,

слага точка на емоционалното отклонение майката. Двамата се връщат към практическите въпроси около организирането на операциите на малката Елица. „Това много се проточи, бавно става – споделя баща ѝ. – Просто искаме да си я вземем у дома.“ 

Как да говорим за деца с тежки заболявания. Право, етика и човечност

Публичният разговор за тежко болните деца често се движи между две крайности – патетична жалост и почти пълно мълчание. Там някъде са и самите деца и семействата им. Как да се говори за страдание, без то да се превръща в сюжет? От Надежда Цекулова.

Диана и Ида

С Диана се срещам, за да проведа най-трудния разговор – този, в който родителите си вземат у дома само въпросите и съмненията. Аз задавам твърде малко въпроси – майката има достатъчно. Историята се излива от Диана, сякаш в последните месеци само е чакала някой да бъде там, за да я чуе: 

„Много ми е противоречиво все още усещането дали имам свободата да разкажа за това, което ни се случи, защото имах близначета. И историята с двамата е много различна. Знам, че има родители, които са изгубили единственото си дете, и за тях е още по-тежко. Аз имам и едно по-голямо дете и успявам някак си да разделя тези две вселени. Едната вселена е нашето ежедневие, в което аз имам моите две момчета, за които да се грижа, които да обичам, и мога да функционирам нормално. Другата са моментите, в които мога да притихна, в които съм сама, и тогава преминавам отново през всичко, което се случи. 

Близнаците ми се родиха преждевременно, почти в 34-тата седмица. Малкото ми момиченце Ида се роди първо. Тогава не разбрах, че се е наложило реанимиране – аз чух проплакването и след това я отведоха, без да ми я покажат дори. Минута по късно се появи малкото ми момченце Йоан. Видях го за секунди, след това отнесоха и него. 

Часове по-късно се появи една лекарка, която ми се скара защо съм тръгнала да раждам в тази болница, в която неонатологията не е на необходимото ниво. Трябваше да дам съгласие да извозят малкото ми момиченце към специализирана неонатология с повече възможности за поставяне на сърфактант. След още известно време я доведоха с креватчето, за да си я видя. Това беше първата ни среща, но тя спеше, а аз бях все още на легло, не успях дори да я докосна, преди да я преведат в другата болница. По-късно преведоха и Йоан. 

Близо седмица се обаждах всеки ден за информация. След като ме изписаха, една събота беше, ги видяхме, като тогава не беше ден за свиждане. Мънички ми се сториха, безкрайно най-сладките и красиви бебчета. Дори не ми мина през ума да попитам дали мога да си ги пипна по ръчичките… Просто ги гледахме. 

На следващия ден ми се обадиха. Ида беше получила гърч. След това изпадна в кома. Тази кома продължи пет месеца и няколко дни. 

Когато умира дете. Палиативни грижи в края на живота

Никой не отваря с желание текст за това как умират деца. Но зрелостта на едно общество личи не само по темите, които го забавляват, а и по онези, за които намира сили да мисли. Защото грижата не свършва там, където надеждата се изчерпва. От Надежда Цекулова.

И така, в първите може би 6–7 дни повечето лекари там подаваха някакъв вид успокоение, че е възможно комата да е и заради успокоителните. След като направихме образно изследване на мозъка обаче, стана ясно, че е пострадал необратимо. И след това за мен започна едно продължително свободно падане в някакво неясно пространство. Сякаш нямах силата да попитам и да ми обяснят малко повече, тоест беше едно такова просто дълго изчакване без яснота на какво мога да се надявам. 

Йоан го изписаха някъде на 40-тия ден. Давам си сметка, че те се опитваха да ги задържат близо един до друг. Тоест наистина имаше някакви неща, които усещах, че правят отвъд медицината, за да има някакво успокоение и за нас като родители, и за тях двамата. Въпреки стъклената преграда на кувьозите се опитвах да давам цялата си обич и знам, че и бебчетата ми го усещаха. 

Лекарите от неонатологията ми позволяваха да оставям малки предмети и играчки в кувьоза – осветени дрешки, икона, играчки, подаръчета за Коледа, музикална парцалена кукла, която Дядо Коледа подари на Ида, ангелче. Разбира се, винаги пакетирани в стерилизиран плик. Опитвах се да бъда най-добрата възможна майка за малкото време, което имахме заедно. 

И обичта беше там. 

Това беше един голям урок по сила и обич, който с малката ми Ида споделихме. Вечер си представях, че я погалвам, че съм до нея и ѝ пожелавам главичката и сърчицето ѝ да са здрави, изпращах обич и знам, че усещаше това.

Ходех на регулярните свиждания два пъти седмично, които са по около час. Тогава и всички други родители на бебенца в отделението са там, а лекарите минават и дават информация. Опитвах се да ходя и още веднъж-два пъти в седмицата в някакви следобедни часове през уикендите например, в повечето случаи са ме допускали. Все пак се съобразявах кой е дежурен лекар, и не стоях дълго.

Вече беше може би на третия месец, когато видях, че една от сестрите безкрайно нежно и опитно погалва и гушка в кувьоза и другите бебчета, както и моето. И всъщност това беше моментът, в който си дадох сметка, че мога да не подавам само ръчичката, а може би мога да я погаля по главичката. Но разговорът докъде може да стигне контактът помежду ни всъщност никога не е воден. Това може да е моя грешка, мой пропуск. Но просто когато наистина всеки ден по телефона чуваш колко е сериозно положението, се страхуваш да не навредиш. 

Големият отсъстващ. Детските палиативни грижи в публичните политики и в публичния дебат

Детските палиативни грижи в България остават почти невидими – и в законите, и в обществения разговор. Политиките свеждат темата до болници и терминални състояния, а медиите рядко говорят за качество на живот, достойнство, радост и игра. Цената я плащат децата и семействата им. От Надежда Цекулова.

Точно на Нова година бяхме с мъжа ми при кувьоза и тогава при нас дойде заместник-директорът на болницата. Имахме ужасен разговор. Той ни намекна, че трябва да решим какво да правим, защото това може да продължи твърде дълго. Че в някакъв момент може да започнат да се образуват декубитални рани и да е много тежко да се гледа. Този разговор не бива да се случва така на никое семейство, на такова място, по този начин… 

Ние всъщност до този момент не бяхме осмислили какво означава „много лоша прогноза“, макар някои от лекарите да бяха опитали да ни намекнат, че в един момент сърчицето ѝ ще се предаде. 

В деня, в който се случи най-лошото, беше обявена някаква грипна ситуация. От отделението ми казаха, че предпочитат да не ходя, но аз настоях, защото бях ваксинирана. 

Всъщност слава богу, че отидох, защото постоях малко по-дълго време. Имаше едно потрепване на очичките, особено когато я погалвах, и мисля, че наистина си беше някакъв вид реакция на душичката, че съм близо до нея. 

Когато отидохме в деня, след като Ида отлетя, всъщност беше първият път, в който я прегърнах. Нещо, от което през цялото време много ме беше страх, и се чудех дали ще намеря силата да го направя. Но всъщност дори не се замислих. Това беше най-правилното и истинско нещо, което можех да направя в този наш път заедно.“

Христо

Никое общество не е изградило система, която да подготвя родителите да погребват децата си, защото това противоречи на естествения ход на живота. Но всичко е много различно, когато тези хора получават подкрепа в процеса,

казва Христо към края на интервюто ни. Той е лекар. Млад лекар, защото в тази професия се учи дълго, затова се остарява бавно. Христо е известен като д-р Христов и е анестезиолог, работи като детски анестезиолог и реаниматор, бил е най-младият координатор по донорство. Говорим с д-р Христо Христов как в една недружелюбна система да се намери балансът между нуждата от медицински грижи и нуждата от родителска подкрепа на децата пациенти, когато липсват условия да бъде откликнато едновременно и на двете. Особено когато тези пациенти са в края на живота си. 

„Аз съм работил в интензивно отделение, където родителите са придружавали детето, и беше много хубаво“, разказва д-р Христов. По думите му, това е по-скоро изключение, тъй като в повечето лечебни заведения нито интензивните отделения са пригодени да посрещнат придружител, нито медицинският екип се чувства спокоен да работи в присъствието на родител. Според анестезиолога липсва опит с тази практика: 

Всъщност родителите са спокойни, защото знаят какво се случва с детето им, какво правим, то спало ли е, яло ли е, боли ли го, тъжно ли е – родителят е там и вижда, и може да бъде от полза за детето си. 

Доверието между родители и медици е компрометирано, смята д-р Христов, и това създава допълнителни пречки. „Много лекари в България не са виждали грижа за пациента вкъщи и не вярват, че такава грижа може да бъде полагана както трябва“, смята той. „Имаше едно дете, което беше престояло в болницата две години – разказва още лекарят. – Колегите бяха осигурили апаратура, с която да може да си отиде вкъщи, но не намираха сили да го изпратят у дома, защото ги беше страх, че вкъщи то ще умре.“ 

Тази история завършва с успешното събиране на семейството. Пътят минава през упорита работа на екипа с родителите, за да се обучат и да могат в своето село, на часове път от лекуващия екип, да отговарят на нуждите на детето си. „Да, това дете ще трябва да влиза в болница. Няма да е лесно. Но ще има качествено време у дома със своето семейство“, убеден е д-р Христов. 

Между лекарствата и играчките – да избягаме от медицинския модел

В Русе има място с почти невъзможно за запомняне име, но с трудно забравими истории. Надежда Цекулова посещава център, в който живеят деца с тежки заболявания и комплексни потребности, за да се опита да разбере какво означава добра грижа в България днес.

При тежки състояния, когато медицината изчерпи възможностите си за активно лечение и стане ясно, че повече нищо не може да се направи за излекуването на едно дете, фокусът на грижите се измества към неговото семейство. Според д-р Христов, когато едно заболяване е в терминален стадий или е настъпила мозъчна смърт, медиците трябва да бъдат честни с близките, да ги подготвят и да им осигурят време, подкрепа и възможност да прекарат последните си часове заедно в спокойствие и с достойнство. „Имали сме случаи, в които сме чакали някой от семейството да се прибере от чужбина. Или да го обсъдят помежду си, да съумеят да го осмислят и да се сбогуват“, споделя той. 

В много случаи обаче такова време „заедно“ просто няма как да се осъществи пълноценно в нашата система. „Общественият разговор, който липсва, е какво всъщност е в най-добрия интерес на детето, когато медицината не може да го излекува – дали да прекара останалата част от живота си в кувьоз, или в болнична стая, защото това би му осигурило повече дни, или да има по-малко време, което обаче да прекара със семейството си. Този въпрос няма лесен или еднозначен отговор, но за да бъдем честни към семействата, трябва да започнем да го поставяме.“

* Имената на родителите и децата са променени.

Какъв национален хоризонт чакаме от президента?

Post Syndicated from Емилия Милчева original https://www.toest.bg/kakuv-natsionalen-horizont-chakame-ot-prezidenta/

Какъв национален хоризонт чакаме от президента?

Месец и половина преди осмите преки президентски избори българските граждани знаят имената на кандидатите. Но знаят ли какъв президент избират? „Обединител на нацията“, както твърди политическото клише? Церемониалмайстор на държавата? Или коректив на властта, от когото се очаква да вижда по-далеч от следващия бюджет и следващото правителство?

Когато през 1990 г. Националната кръгла маса обсъжда създаването на президентската институция в новата конституция, отрежда на държавния глава далеч по-съдържателна роля. Той трябва да бъде „арбитър и гарант“ за нормалното функциониране на държавата, националната сигурност, териториалната цялост и международните ѝ ангажименти, казва Георги Пирински (БКП). И още: да пази баланса на интересите и правовия ред в полза на всички граждани, а не на отделна част от тях.

Президент на всички българи. Парламентарно представен

България очаква своя спасител, епизод пореден – президентските избори са хубав повод. Емилия Милчева разнищва потенциалните стратегически ходове на партиите – дори на онези…

Тогавашният представител на СДС Крум Неврокопски добавя друго определение: президентът е „гарант и арбитър за националното съгласие“, но и „гарант за бъдещето“ – фигура, призвана да утвърждава посоката напред и да осигурява мирния преход към демокрация. Така е замислена институцията в началото – като гарант, че политическото противопоставяне няма да разруши държавата и нейното бъдеще.

В Конституцията обаче президентът не е наречен нито обединител, нито арбитър. Според чл. 92 той е държавен глава, който „олицетворява единството на нацията“. Глаголът олицетворява е важен: 

президентът не е натоварен да създава единство там, където има различни убеждения и политически конфликти, а да представлява нацията като цяло – включително и гражданите, които не са гласували за него.

Още през 1995 г. Конституционният съд пресича удобното тълкуване, че държавният глава трябва да стои безмълвен и равноотдалечен от всички. „Националното единство не означава политическо единомислие“, се казва в Решение №25. Президентът не е деполитизиран орган: той има право да заема позиции, да отправя политически послания и да издава актове със съществени политически последици. Неговата надпартийност не е безразличие, а задължение да преценява властта и политическите конфликти от гледна точка на Конституцията и интереса на цялата общност, а не на партията, която го е издигнала.

„Длъжностната характеристика“ на практика

Петимата президенти след началото на демократичните промени влизаха на „Дондуков“ 2 в различна България, а и с различна представа каква посока да отстоява държавата. Представите им се формираха от политическите сили, които ги излъчваха, но и от техните убеждения и зависимости. 

Първият пряко избран президент Желю Желев не произнася програмна реч при полагането на клетвата си през януари 1992 г. – само подписва клетвения лист. Неговата заявка обаче е зададена още от биографията и политическата му роля: демонтиране на тоталитарната държава, утвърждаване на парламентарната демокрация и връщане на България към Европа.

Желев: коректив и „Боянски ливади“

Философът и един от водачите на демократичната опозиция Желев показа как президентът може да бъде коректив на политическата сила, която го е издигнала. Но „Боянските ливади“ оставят открит въпроса къде свършва корективът и откъде започва намесата в управлението. На пресконференцията от 30 август 1992 г. той обвини кабинета на Филип Димитров, че е влязъл в конфликт с медиите, синдикатите, Църквата, Президентството и извънпарламентарните сили. Два месеца по-късно правителството на „сините“ изгуби поискания вот на доверие, след като ДПС и част от депутатите, избрани от СДС, отказаха подкрепа. 

Намесата на Желев задълбочи разцеплението и придаде институционална тежест на атаката срещу кабинета. Следващото правителство на проф. Любен Беров, подкрепено от БСП и ДПС, не донесе нито по-голяма прозрачност, нито по-убедителни реформи. Затова „Боянските ливади“ остават двусмислен епизод: доказателство за независимостта на президента от собствената му политическа среда, но и предупреждение, че корективът може да разклати властта, без това да е от полза за демократичния преход. 

Националният хоризонт при Желев беше по-ясен от вътрешнополитическите му маневри: демокрация, европейска принадлежност и излизане от съветската орбита. През февруари 1994 г. той подписа рамковия документ за включването на България в програмата на НАТО „Партньорство за мир“ – първата институционална крачка по пътя към членството в Алианса.

Стоянов: посоката е ЕС и НАТО

При юриста Петър Стоянов ролята на президента като коректив и носител на национален хоризонт се прояви още преди официално да встъпи в длъжност. Той положи клетва на 19 януари 1997 г. в държава с хиперинфлация, масови протести и рухнало доверие в управлението на БСП. В първата си реч поиска предсрочни избори, валутен борд и „нова воля за промяна“. Но най-важната му заявка беше посоката: България трябва да избере „европейския тип цивилизация“ и интеграцията в Европейския съюз и НАТО.

Две седмици по-късно Президентството се оказа в центъра на политическата криза. На 4 февруари 1997 г., след заседание на Консултативния съвет за национална сигурност и преговори между основните политически сили, БСП върна мандата за съставяне на ново правителство. Последваха служебен кабинет и предсрочни избори. Стоянов не изведе сам България от кризата, но използва авторитета и инструментите на президентската институция, за да предотврати продължаването на управление, изгубило обществена легитимност.

Неговият хоризонт беше формулиран ясно: върховенство на закона, пазарна икономика и необратима принадлежност към ЕС и НАТО. Това беше и мярката, с която Стоянов оценяваше текущата политика. В момент на дълбоко разделение той не обедини всички около общо мнение. Помогна да се постигне съгласие накъде да върви държавата. 

И макар да беше избран с гласовете на избирателите, довели на власт и ОДС, и кабинета на Иван Костов, отново настъпи разрив между него и изпълнителната власт. 

На терена на постполитиката президентът е цар

Стига да поискат, политиците в България могат да продават лиценз за това как се линчува политиката, за да се замени с постполитика. На модерния Запад за тази цел бяха нужни десетилетия, но българите се справиха бързо и направиха една хубава работа, ама българска. Деидеологизация – няма ляво, няма дясно, и левите,

Първите признаци се появиха още през 1998 г., когато Стоянов започна да критикува кадрови решения и начина, по който СДС упражнява властта. До открит сблъсък се стигна през април 2000 г., след обвиненията на уволнения вътрешен министър Богомил Бонев за корупция във властта (Бонев беше отстранен поради съмнения за същото). Стоянов упрекна премиера, че не обяснява причините за смените в правителството от декември 1999 г. 

Последва разгром на сините на изборите през 2001 г., когато отношенията между премиер и президент фактически бяха прекъснати. Стоянов се кандидатира за втори мандат като независим, макар и подкрепен от ОДС, и загуби, а Костов подаде оставка като лидер на СДС. 

Първанов: прегръдка с капитала

Единственият политически лидер, избран за президент – председателят на БСП Георги Първанов, встъпи в длъжност през 2002 г. Закле се в името на „националното помирение и съгласие“. След ожесточеното противопоставяне на 90-те години той предложи друга представа за Президентството – посредник между политическите сили, и даже се самоопредели като „социален президент“.

По време на двата му мандата България постигна двете големи цели на Прехода – членството в НАТО през 2004 г. и в ЕС през 2007 г. Първанов не беше техният архитект, но Президентството му осигури приемственост във външнополитическата посока. 

Договореният между него и Путин „Голям шлем“ от руски енергийни проекти не се превърна в национален хоризонт, а в източник на зависимости, политически спорове и провал. По изчисления на „Капитал“ „България пропиля поне 2,3 млрд. лв. в трите лошо обмислени енергийни проекта [АЕЦ „Белене“, газопровода „Южен поток“ и нефтопровода „Бургас–Александруполис“ – б.а.]“.

На 17 септември 2001 г. – по-малко от два месеца преди президентските избори – беше учреден бизнес клуб „Възраждане“. Сред основателите му бяха някои от най-могъщите фигури на Прехода: банкерът Емил Кюлев, президентът на „Мултигруп“ Илия Павлов и Васил Божков. В следващите години първите двама бяха убити от неизвестни и до момента извършители. 

Кюлев, който оглави клуба, след победата на Първанов стана и негов икономически съветник. Така още в началото на мандата около „социалния президент“ се оформи кръг, в който политическото влияние и едрият капитал се срещаха без особена дистанция. По-късно от американска дипломатическа грама, разпространена от WikiLeaks, се разбра, че Кюлев е финансирал кампаниите на Симеон Сакскобургготски и Първанов.

Близостта не се изчерпваше с „Възраждане“. Сред официалните спонсори на кампанията на Първанов за втори мандат фигурираха и фирми на Людмил Стойков – бизнесмен, чието име се появи в разследването на ОЛАФ за злоупотреби със средства по САПАРД. 

Това показва парадокса на Първановото „помирение“: президентът, който обещаваше да представлява губещите от Прехода, отвори Президентството за хората, спечелили най-много от него. Така социалната реторика започна да служи като прикритие на близостта между властта и едрия капитал. 

Дали не виждаме същата хамелеонщина и при Румен Радев?

Днес Първанов е един от хората в инициативния комитет, издигнал настоящата президентка Илияна Йотова и генералния директор на БТА Кирил Вълчев за президент и вицепрезидент. 

Плевнелиев: с план за бъдещето

Предприемачът Росен Плевнелиев дойде през 2012 г. със заявката да бъде „прагматичният президент“. Неговият речник беше различен: модернизация, конкурентоспособност, образование, електронно управление, иновации, енергийна независимост. 

Той опита да превърне Президентството в място за изработване на дългосрочни приоритети чрез националната програма „България 2020“ и чрез обществените съвети към институцията. Във встъпителното си слово обеща Президентството да бъде отворено за гражданите, защото „президентът не е началник на гражданското общество“.

Политическите кризи след 2013 г. го превърнаха и в коректив. След избухването на протестите #ДАНСwithme, предизвикани от избора на Делян Пеевски за шеф на контраразузнаването, Плевнелиев застана срещу кабинета „Орешарски“. По време на мандата си той назначи две служебни правителства, защитаваше категорично европейската принадлежност на България и осъди руската анексия на Крим. 

Избран с подкрепата на ГЕРБ, Плевнелиев имаше хоризонт, но не и политическа тежест. В рамките на президентския си мандат изработваше стратегии и защитаваше позиции, които така и не станаха част от дневния ред на правителствата на Бойко Борисов. 

Радев: архитект на промяна

През 2017 г. бившият командир на Военновъздушните сили ген. Румен Радев влезе в Президентството като коректив. Във встъпителната си реч той посочи корупцията, неравенството, обезлюдяването като нерешените проблеми на Прехода. Радев декларира, че членството в ЕС и НАТО е стратегически избор, който не бива да бъде поставян под въпрос, но добави формулата, която предвещаваше бъдещата му политика: българската външна политика трябва „да се формулира у нас и да се отстоява навън, а не обратното“.

През първия мандат противопоставянето на Борисов постепенно се превърна в главната му политическа роля. Кулминацията настъпи с протестите от 2020 г. и „Мутри, вън!“. Президентът застана на страната на общественото недоволство, но не предложи ясна програма за времето след Борисов.

През 2022 г. заявката вече беше по-голяма. Радев сам формулира тази роля:

Мой дълг като държавен глава е да връщам дневния ред към дългосрочните цели на нацията, далеч отвъд хоризонта на политическите мандати.

Обяви още, че Президентството трябва едновременно да „катализира обществената трансформация“ и да бъде „стожер на стабилността“. Това вече беше заявка за архитект на следващия политически период. Продължителната парламентарна криза и поредицата от служебни кабинети му дадоха възможност да превърне Президентството в център на изпълнителна власт. 

Въпреки знаменитата му реплика в кампанията през 2021 г. в отговор на въпроса „Чий да е Крим?“ – „Руски, какъв да е!“, той получи подкрепата на „Продължаваме промяната“, а и на част от „Демократична България“ за втория мандат.

Успя ли Радев да превърне отрицанието на стария модел в национален хоризонт? Беше коректив – понякога необходим, друг път пристрастен и избирателен. Сега като премиер с парламентарно мнозинство е неубедителен в уверенията, че демонтира олигархията.

Пирамидата

Абсолютното мнозинство на „Прогресивна България“ пренарежда властовия модел и предлага централизиран контрол с бързи решения и по всяка вероятност слаб отпор. Кой с какви заявки влиза в 52-рия парламент? От Емилия Милчева.

Кандидатите – посока или позициониране

Какво се чува в заявките на сегашните кандидати? 

Заявката на Илияна Йотова и Кирил Вълчев е за приемственост (на политиката на Радев). Президентството трябва да бъде „място за диалог, а не за партийни решения“, казва Йотова, а Вълчев обещава да работи за културата. Към това се прибавя и предложението на Йотова за „коалиция за мир“, която да настоява за преговори с Русия.

Имаме си президентка. И?

Имаме си президентска институция с жена начело, но то е по стечение на обстоятелствата, а не защото сме я избрали и сме решили, че тъкмо нея искаме тъкмо на това място. За жените в българската политика и защо президентКАТА не е пробив – от Светла Енчева.

Вълчев внася и културен национализъм: България, свързана от езика, историята и културата и чрез българите зад граница. Той познава общностите в чужбина – посетил е 191 от 193 държави в ООН. Към това се прибавят обещанието му да показва българския принос в Европа и намерението на двойката да „съживи културата“. 

Остава неясно как разбират мястото на България в самата Европа – като държава, която участва в общите решения, или като периферия, която се отдръпва зад думите за мир?

При Андрей Гюров и Георги Кандев има хоризонт – единна, достойна и модерна България, неразделна част от обединена Европа, която гради икономика на знанието и разчита на хората като свой най-голям капитал. Към това се прибавят европейската принадлежност, равенство пред закона за всички граждани и държава, която предпочита можещите пред лоялните на властта. 

Неясното засега остава как президентът с ограничените си правомощия ще превърне тази картина на желаната държава в последователен политически дневен ред. 

По-съдържателна е заявката на Гюров за президентство, което не чака „ножът да стигне до кокала“, а оказва натиск властта да показва компетентност и отчетност. Иронията е, че срещу авторитарния Радев Гюров влиза в ролята, в която самият Радев натрупа политически капитал – президент, който беше критик на изпълнителната власт.

След 44 дни българите ще избират дали Президентството да продължи политиката на Радев, да ѝ се противопостави, или да предложи друга посока. Президентът не е длъжен да обедини всички около себе си. Длъжен е да каже какво да е общото помежду ни. 

Forgejo 16.0.4 and 15.0.8 address critical security vulnerability

Post Syndicated from jzb original https://lwn.net/Articles/1093671/

The Forgejo software-forge project has announced the
release of versions 16.0.4
and 15.0.8,
which fixes two security vulnerabilities. One is a critical flaw that would
allow remote-code execution (RCE):

When generating a new repository from a template repository, Forgejo clones the
template repository, removes the .git folder, performs variable template
expansion on files listed in .forgejo/template, and initializes a new git
repository. During this process, variable template expansion could be misused in
order to create a new .git folder, which git would adopt and incorporate during
its initialization of a new git repository. A malicious template repository
could be used to read arbitrary data from the Forgejo host, and to execute
arbitrary processes on the Forgejo host, as a remote code execution attack. To
address this issue, after variable expansion is completed, any existing .git
folder is removed from the directory before the git repository is initialized.

The project recommends upgrading to the latest version as soon as
possible.

[$] PostgreSQL 19’s “scary patch contest”

Post Syndicated from jzb original https://lwn.net/Articles/1092003/

PostgreSQL 19 was
expected to be released in September, in keeping with the database
project’s longstanding tradition of a major release every year. However,
some late-breaking concerns about several of the features slated for inclusion
has some developers worried about the quality of the release. On August 25, PostgreSQL
contributor Robert Haas sent
an email
with the subject “scary patch contest” about several patches
that have required an unusually large number of bug fixes leading up to the
release, which has raised questions about their readiness for a stable
release. One of the patches has been reverted, but several are still under heavy
revision, and an extra beta release has been slotted in to allow for additional
testing.

Building resilient real-time streaming workers with Amazon DynamoDB leases

Post Syndicated from Siddhesh Tiwari original https://aws.amazon.com/blogs/architecture/building-resilient-real-time-streaming-workers-with-amazon-dynamodb-leases/

Consider a real-time transcription service processing 500 concurrent meetings. Each worker processing these meetings requires a dedicated outbound WebSocket connection to an upstream streaming source. When a single worker fails, it drops 100+ connections, causing 2 to 3 minutes of data loss per connection until operators manually restart services.

Building real-time streaming workers that maintain hundreds of persistent WebSocket connections presents a coordination challenge: when a worker stops unexpectedly, its connections become unmanaged and data stops flowing. Exactly one worker must own each connection, yet workers fail, redeploy, and scale independently. Without a mechanism to track ownership and automatically transfer connections that healthy workers can claim, operators must intervene manually for every failure.

This pattern reduces manual intervention during failures, reduces connection recovery time from minutes to seconds, and helps minimize downtime during deployments without requiring external coordination services.

In this post, you learn how to build a WebSocket fleet management system on Amazon Elastic Container Service (Amazon ECS) and AWS Fargate. Amazon DynamoDB is the primary service that manages distributed lease ownership, coordination, and failover in this solution. For the compute layer, this post uses Amazon ECS on AWS Fargate to run the worker fleet. However, you can adapt this pattern to any compute layer of your choice, such as Amazon Elastic Kubernetes Service (Amazon EKS) or Amazon Elastic Compute Cloud (Amazon EC2) with Auto Scaling groups, without changing the core lease logic. You learn how to implement lease-based ownership with conditional writes, automatic failover through orphan reconciliation, and low downtime deployments through graceful shutdown.

The challenge: managing long-lived WebSocket connections

WebSocket connections are fundamentally different from HTTP requests. An HTTP request arrives, gets processed, and returns a response. The server holds no state between requests. A WebSocket connection, by contrast, is a persistent bidirectional channel. The worker must maintain an open TCP connection, process messages the upstream source sends, and respond to keep-alive pings from the upstream source.

This statefulness introduces several operational challenges:

Worker failures. When a worker process stops unexpectedly or its container terminates, the worker drops its WebSocket connections. The upstream source might buffer data briefly, but without a mechanism to detect the failure and reassign the connection to a healthy worker, the system loses data.

Rolling deployments. ECS rolling deployments terminate old tasks and start new ones. Each terminated task drops its connections. Without coordination, there’s a window where connections have no owner.

Horizontal scaling. Adding workers is straightforward. New tasks start and pick up work. Removing workers is harder. You need to drain connections from departing workers and verify other workers take over before the task exits.

Double-claiming. If two workers both believe they own the same connection, they both attempt to connect to the same upstream source. This can cause duplicate data processing, protocol errors, or connection rejection by the upstream service.

Because the workers are WebSocket clients that initiate outbound connections to upstream sources, you need a coordination mechanism that operates at the application layer rather than the network layer.

Solution overview

The architecture uses six AWS services to coordinate a fleet of WebSocket workers:

Architecture of the WebSocket fleet: API Gateway and Lambda write events to DynamoDB and SQS, and ECS Fargate workers claim leases and publish metrics to CloudWatch

Figure 1: WebSocket fleet management architecture

  1. Amazon API Gateway: You use this to receive START and STOP events from external systems through a REST API. A START event signals that a new streaming session (for example, a meeting or live feed) has begun and requires a dedicated WebSocket connection. A STOP event signals that the streaming session has ended and the connection should be released.
  2. AWS Lambda (event router): You use this to write connection state to Amazon DynamoDB and enqueue a notification to Amazon Simple Queue Service (Amazon SQS).
  3. Amazon DynamoDB: You use this to store connection state and lease ownership. Conditional writes (atomic operations that succeed only if specified conditions are met) can provide distributed locking capabilities without external coordination services.
  4. Amazon SQS: You use this to distribute work notifications to workers for fast pickup of new connections.
  5. Amazon ECS on AWS Fargate: You use this to run the worker fleet. Each worker polls Amazon SQS, manages WebSocket connections, and renews leases through heartbeats.
  6. Amazon CloudWatch: You use this to collect custom metrics (active connection count) that drive ECS automatic scaling.

The key insight is that DynamoDB conditional writes act as a distributed lock without requiring a separate coordination service. Each connection has a lease: a time-bounded ownership claim. Workers must continuously renew their lease. If a worker stops unexpectedly, the lease expires and another worker takes over.

Why not SQS alone or an existing lock client?

SQS plays an important role in this architecture as a fast notification channel, but it cannot serve as the sole coordination mechanism. SQS is designed for task execution, delivering a unit of work to one consumer. WebSocket connection ownership is not a one-time task. It is a continuous state that must be maintained and renewed for the lifetime of the connection. SQS has no mechanism to track who currently owns a connection, query for connections with no active owner, or represent the domain state (desired_state, ws_url, last_seq) needed to manage a connection. DynamoDB provides all these capabilities through persistent items, conditional writes, and secondary indexes.

The amazon-dynamodb-lock-client library published by AWS implements similar distributed locking primitives on DynamoDB. However, it is designed for Java environments and does not integrate domain-specific connection state into the lock record. This solution is implemented in async Python to match the worker architecture, combines lock ownership and connection metadata in a single DynamoDB item to reduce read operations, and uses a GSI to enable fleet-wide reconciliation queries that a general-purpose lock client does not provide.

The lease pattern

A lease is a row in DynamoDB that tracks who owns a connection and when that ownership expires. The table uses the following schema:

Attribute Type Description
Pk String (Partition Key) Connection ID, for example, CONN#meeting-123
desired_state String STARTED or STOPPED
ws_url String Upstream WebSocket URL to connect to
lease_owner String Worker ID that currently owns this connection
lease_expires_at_ms Number Epoch milliseconds when the lease expires
last_seq Number Last processed sequence number (for resumption)

A global secondary index (GSI), a secondary lookup structure that you can use to query on non-primary-key attributes, on desired_state (partition key) and lease_expires_at_ms (sort key) allows efficient queries for unmanaged connections: those with desired_state = STARTED and an expired lease.

A note on clock accuracy

The lease expiration mechanism relies on epoch millisecond timestamps generated by worker processes using their local system clocks. DynamoDB evaluates lease expiration conditions against the now value supplied by the calling worker, not against a DynamoDB server-side clock. This means all workers must have reasonably synchronized clocks for the lease pattern to behave correctly.

AWS Fargate tasks running in the same AWS region receive clock synchronization through the Amazon Time Sync Service, which keeps clock skew between tasks to within a few milliseconds. This is well within the safety margin provided by the default 20-second lease duration and 5-second heartbeat interval. If you deploy this pattern on compute infrastructure outside of AWS Fargate, verify that NTP synchronization is configured and monitor for clock drift. For environments where clock accuracy cannot be guaranteed, increase the lease duration by the maximum expected clock skew to prevent false lease expirations.

The lease lifecycle has four states. Figure 2 shows the lease state machine.

State machine showing the lease lifecycle transitions between the Acquire, Renew, Release, and Expired states

Figure 2: Lease lifecycle

Acquire

A worker claims a connection by writing its worker ID (lease_owner) and a future expiration timestamp (lease_expires_at_ms) to the DynamoDB lease record. The conditional expression ensures that only one worker can succeed: it checks that either no lease exists yet (attribute_not_exists) or the existing lease has already expired (lease_expires_at_ms < :now). If two workers attempt to acquire the same connection simultaneously, DynamoDB evaluates this condition atomically and only one worker succeeds. The other receives a ConditionalCheckFailedException and gracefully backs off.

The following code example is from the worker application (worker.py), which initializes the Amazon DynamoDB table client, worker ID, and configuration at startup. The complete implementation is available in the GitHub repository.

async def try_acquire_lease(pk: str) -> Optional[dict]:
    """Attempt to acquire lease on a connection."""
    try:
        resp = table.update_item(
            Key={"pk": pk},
            UpdateExpression=(
                "SET lease_owner = :w, "
                "lease_expires_at_ms = :exp, "
                "updated_at_ms = :now"
            ),
            ConditionExpression=(
                "attribute_not_exists(lease_expires_at_ms) "
                "OR lease_expires_at_ms < :now"
            ),
            ExpressionAttributeValues={
                ":w": WORKER_ID,
                ":exp": now_ms() + LEASE_SECONDS * 1000,
                ":now": now_ms(),
            },
            ReturnValues="ALL_NEW",
        )
        return resp["Attributes"]
    except ClientError as e:
        if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
            return None  # Another worker already owns this connection
        raise

The ConditionExpression is the critical piece: it succeeds when the lease does not exist yet (attribute_not_exists) or has already expired (lease_expires_at_ms < :now).

Renew

The owning worker renews its lease every few seconds (the heartbeat). The conditional expression verifies the worker still owns the lease:

async def renew_lease(pk: str) -> bool:
    """Renew lease for owned connection."""
    try:
        table.update_item(
            Key={"pk": pk},
            UpdateExpression=(
                "SET lease_expires_at_ms = :exp, "
                "updated_at_ms = :now"
            ),
            ConditionExpression="lease_owner = :w",
            ExpressionAttributeValues={
                ":w": WORKER_ID,
                ":exp": now_ms() + LEASE_SECONDS * 1000,
                ":now": now_ms(),
            },
        )
        return True
    except ClientError:
        return False  # Lost ownership

If renewal returns False, the worker knows it has lost ownership (perhaps another worker acquired the expired lease) and exits cleanly.

Release

During graceful shutdown, the worker explicitly releases its leases so other workers can acquire them immediately rather than waiting for expiration:

async def release_lease(pk: str):
    """Release lease on connection."""
    try:
        table.update_item(
            Key={"pk": pk},
            UpdateExpression=(
                "SET lease_owner = :empty, "
                "lease_expires_at_ms = :zero"
            ),
            ConditionExpression="lease_owner = :w",
            ExpressionAttributeValues={
                ":w": WORKER_ID,
                ":empty": "",
                ":zero": 0,
            },
        )
    except ClientError:
        pass  # Already released or taken by another worker

Expired

When a worker stops unexpectedly, because of a container crash, network partition, or process failure, it can no longer renew its lease. Unlike graceful shutdown, the worker has no opportunity to explicitly release ownership. The lease remains in DynamoDB with the crashed worker’s lease_owner value, but the lease_expires_at_ms timestamp passes without renewal.

This expired lease represents a connection with no active owner: desired_state remains STARTED (the connection should be active) but no healthy worker is managing it. The connection is now an orphan.

The reconciliation loop detects this condition by querying the GSI for records where desired_state = STARTED and lease_expires_at_ms < now. Any healthy worker that finds such a record can attempt to acquire it using the same conditional write used during initial acquisition. Because lease_expires_at_ms < :now is one of the valid conditions for acquisition, the expired lease is treated identically to an unclaimed one.

The Expired state is transient: it exists between the moment a lease stops being renewed and the moment the reconciliation loop runs and a new worker successfully acquires it. The maximum time a connection spends in the Expired state is bounded by the reconciliation interval (default: 60 seconds).

Technical implementation

The following sections walk through each component of the system, starting with how events enter the pipeline and ending with how the fleet scales.

Event ingestion

When an external system needs to start or stop a streaming connection, it sends an event to the Lambda event router through API Gateway. The Lambda function writes the connection state to DynamoDB and enqueues a notification to SQS:

def handler(event, context):
    payload = json.loads(event.get("body", "{}"))
    event_type = payload["event_type"].upper()
    connection_id = payload["connection_id"]
    pk = f"CONN#{connection_id}"

    if event_type == "START":
        table.put_item(Item={
            "pk": pk,
            "desired_state": "STARTED",
            "ws_url": payload["ws_url"],
            "last_seq": 0,
            "lease_owner": "",
            "lease_expires_at_ms": 0,
            "updated_at_ms": now_ms(),
        })
        sqs.send_message(
            QueueUrl=QUEUE_URL,
            MessageBody=json.dumps({"pk": pk})
        )

    elif event_type == "STOP":
        table.update_item(
            Key={"pk": pk},
            UpdateExpression="SET desired_state = :s, updated_at_ms = :t",
            ExpressionAttributeValues={
                ":s": "STOPPED", ":t": now_ms()
            },
        )

    return {"statusCode": 200, "body": "OK"}

DynamoDB is the source of truth for connection state. Amazon SQS serves as a fast notification channel. When a START event arrives, the SQS message immediately notifies available workers that they can claim a new connection, so workers do not need to wait for the next reconciliation cycle (default: 60 seconds) to discover and acquire the new connection. Without SQS, new connections would only be picked up when the reconciliation loop queries the GSI for unmanaged connections on its next scheduled run.

Worker polling

Each ECS Fargate worker runs a continuous SQS polling loop to pick up new connection notifications. The loop follows four steps before starting a new WebSocket connection:

1. Capacity check

Before accepting any new work, the worker checks whether it has reached its maximum connection limit (MAX_CONNECTIONS). If the worker is at capacity, it pauses for 5 seconds and skips the current polling cycle. This prevents a single worker from being overwhelmed while other workers in the fleet remain underutilized.

2. Deduplication

If the worker already manages the connection referenced in the SQS message (tracked in its local connections dictionary), it deletes the message and moves on. This handles cases where the same connection generates multiple SQS notifications, for example during retries or redeliveries.

3. Lease acquisition before WebSocket start

The SQS message is a hint, not a guarantee of ownership. Before starting a WebSocket connection, the worker must successfully acquire the DynamoDB lease using try_acquire_lease. If another worker has already claimed the connection, try_acquire_lease returns None and this worker skips it. This ensures exactly one worker owns each connection at any time.

4. Task creation

If the lease is acquired and desired_state is STARTED, the worker creates an async task to manage the WebSocket connection. The SQS message is then deleted regardless of whether the lease was acquired, preventing repeated reprocessing of the same notification.

The following code shows the full polling loop implementation:

async def poll_sqs():
    while not shutdown_event.is_set():
        if len(connections) >= MAX_CONNECTIONS:
            await asyncio.sleep(5)
            continue

        resp = await asyncio.to_thread(
            sqs.receive_message,
            QueueUrl=QUEUE_URL,
            MaxNumberOfMessages=1,
            WaitTimeSeconds=10,
            VisibilityTimeout=30,
        )

        for msg in resp.get("Messages", []):
            body = json.loads(msg["Body"])
            pk = body["pk"]

            if pk in connections:
                sqs.delete_message(
                    QueueUrl=QUEUE_URL,
                    ReceiptHandle=msg["ReceiptHandle"]
                )
                continue

            conn_data = await try_acquire_lease(pk)
            if conn_data and conn_data.get("desired_state") == "STARTED":
                asyncio.create_task(
                    manage_websocket(
                        pk, conn_data["ws_url"],
                        conn_data.get("last_seq", 0)
                    )
                )
            sqs.delete_message(
                QueueUrl=QUEUE_URL,
                ReceiptHandle=msg["ReceiptHandle"]
            )

Connection management

Once a worker acquires a lease, it opens a WebSocket connection to the upstream source and runs three concurrent async tasks for the lifetime of that connection. These three tasks work together to keep the connection alive, process incoming data, and detect when the connection should stop.

1. Heartbeat loop

The heartbeat loop calls renew_lease every HEARTBEAT_EVERY seconds. If renewal fails, meaning another worker has taken ownership or the lease record has changed, the loop exits immediately. This is the mechanism by which a worker detects that it has lost ownership of a connection mid-flight.

2. Receive loop

The receive loop processes every incoming message from the upstream WebSocket source. Each message is written to a separate DynamoDB messages table with the connection ID, a timestamp, the message data, and the worker ID. The loop runs continuously until the WebSocket connection closes or an error occurs.

3. Desired state checker

Every 10 seconds, the desired state checker reads the connection record from DynamoDB. If desired_state has been set to STOPPED, meaning an external system sent a STOP event through the API, the loop exits, signaling that this connection should be closed even though the WebSocket itself is still open.

How the three tasks interact

All three tasks run concurrently using asyncio.gather. When any one of the three tasks returns or raises an exception, asyncio.gather completes and execution moves to the finally block. This means a single trigger, lease loss, WebSocket closure, or a STOP event, is sufficient to cleanly end the connection regardless of the state of the other two tasks.

Cleanup

The finally block always runs, regardless of how the connection ended. It releases the DynamoDB lease so other workers can acquire the connection immediately and removes the connection from the worker’s local tracking dictionary.

The following code shows the full connection management implementation:

async def manage_websocket(pk: str, ws_url: str, last_seq: int):
    connections[pk] = {"pk": pk, "ws_url": ws_url, "ws": None}

    try:
        async with websockets.connect(ws_url) as ws:
            connections[pk]["ws"] = ws

            async def heartbeat_loop():
                while not shutdown_event.is_set():
                    await asyncio.sleep(HEARTBEAT_EVERY)
                    if not await renew_lease(pk):
                        print(f"[{pk}] Lost lease, closing")
                        return

            async def receive_loop():
                async for msg in ws:
                    data = json.loads(msg)
                    messages_table.put_item(Item={
                        "pk": pk,
                        "sk": str(now_ms()),
                        "message_data": data.get("data", str(data)),
                        "timestamp_ms": now_ms(),
                        "worker_id": WORKER_ID,
                    })

            async def check_desired_state():
                while not shutdown_event.is_set():
                    await asyncio.sleep(10)
                    resp = table.get_item(Key={"pk": pk})
                    if resp.get("Item", {}).get("desired_state") == "STOPPED":
                        return

            await asyncio.gather(
                heartbeat_loop(),
                receive_loop(),
                check_desired_state()
            )

    except Exception as e:
        print(f"[{pk}] WebSocket error: {e}")
    finally:
        await release_lease(pk)
        connections.pop(pk, None)

Production note: The code samples use print() for clarity. In production, replace these with structured logging (the Python logging module or Amazon CloudWatch Logs) and emit CloudWatch metrics for lease acquisition failures and reconnection events to support operational alerting.

Scaling note: The per-connection check_desired_state() loop shown here works for small fleets. At scale, replace individual GetItem calls with a single centralized loop that uses BatchGetItem to check the state of all active connections in one call, reducing DynamoDB reads from N calls every 10 seconds to 1 batched call.

Orphan reconciliation

The reconciliation loop is the safety net of the system. It runs on every worker periodically, independent of the SQS polling loop. Its sole purpose is to find connections that should be active but have no current owner, and reacquire them.

The loop queries the GSI for all records where desired_state = STARTED and lease_expires_at_ms is less than the current time. These are connections that an external system has requested as active, but whose lease has either never been claimed or has expired without renewal, indicating the previous owner is no longer running.

For each orphaned connection found, the worker calls try_acquire_lease. Because try_acquire_lease uses a DynamoDB conditional write, multiple workers can safely run reconciliation concurrently without risk of double-claiming. Exactly one worker succeeds for each connection. The others receive a ConditionalCheckFailedException and move on.

The reconciliation interval (default: 60 seconds) determines the maximum recovery time for unexpected worker terminations. A worker that crashes without running its graceful shutdown handler leaves its leases to expire naturally after LEASE_SECONDS (default: 20 seconds). The reconciliation loop then picks up those connections within the next 60-second cycle, giving a worst-case recovery time of approximately 80 seconds (20 seconds lease expiry plus up to 60 seconds reconciliation interval).

The following code shows the full implementation:

async def reconcile_orphaned_connections():
    while not shutdown_event.is_set():
        await asyncio.sleep(RECONCILE_EVERY)

        if len(connections) >= MAX_CONNECTIONS:
            continue

        resp = table.query(
            IndexName=GSI_NAME,
            KeyConditionExpression=(
                "desired_state = :state "
                "AND lease_expires_at_ms < :now"
            ),
            ExpressionAttributeValues={
                ":state": "STARTED",
                ":now": now_ms()
            },
            Limit=RECONCILE_PAGE_SIZE,
        )

        for item in resp.get("Items", []):
            pk = item["pk"]
            if pk not in connections and len(connections) < MAX_CONNECTIONS:
                conn_data = await try_acquire_lease(pk)
                if conn_data:
                    asyncio.create_task(
                        manage_websocket(
                            pk, conn_data["ws_url"],
                            conn_data.get("last_seq", 0)
                        )
                    )
Failover sequence in which a crashed worker’s lease expires and another worker reacquires the connection through orphan reconciliation

Figure 3: Automatic failover through orphan reconciliation

Graceful shutdown

When ECS sends a SIGTERM signal during a rolling deployment or scale-in event, the worker has a limited window to clean up before the container is forcibly terminated. Rather than dropping connections abruptly and waiting for leases to expire naturally, the worker performs a coordinated shutdown in three steps.

Step 1: Signal propagation

The signal_handler function sets a shared shutdown_event when SIGTERM is received. This event is checked by every running loop across all active connections. The heartbeat loop, the desired state checker, and the reconciliation loop all exit their while not shutdown_event.is_set() loops as soon as the event is set. No additional per-connection shutdown logic is needed. The shared event propagates the shutdown signal automatically to all concurrent tasks.

Step 2: Parallel cleanup

Rather than closing connections and releasing leases sequentially, which would take longer as the number of active connections grows, the worker closes all WebSocket connections and releases all leases concurrently using asyncio.gather. For a worker managing hundreds of connections, this keeps the total shutdown time roughly constant regardless of connection count.

Step 3: Immediate lease release

During graceful shutdown, the worker sets lease_expires_at_ms = 0 for each released connection. A value of 0 means the lease appears already expired to any worker running a reconciliation query. Other workers in the fleet pick up the released connections on their next reconciliation cycle rather than waiting for the original lease duration (default: 20 seconds) to elapse naturally.

Contrast with unexpected termination

Graceful shutdown is the fast path. When a worker exits cleanly through SIGTERM, connections are available for reacquisition within one reconciliation cycle. When a worker crashes unexpectedly without running the shutdown handler, leases expire naturally after LEASE_SECONDS (default: 20 seconds) and are then picked up by the reconciliation loop. Both paths converge on the same outcome, another worker acquires the connection, but graceful shutdown is significantly faster.

The following code shows the full graceful shutdown implementation:

shutdown_event = asyncio.Event()

def signal_handler(signum, frame):
    shutdown_event.set()

async def graceful_shutdown():
    await shutdown_event.wait()
    tasks = []
    for pk, conn in list(connections.items()):
        if conn.get("ws"):
            tasks.append(conn["ws"].close())
        tasks.append(release_lease(pk))
    await asyncio.gather(*tasks, return_exceptions=True)

Setting shutdown_event causes the heartbeat loops and state checkers to exit their while not shutdown_event.is_set() loops. The graceful_shutdown function then closes the active WebSocket connections and releases its leases in parallel. Released leases have lease_expires_at_ms = 0, which means the reconciliation loop on other workers picks them up on its next cycle rather than waiting for the original lease to expire.

Scaling the fleet

Each worker publishes a custom CloudWatch metric with its active connection count:

async def publish_metrics():
    while not shutdown_event.is_set():
        await asyncio.sleep(30)
        cw.put_metric_data(
            Namespace="WsFleet",
            MetricData=[{
                "MetricName": "ActiveConnections",
                "Value": len(connections),
                "Unit": "Count",
                "Dimensions": [
                    {"Name": "ServiceName", "Value": SERVICE_NAME}
                ],
            }],
        )

An AWS Application Auto Scaling target tracking policy scales the fleet based on the average ActiveConnections metric across all workers. When the average exceeds the target (for example, 700 connections per task), ECS launches additional tasks. New tasks start their SQS polling and reconciliation loops, picking up new connections and rebalancing the fleet.

Application Auto Scaling adds and removes ECS tasks based on the average ActiveConnections CloudWatch metric across the worker fleet

Figure 4: Automatic scaling based on active connection count

Scale-in is safe because of the lease pattern. When ECS terminates a task, the worker receives SIGTERM, releases its leases, and other workers acquire the freed connections through reconciliation.

Configuration Value Rationale
Lease duration 20 seconds Long enough to survive brief network hiccups, short enough for fast failover
Heartbeat interval 5 seconds Renew well before expiration (4x safety margin)
Reconciliation interval 60 seconds Balance between recovery speed and DynamoDB read cost
Max connections per task 700 Based on memory and CPU profiling per connection
Scale-out cool down 2 minutes Prevent thrashing during traffic spikes
Scale-in cool down 15 minutes Allow connections to stabilize before removing capacity

Tuning guidance. These values represent a starting point. Adjust based on your requirements:

  • Lease duration: Start with 20s. Reduce for faster failover, increase if network hiccups cause false expirations.
  • Heartbeat interval: Keep below lease duration. A 4:1 ratio (lease:heartbeat) gives 4 renewal attempts before expiry.
  • Reconciliation interval: Start with 60s. Reduce for faster recovery from unexpected terminations, increase to lower DynamoDB read cost.
  • Max connections per task: Start with 100 and increase while monitoring memory and CPU utilization in CloudWatch Container Insights. Each WebSocket connection typically consumes 2-5 MB of memory depending on message throughput.

DynamoDB cost considerations

The dominant cost driver in this architecture is heartbeat writes. Each active connection generates one update_item call per heartbeat interval, consuming 1 WCU. At the default 5-second heartbeat interval:

Active connections WCUs/second Approx. monthly cost (on demand) Approx. monthly cost (provisioned)
100 20 ~$65 ~$10
500 100 ~$325 ~$47
2,000 400 ~$1,300 ~$190

For production deployments at sustained high connection counts, use provisioned capacity with Auto Scaling rather than on-demand pricing. Heartbeat writes are predictable and consistent, which makes them well-suited to provisioned throughput. Configure Auto Scaling on your provisioned capacity to track connection count changes as the fleet scales.

To reduce cost, consider the following adjustments:

  1. Increase the heartbeat interval. Doubling the heartbeat interval from 5 seconds to 10 seconds halves WCU consumption. Maintain the 4:1 lease-to-heartbeat ratio by also doubling the lease duration. This increases the failover window proportionally.
  2. Increase the reconciliation interval. Increasing from 60 seconds to 120 seconds halves RCU consumption from reconciliation queries. This slows recovery from unexpected terminations.
  3. Use BatchGetItem for desired state checks. Replace the per-connection get_item calls in the check_desired_state loop with a single BatchGetItem call covering all active connections. This reduces RCU consumption from N reads per cycle to 1 batched read per cycle.

    GSI queries during reconciliation use eventually consistent reads by default, which halves the RCU cost compared to strongly consistent reads. Monitor your GSI read consumption in the DynamoDB console and adjust the reconciliation page size and interval to stay within your cost targets.

Conclusion

Managing long-lived WebSocket connections at scale requires explicit ownership tracking, automatic failover, and coordination across a fleet of workers. This post showed you a pattern that addresses these challenges using DynamoDB conditional writes as a distributed lease mechanism.

Key takeaways:

  • You can use DynamoDB conditional writes for atomic distributed coordination without external lock services. The ConditionExpression on update_item helps confirm one worker owns each connection at a time.
  • The heartbeat and reconciliation pattern handles the full failure spectrum. Lease expiration detects unexpected worker terminations. Graceful shutdown handles rolling deployments. New workers acquire leases and departing workers release them, making scaling safe.
  • This pattern applies to systems that manage long-lived WebSocket connections at scale: real-time transcription, IoT data ingestion, financial feed processing, or live event streaming.

Getting started

The complete implementation, including the worker application, Lambda event router, and Terraform templates for the DynamoDB table, SQS queue, and ECS cluster, is available in the GitHub repository. Follow the instructions in the repository README to deploy the infrastructure and validate the lease lifecycle with a small set of test connections.

For further enhancements, add distributed tracing with AWS X-Ray for end-to-end visibility across workers, and implement reconnection logic with upstream replay or offset-based resumption to handle data gaps between worker failure and recovery.

Further reading

How to migrate from Amazon CloudSearch to Amazon OpenSearch Serverless

Post Syndicated from Prasad Nadig original https://aws.amazon.com/blogs/big-data/how-to-migrate-from-amazon-cloudsearch-to-amazon-opensearch-serverless/

If you run search on Amazon CloudSearch, now is the time to plan your migration to Amazon OpenSearch Serverless. Modern search has moved on to capabilities beyond what CloudSearch provides: semantic and hybrid search, Retrieval Augmented Generation (RAG), and agentic search. OpenSearch Serverless gives you all of these with automatic scaling on a pay-for-what-you-use basis. You don’t need to choose or maintain infrastructure. OpenSearch Serverless maintains the hands-off, operational simplicity of CloudSearch.

This post shows you how to migrate your CloudSearch domain to an Amazon OpenSearch Serverless collection. We walk you through assessing your CloudSearch configuration, creating an OpenSearch Serverless collection with explicit index mappings, converting your documents and queries, configuring security policies, loading your data with Amazon OpenSearch Ingestion, and validating the migration before cutting over.

Key differences to note

Prerequisites

To follow along with this post, you need the following:

  • An AWS account.
  • An existing Amazon CloudSearch domain with indexed data.
  • Source data available in a durable store such as Amazon Simple Storage Service (Amazon S3) or Amazon DynamoDB (CloudSearch doesn’t provide a built-in export or backup feature, so your original source data is required to re-ingest into OpenSearch).
  • AWS Identity and Access Management (IAM) permissions to create and manage Amazon OpenSearch Serverless collections, encryption policies, network policies, and data access policies.
  • An Amazon OpenSearch Ingestion pipeline (or alternative ingestion method) for loading data.

Plan the migration

Planning is where you decide what success means: minimal downtime, no data loss, current functionality preserved, and custom configurations carried over. You don’t need to plan for infrastructure because OpenSearch Serverless provisions and scales compute for you. Your main planning task is to assess your current CloudSearch configuration so you can reproduce its behavior on the target.

Document your existing setup from the Amazon CloudSearch console. Record the current instance type, the partition count, and the replication count. Capture the total document count and overall data size, and record every field definition, including field types and the search, facet, and sort settings for each field. Note any analyzers, synonyms, stopwords, or custom rank expressions. Note whether you use the 2011 or the 2013 CloudSearch API version, because the 2013 API added faceting and filtering features that change how you model the target.

OpenSearch Serverless is the right target for most CloudSearch workloads, but not all of them. If your workload needs very low read-after-write latency (a short refresh interval), tight and predictable query response times, or direct control over instance configuration, choose an Amazon OpenSearch Service managed clusters deployment instead and size it from your workload profile.

The migration involves four main concerns: your source data format, your queries, your field definitions, and your access policies. Before you plan the details, it helps to see the whole migration at once. The following diagram maps the migration across four phases: your source CloudSearch environment, the migration pipeline that converts and moves your data, the OpenSearch Serverless target, and cutover and operations.

Migration workflow across four phases: source CloudSearch, migration pipeline, OpenSearch Serverless target, and cutover and operations

Figure 1: The migration workflow across four phases

In the source environment, you assess your CloudSearch configuration and back up your source data (Amazon S3, Amazon DynamoDB, or another store). Note the Source Data Format (SDF), the URL-based query syntax, and the IAM access policies you need to carry over. In the migration pipeline, you map field types, convert the data format from CloudSearch JSON to OpenSearch-compatible JSON, convert your queries to the OpenSearch query domain-specific language (DSL), configure security, bulk-ingest the data, and validate the result. The OpenSearch Serverless target holds the collection, index mappings, ingested documents, and the encryption, network, and data access policies, and it scales with your workload on a pay-per-use basis. In cutover and operations, you update your application to the new endpoint and clients, monitor with Amazon CloudWatch, and decommission CloudSearch once no traffic remains.

Model your data in OpenSearch Service

OpenSearch Service uses index mappings to define the fields and data types in an index. Because you know your CloudSearch schema, define the target mapping explicitly when you create the index. Create the index and set its mapping in a single request, and set dynamic to strict so OpenSearch rejects any document that contains a field you did not define. Strict mapping catches schema drift at ingest time, avoiding the default OpenSearch behavior of creating new mappings for undefined fields.

PUT /imdb_movies
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "genres": { "type": "keyword" },
      "rating": { "type": "float" },
      "release_date": { "type": "date" }
      ...
    }
  }
}

Field type mapping

The following table maps CloudSearch field types to their OpenSearch Service equivalents.

CloudSearch OpenSearch Service equivalent Notes
text text Text is tokenized. Stemming, synonyms, and stopwords apply. Good for matching user terms.
literal keyword Not tokenized. Good for exact-match search.
int integer Use for ranking, faceting, and narrowing.
double float or double .
date date .
boolean boolean .
latlon geo_point .
text-array text OpenSearch handles arrays natively, so map to the base text type.
literal-array keyword OpenSearch handles arrays natively, so map to the base keyword type.
multi-value nested or object .
long long .
binary binary .

Two mapping details deserve attention. First, pick the smallest numeric type that fits your data rather than copying the widths CloudSearch uses. CloudSearch stores integers as 64-bit values, but few datasets hold numbers that large. A long or a double consumes more disk than an integer, a short, or a float with no benefit when the values are small. Evaluate the actual range of each field and choose the narrowest type that holds it. Reserve long for values that genuinely exceed the roughly 2.1 billion ceiling of integer, and use float instead of double unless you need double precision. Smaller types shrink your index and speed up queries.

Second, if you sort or aggregate on a text field, add a keyword sub-field. The preceding example mapping has a keyword subfield for the title field. You access the field using dot notation: title.keyword. OpenSearch doesn’t sort or aggregate analyzed text fields by default.

As noted earlier, if you run several CloudSearch domains, model each one as a separate index within a single OpenSearch Serverless collection to consolidate them.

Move your data

Migrating to OpenSearch Service is a re-ingestion: you convert your source documents and index them into the collection you created. CloudSearch doesn’t provide a built-in backup or snapshot feature. It relies on the documents you send through the indexing process, so before you migrate, make sure your source data is available in a durable store such as Amazon S3, Amazon DynamoDB, or another database.

The conversion is a format translation. CloudSearch accepts data in SDF as JSON or XML, where a document batch is a collection of add and delete operations. The JSON that CloudSearch uses differs from the JSON that OpenSearch Service expects, so you must transform each source document into an OpenSearch document whose fields match the index mapping you defined earlier. Handle the same details the mapping calls out: emit each numeric value so it fits the narrow type you chose for its field rather than a wide long or double, format dates to match your date mapping, and drop or rename any field that your strict mapping doesn’t define.

CloudSearch batch format showing add and delete operations in JSON OpenSearch bulk batch format showing index operations in JSON

Figure 2: CloudSearch batch format (left) compared to OpenSearch batch format (right)

You can write a small conversion script. Have the script write its output to an Amazon S3 bucket so the converted documents live in a durable store you can re-ingest from as many times as you need.

With your converted documents in Amazon S3, use Amazon OpenSearch Ingestion to load them. Amazon OpenSearch Ingestion is a feature of Amazon OpenSearch Service that you can use to ingest, filter, transform, enrich, and route data to an Amazon OpenSearch Service domain or an OpenSearch Serverless collection. Configure an OpenSearch Ingestion pipeline with an Amazon S3 source (you can use an OpenSearch Ingestion blueprint to get started) that reads your converted documents. Let its built-in processors apply any final transformation before the pipeline writes to your collection. A managed pipeline reading from Amazon S3 gives you a repeatable, restartable load without operating ingestion infrastructure, which makes it the recommended path for most migrations.

If you prefer to load data directly, OpenSearch Service exposes a REST API, so you can index documents with a standard client such as curl or with the OpenSearch client libraries for many languages. Direct indexing is convenient for a small dataset or a quick test, but an Amazon S3 source with OpenSearch Ingestion is the better choice for a production migration.

Convert your queries

CloudSearch uses a URL-based query format. You pass a query parameter in the URL and submit either a simple string search or a JSON-formatted query. OpenSearch Service uses a REST API and the OpenSearch query DSL in the request body, which gives you compound queries, function scoring, and richer relevance control. You can use generative AI coding assistants to help with this translation. Provide your CloudSearch query patterns, and the model generates the equivalent OpenSearch query DSL, which you then validate against your test cases.

Query syntax changes

CloudSearch appends parameters such as sort to the query URL, while OpenSearch expresses sorting, filtering, and boosting as explicit elements of the request body. For example, a title search for “shakespeare” in CloudSearch looks like the following.

https://my-cloudsearch-domain.us-east-1.cloudsearch.amazonaws.com/2013-01-01/search?q=shakespeare&size=10

The equivalent query in OpenSearch Service uses the query DSL.

GET /imdb_movies/_search
{
  "query": {
    "match": { "title": "shakespeare" }
  }
}

To keep result sets consistent after migration, set the default operator to AND in OpenSearch to match the default query behavior of CloudSearch. The following table shows common CloudSearch query patterns and their OpenSearch Service equivalents, using a sample IMDB movies dataset.

Query type CloudSearch (Lucene syntax) OpenSearch Service query DSL
Compound AND title:"Inception" AND genres:"Sci-Fi" {"query":{"bool":{"must":[{"match":{"title":"Inception"}},{"match":{"genres":"Sci-Fi"}}]}}}
Compound NOT title:"Star Wars" AND NOT genres:"Comedy" {"query":{"bool":{"must":[{"match":{"title":"Star Wars"}}],"must_not":[{"match":{"genres":"Comedy"}}]}}}
Wildcard title:Batman* {"query":{"wildcard":{"title":{"value":"batman*"}}}}
Numeric range rating:[7 TO 9] {"query":{"range":{"rating":{"gte":7,"lte":9}}}}
Date range (after) release_date:[2015-01-01T00:00:00Z TO *] {"query":{"range":{"release_date":{"gte":"2015-01-01T00:00:00Z"}}}}
Boosting title:"The Matrix"^6 OR genres:"Sci-Fi"^4 {"query":{"bool":{"should":[{"query_string":{"query":"title": \"The Matrix\"^6","fields":["title"]}},{"query_string":{"query":"genres:\"Sci-Fi\"^4","fields":["genres"]}}]}}}
Sorting title:"Batman" sort=release_date desc {"query":{"match":{"title":"Batman"}},"sort":[{"release_date":{"order":"desc"}}]}

Sorting and boosting

Boosting is useful when you want certain fields or terms to carry more weight in relevance scoring. A higher boost value means the term contributes more to the score. OpenSearch also supports sorting by _score (relevance), which is the default when you specify no sort. For the full query language, see the OpenSearch query DSL documentation.

Configure security

CloudSearch uses AWS Identity and Access Management policies to control access to its configuration and domain service APIs. You attach user-based policies to an IAM role, user, or group, and the document, search, and suggest actions in those policies control access to the CloudSearch APIs.

OpenSearch Serverless applies security through policies at several layers.

  • Collections: Encrypted at rest by default, using either an AWS owned key or a customer managed key defined in an encryption policy.
  • Network policies: Define whether a collection is reachable privately through a virtual private cloud (VPC) endpoint or over the internet.
  • Data access policies: Control which IAM principals and Security Assertion Markup Language (SAML) identities can create indexes and read or write data in the collection.

Amazon OpenSearch Service provisioned domains also offer fine-grained access control, with role-based access control and security at the index, document, and field level. For OpenSearch Serverless, data access policies provide collection-level and index-level permissions, controlling which IAM principals and SAML identities can create, read, or write data within a collection.

Validate the migration

Validation confirms that the migration is complete and correct before you send production traffic to OpenSearch Serverless. Work through five kinds of validation.

  • Documents: Check your document count. Your OpenSearch Serverless indexes should have the same count as your CloudSearch indexes.
  • Queries: Translate your most important queries and run them manually against your collection. Spot check the output for the presence of important results.
  • Ranking: Check the order of results, especially for queries with custom rank functions or field weighting. Results might not match exactly, so look for anything that’s incorrect.
  • Latency: Ideally you should tee your production traffic to your Serverless collection to get real latency metrics. Worst case, generate at least 100,000 synthetic queries across all your query types and run them. Monitor OpenSearch Compute Unit (OCU) consumption with Amazon CloudWatch to understand your cost profile.

To validate search functionality, run the same query against both systems and compare the results. Reuse the query pairs from the conversion step so you exercise the syntax differences directly. For example, to check a numeric range against the sample IMDB movies dataset, run the following query in CloudSearch.

https://my-cloudsearch-domain.us-east-1.cloudsearch.amazonaws.com/2013-01-01/search?q=rating: [7 TO 9]&size=10

Run the equivalent query DSL against your OpenSearch Serverless collection.

GET /imdb_movies/_search
{
  "query": {
    "range": { "rating": { "gte": 7, "lte": 9 } }
  }
}

Confirm that both queries return the same set of movies. Then repeat the comparison for a query that exercises relevance, such as the boosted query from the conversion step, and confirm the top results appear in the same order.

GET /imdb_movies/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": { "query": "The Matrix", "boost": 6 } } },
        { "match": { "genres": { "query": "Sci-Fi", "boost": 4 } } }
      ]
    }
  }
}

Cut over and operate

When validation passes, update your application to use the OpenSearch Serverless endpoint and the query DSL, and switch from the CloudSearch SDK to the OpenSearch client libraries. After cutover, confirm that no application still points to a CloudSearch endpoint, retain your source data backups in Amazon S3 for rollback, and then delete the CloudSearch domain.

Operating OpenSearch Serverless in production is lighter than operating a domain, because OpenSearch Serverless scales compute for you and you do not tune shards, instance types, or capacity. Your focus shifts to cost and search quality. Monitor OCU consumption and search latency with Amazon CloudWatch, and set alarms on the thresholds that matter to you. Review OCU usage patterns to understand cost and find optimization opportunities, and set capacity limits on the collection to cap the maximum OCUs it can consume. For guidance, see Managing capacity limits for Amazon OpenSearch Serverless and Monitoring Amazon OpenSearch Serverless.

Cost considerations

With OpenSearch Serverless, you pay only for the compute and storage your workload consumes, and OpenSearch Serverless charges for compute and storage separately. OpenSearch Serverless scales indexing compute and search compute independently, so a write-heavy or a read-heavy workload scales only the dimension it needs, and compute can scale to zero when a collection is idle, in which case you pay only for storage. To share hardware across workloads, place collections in a collection group so they draw from the same compute rather than each provisioning its own. For pricing and unit details, see Amazon OpenSearch Service pricing.

Clean up

Because you’re migrating to OpenSearch Serverless, the resources that you’ve created will likely become your production resources. If not, delete any OpenSearch Serverless collections and S3 buckets you created to avoid incurring ongoing cost.

Conclusion

In this post, you saw how Amazon CloudSearch and Amazon OpenSearch Serverless compare, and how the concepts you rely on in CloudSearch (field types, query syntax, autoscaling, and access control) translate into OpenSearch Service. You assess your CloudSearch configuration, model your data with explicit OpenSearch mappings, move your converted documents into the collection with OpenSearch Ingestion, convert your URL-based queries into the OpenSearch query DSL, configure security, and validate before cutover. OpenSearch Serverless gives you the hands-off operational model you have with CloudSearch, and adds richer query capabilities, granular data access policies, and automatic scaling. To get started, create an OpenSearch Serverless collection on the AWS Management Console and follow the steps in this post.

To learn more, see the following resources:


About the authors

Prasad Nadig

Prasad Nadig

Prasad is a Senior Analytics Specialist Solutions Architect at Amazon Web Services (AWS), specializing in large-scale data analytics and AI. Prasad partners with customers to design, migrate, and modernize their analytics platforms on AWS into scalable, cost-effective solutions, with deep expertise in data lakes, data warehousing, distributed processing, and performance tuning at petabyte scale.

Jon Handler

Jon Handler

Jon is a Senior Principal Solutions Architect for Search Services at Amazon Web Services. Jon works closely with OpenSearch and Amazon OpenSearch Service, providing help and guidance to a broad range of customers who have search and log analytics workloads. Prior to joining AWS, Jon’s career as a software developer included four years of coding a large-scale, eCommerce search engine.

Accelerating Spark queries with Iceberg materialized views

Post Syndicated from Yuzhou Sun original https://aws.amazon.com/blogs/big-data/accelerating-spark-queries-with-iceberg-materialized-views/

In this post, you learn how to reduce Apache Spark query execution time with Apache Iceberg materialized views without changing a single SQL query.

Organizations running analytical workloads on their data lakes often hit a common wall: queries that are slow and costly, yet difficult to rewrite by hand. Multi-table joins, heavy aggregations, and window functions over large fact tables all drive up execution times, but the SQL behind them often can’t be changed. It might come from business intelligence (BI) dashboards, packaged independent software vendor (ISV) applications, or legacy reports, where editing the source introduces regression risk that outweighs the performance gain.

Starting with Amazon EMR 7.12.0 and AWS Glue 5.1, you can accelerate these queries without rewriting them. Automatic query rewrite analyzes the logical plan of each incoming query and compares it against a metadata cache of available MVs. When the optimizer finds a materialized view (MV) that satisfies all or part of a query, it rewrites the plan to read from that MV instead of the base tables. Matches can be structural (aggregations and joins) or exact (more complex patterns like window functions). If no MV matches, the original query runs unchanged with no impact on correctness.

If you have previously tried to speed up slow analytical queries, you might have considered one of the following alternatives. Here is how automatic query rewrite compares:

Query modification approach Stored results Refreshes Modification to existing queries
Standard views in AWS Glue No (re-runs each time) n/a Required
Custom ETL pipeline Yes Manual Required
Hand-rolled rewrite Yes Manual Required
Materialized views with automatic rewrite enabled Yes Automatically through AWS Glue Data Catalog on a schedule when configured Not required when supported

In this post, we:

  • Give a high-level overview of how automatic query rewrite works in Apache Spark.
  • Walk through a concrete example, showing how the same query can benefit from MVs at different levels of coverage.
  • Discuss the trade-offs so you can choose the right MV shape for your workload.

Prerequisites

To use automatic query rewrite with Iceberg materialized views, you need:

  • Amazon EMR release 7.12.0 or later, or AWS Glue 5.1 or later.
  • Source tables in Apache Iceberg or Parquet format, registered in the AWS Glue Data Catalog, in the same AWS Region and account as the materialized view. Parquet source tables are supported for automatic query rewrite starting with Amazon EMR 7.14.0 and AWS Glue 8.1.
  • An Amazon Simple Storage Service (Amazon S3) Tables (a capability of Amazon S3) bucket, or an S3 general purpose bucket, for the materialized view data.
  • Permissions for the definer role. You can use AWS Identity and Access Management (IAM) policies or AWS Lake Formation.
  • Automatic query rewrite turned on in your Spark session: --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true.
  • For Parquet source tables, set spark.sql.materializedView.v1SourceTables.enabled=true and spark.sql.materializedView.v1ETagVersioning.enabled=true.

For more Spark configurations, see Introducing Apache Iceberg materialized views in AWS Glue Data Catalog.

How it works

Here is how MVs and automatic query rewrite work together:

  • You define a SQL query with aggregations, joins, or filters across your supported source tables.
  • AWS Glue Data Catalog stores the precomputed results as an Apache Iceberg table in your Amazon S3 bucket. You can store it in a general purpose S3 bucket or in Amazon S3 Tables. Any Apache Iceberg-compatible query engine can read the materialized view, including Amazon Athena, Amazon EMR, AWS Glue, Amazon Redshift, and Iceberg-compatible third-party query engines. Automatic query rewrite is available on the AWS optimized Spark runtime in Amazon Athena, Amazon EMR, and AWS Glue. Other engines can query the materialized view directly, but they don’t rewrite queries to use it automatically.
  • Automatic refresh keeps the MV current on a schedule that you define, for example SCHEDULE REFRESH EVERY 1 DAY. You set it at creation time or later with ALTER MATERIALIZED VIEW ... ADD SCHEDULE REFRESH. At that scheduled time, the refresh process checks the current Apache Iceberg snapshot ID or Parquet file ETags and refreshes the MV when it detects source-table changes.
  • Automatic query rewrite redirects matching queries to the MV at query optimization time. Automatic query rewrite in Apache Spark uses two matching strategies:
    • Structural rewrite (adapted from Amazon Redshift) handles an MV defined as a single SELECT-FROM-WHERE-GROUP-BY block over INNER joins. The optimizer can roll up an MV’s aggregates to a coarser grain and pull extra query predicates up onto the MV scan.
    • Exact-match rewrite handles MVs defined as other shapes, such as window functions and outer joins, by matching a canonicalized form of the MV body against subtrees of the query plan.

When the optimizer evaluates a query, it consults a metadata cache of MVs from the configured catalogs and chooses the best match. It also checks MV staleness during optimization. It skips stale MVs, so rewrite won’t return stale results. If no MV matches, the original query runs unchanged.

Note that automatic query rewrite is opt-in: set spark.sql.optimizer.answerQueriesWithMVs.enabled=true when creating the Apache Spark session.

Example: One query with three potential MVs

An MV doesn’t need to cover an entire query to help it. Automatic query rewrite in Apache Spark operates on subtrees: when an MV matches a portion of your query plan, the rewriter substitutes that subtree and lets the rest of the query run on the rewrite output unchanged. The same query can therefore be served by many possible MV designs, each making a different trade-off between per-query speedup, storage cost, and reuse across other queries.

To make this concrete, consider a typical analytics query: Top 100 preferred US customers by total store spending.” It joins fact and dimension tables, applies two selective filters on the customer dimension, aggregates per customer, ranks the result with a window function, and keeps only the top 100:

SELECT c_customer_id, total_revenue, num_transactions, avg_purchase, revenue_rank
FROM (
    SELECT cust.c_customer_id,
        SUM(sales.ss_quantity * sales.ss_sales_price) AS total_revenue,
        COUNT(*) AS num_transactions,
        AVG(sales.ss_quantity * sales.ss_sales_price) AS avg_purchase,
        RANK() OVER (ORDER BY SUM(sales.ss_quantity * sales.ss_sales_price) DESC) AS revenue_rank
    FROM base_catalog.base_db.store_sales sales
    INNER JOIN base_catalog.base_db.customer cust
        ON sales.ss_customer_sk = cust.c_customer_sk
    WHERE cust.c_birth_country = 'UNITED STATES'
        AND cust.c_preferred_cust_flag = 'Y'
    GROUP BY cust.c_customer_id
) ranked
WHERE revenue_rank <= 100
ORDER BY revenue_rank;

Query 1: The original query. Top 100 preferred US customers by total store spending, before any materialized view.

Three MV designs cover progressively more of this query, from a single-table pre-aggregate to the full query body itself:

Tier 1: Pre-aggregate store_sales only, no join, no filter. This tier is a single-table aggregate of store_sales at customer-surrogate-key grain. The query still must join the customer table, apply both filters, re-aggregate at c_customer_id grain, and run the window function.

CREATE MATERIALIZED VIEW mv_catalog.mv_db.customer_tier_1 AS
SELECT ss_customer_sk,
    SUM(ss_quantity * ss_sales_price) AS sum_revenue,
    COUNT(ss_quantity * ss_sales_price) AS count_revenue,
    COUNT(*) AS num
FROM base_catalog.base_db.store_sales
GROUP BY ss_customer_sk;

Tier 1 MV: Single-table pre-aggregate of store_sales by customer surrogate key (no join, no filter).

The following plans compare the original query plan to the rewritten plan:

Window, filter, Sort
+- Aggregate by c_customer_id
:  total_revenue = SUM(ss_quantity * ss_sales_price)
:  num_transactions = COUNT(*)
:  avg_purchase = AVG(ss_quantity * ss_sales_price)
+- Project
   +- Join Inner ON ss_customer_sk = c_customer_sk
      :- BatchScan store_sales <- reads the large store_sales table
      +- Filter c_birth_country='UNITED STATES' AND c_preferred_cust_flag='Y'
         +- BatchScan customer

Plan 1: Original plan. Scans the large store_sales table.

Window, filter, Sort
+- Aggregate by c_customer_id <- rolls up pre-aggregated sums
:  total_revenue = SUM(sum_revenue) <- sum of sum_revenue
:  num_transactions = SUM(num) <- sum of num
:  avg_purchase = SUM(sum_revenue) / SUM(count_revenue) <- sum of sum_revenue / sum of count_revenue
+- Project
   +- Join Inner ON ss_customer_sk = c_customer_sk
      :- BatchScan customer_tier_1 <- reads pre-aggregated MV
      +- Filter c_birth_country='UNITED STATES' AND c_preferred_cust_flag='Y'
         +- BatchScan customer

Plan 2: Rewritten plan (Tier 1). Reads the pre-aggregated customer_tier_1 MV.

Tier 2: Pre-join store_sales x customer, pre-apply one filter (c_preferred_cust_flag = ‘Y’). The middle tier pre-joins both tables and bakes in the preferred-customer filter. The query still must apply the country filter as a residual on the MV scan and run the RANK() window.

CREATE MATERIALIZED VIEW mv_catalog.mv_db.customer_tier_2 AS
SELECT cust.c_customer_id, cust.c_birth_country,
    SUM(sales.ss_quantity * sales.ss_sales_price) AS sum_revenue,
    COUNT(sales.ss_quantity * sales.ss_sales_price) AS count_revenue,
    COUNT(*) AS num
FROM base_catalog.base_db.store_sales sales
INNER JOIN base_catalog.base_db.customer cust
    ON sales.ss_customer_sk = cust.c_customer_sk
WHERE cust.c_preferred_cust_flag = 'Y'
GROUP BY cust.c_customer_id, cust.c_birth_country;

Tier 2 MV: Pre-joins store_sales and customer, with the preferred-customer filter applied.

Rewritten query plan:

Window, filter, Sort
+- Aggregate by c_customer_id <- rolls up pre-aggregated sums
:  total_revenue = SUM(sum_revenue) <- sum of sum_revenue
:  num_transactions = SUM(num) <- sum of num
:  avg_purchase = SUM(sum_revenue) / SUM(count_revenue) <- reads pre-aggregated MV
+- Filter c_birth_country='UNITED STATES' [residual filter on MV scan]
   +- BatchScan customer_tier_2 <- reads pre-aggregated MV

Plan 3: Rewritten plan (Tier 2). Country filter applied as a residual on the MV scan.

Tier 3: Match the entire query, including the window function and top N filter. This is the most specific tier. The MV body is the target query verbatim (minus the top-level ORDER BY, which is meaningless for a stored set). The MV stores the top-ranked rows the query asks for (rank ≤ 100).

CREATE MATERIALIZED VIEW mv_catalog.mv_db.customer_tier_3 AS
SELECT c_customer_id, total_revenue, num_transactions, avg_purchase, revenue_rank
FROM (
    SELECT cust.c_customer_id,
        SUM(sales.ss_quantity * sales.ss_sales_price) AS total_revenue,
        COUNT(*) AS num_transactions,
        AVG(sales.ss_quantity * sales.ss_sales_price) AS avg_purchase,
        RANK() OVER (ORDER BY SUM(sales.ss_quantity * sales.ss_sales_price) DESC) AS revenue_rank
    FROM base_catalog.base_db.store_sales sales
    INNER JOIN base_catalog.base_db.customer cust
        ON sales.ss_customer_sk = cust.c_customer_sk
    WHERE cust.c_birth_country = 'UNITED STATES'
        AND cust.c_preferred_cust_flag = 'Y'
    GROUP BY cust.c_customer_id
) ranked
WHERE revenue_rank <= 100;

Tier 3 MV: Stores the exact ranked output of the query (exact-match path).

This tier exercises the exact-match rewrite path: the rewriter canonicalizes the MV body and matches it against the query’s logical plan.

Rewritten plan:

Sort revenue_rank ASC
+- BatchScan customer_tier_3 <- reads around 100 stored rows

Plan 4: Rewritten plan (Tier 3). Reads around 100 stored rows.

The trade-off

The three tiers trade per-query speedup against reuse and storage. In our testing on TPC-DS 3 TB, we observed the following:

MV design Pre-computed Reuse Per-query speedup MV size
Baseline (no MV) nothing n/a 1x n/a
Tier 1: store_sales agg by customer surrogate key aggregate of all sales per customer broadest: any per-customer aggregation ~5x faster 0.07% of store_sales for TPC-DS 3 TB
Tier 2: store_sales x customer agg, one filter pre-applied join + aggregate, preferred customers only medium: any country filter, preferred customers ~10x faster 0.04% of store_sales for TPC-DS 3 TB
Tier 3: entire query body verbatim (exact-match) exact ranked output of this query narrowest: only this exact query shape 20x+ faster negligible (only 100 rows)

Performance measured on TPC-DS 3 TB. Speedup is the ratio of baseline execution time to MV-accelerated execution time. Results might vary based on data characteristics, cluster size, and query complexity.

In addition, MVs incur additional cost. Each one runs a query against your source tables once and stores the result. The more pre-computation it does (joining more tables, applying more filters), the more time it takes.

The following chart plots per-query speedup and creation time for the three tiers in our testing on TPC-DS 3 TB. Per-query speedup rises steadily, from about 5x at Tier 1 to over 20x at Tier 3. Creation time doesn’t follow the same pattern: it peaks at Tier 2. Tier 2 pre-joins and aggregates all preferred customers across every country, so it materializes the most data work. Tier 3 applies both filters, so it processes far fewer rows and costs less to create.

Chart comparing three materialized view designs. In our testing with TPC-DS 3 TB, we observed per-query speedup rises from about 5x (Tier 1) to over 20x (Tier 3), while creation time peaks at Tier 2, which materializes the most data work. Stacked bars show creation time split into catalog setup, data work, and commit.

Figure 1: Per-query speedup and creation time across the three materialized view tiers, measured on TPC-DS 3 TB

Start by identifying one expensive query that runs repeatedly with stable filters. It is likely a good candidate for an exact-match MV.

Validating automatic query rewrite

To confirm that your query benefited from automatic rewrite:

  1. Query plan inspection: Check the query’s optimized logical plan or physical plan for a leaf scan node referencing the MV (for example, BatchScan mv_catalog.mv_db.your_mv_name). If the MV appears as a scan source, rewrite succeeded.
  2. Log confirmation (Amazon EMR 7.14.0+): Look for INFO-level log entries such as AQMV outcome: rewritten=true, mvs=[mv_name], duration=12ms.
  3. No-rewrite diagnostics (Amazon EMR 7.14.0+): If rewrite didn’t occur, check the MVRewriteMetricsEvent in the Apache Spark Event Log for the specific reason the optimizer skipped the MV.

If you have set spark.sql.optimizer.answerQueriesWithMVs.enabled=true but your query still runs against the base tables, check the following common causes:

  1. Write commands block rewrite by default. INSERT and MERGE statements don’t trigger rewrite. Set spark.sql.optimizer.answerQueriesWithMVs.commandBlockingEnabled=false to turn on rewrite within write command subqueries.
  2. The MV is stale. Rewrite skips the MV when one or more source tables have changed since its last refresh. Wait for the next scheduled refresh, or force an immediate refresh with REFRESH MATERIALIZED VIEW <mv_name>.
  3. Heuristic candidate filtering. The optimizer uses heuristic checks to narrow the set of MV candidates before attempting a full match. In some cases, an MV that could benefit the query might be filtered out early by these heuristics.
  4. Spark version mismatch (Amazon EMR 7.13.0+). Automatic query rewrite skips MVs whose stored IMV_sparkVersion does not match the cluster’s current Apache Spark version. To bypass this check, set spark.sql.materializedView.sparkVersionCompatibilityCheck.enabled=false.
  5. MV metadata cache not loaded. The metadata cache loads lazily during optimization of the first rewritable query in a Spark session. If your critical query fires before the cache is warm, the MV will not be available. Run a small warm-up query (for example, SELECT 1 FROM <some_iceberg_table>) at session start to pay this cost off the critical path.
  6. MV metadata cache memory limit reached. If the cache was disabled or stopped loading MVs because of reaching its memory limit, increase spark.driver.memory.
  7. Too many tables in configured catalogs. If there are many tables or MVs in the configured catalogs, the cache might not finish loading before your query starts. Place MVs in a dedicated catalog, add it to spark.sql.materializedViews.additionalCatalogs, and set spark.sql.materializedViews.scanCurrentCatalog=false to skip scanning the current catalog.
  8. Parquet base tables have additional limitations and configuration requirements. For automatic query rewrite with Parquet base tables, set spark.sql.materializedView.v1SourceTables.enabled=true and spark.sql.materializedView.v1ETagVersioning.enabled=true. Without ETag versioning, Spark can’t determine a usable source-table version and skips the MV. Partitioned Parquet base tables are also subject to additional validation limits.

Performance considerations

Turning on automatic query rewrite has overhead: it introduces trade-offs that might affect some queries negatively:

  1. Optimization overhead. Enabling rewrite adds processing time during query optimization as the optimizer evaluates MV candidates against the query plan. This overhead applies to every query in the session, including those that ultimately don’t match any MV.
  2. Reduced task parallelism. Reading from an MV instead of the original base table might produce fewer tasks or introduce data skew, depending on the MV’s data layout. This reduces parallelism compared to a direct scan of the larger, more evenly distributed source table.

Conclusion

In this post, we showed how automatic query rewrite can accelerate your existing Apache Spark workloads. It uses Apache Iceberg materialized views in the AWS Glue Data Catalog, without changing a single line of SQL. By storing precomputed results as managed Apache Iceberg tables, the AWS Glue Data Catalog lets the Apache Spark optimizer transparently substitute matching query plans. You get the performance benefit of pre-aggregation without the application-level rewiring. BI dashboards, ISV-generated reports, and legacy pipelines all benefit the moment a matching MV exists.

We walked through three MV designs for the same analytical query, each striking a different balance between per-query speedup, storage footprint, and reuse across your workload. As the trade-off table shows, our testing found that a narrow, exact-match MV delivered 20x+ acceleration for a single query shape. A broader pre-aggregate served an entire family of queries at a more modest ~5x gain. The right choice depends on how many queries share the same join-and-aggregate pattern and how frequently your source data changes.

To get started:

  1. Launch an Amazon EMR 7.12.0+ cluster or an AWS Glue 5.1+ job.
  2. Create an MV over your most expensive repeating query using CREATE MATERIALIZED VIEW in the AWS Glue Data Catalog.
  3. Turn on automatic query rewrite by setting spark.sql.optimizer.answerQueriesWithMVs.enabled=true in your Spark session configuration.
  4. Verify the rewrite by inspecting the optimized query plan for an MV scan node, or by checking INFO-level logs on Amazon EMR 7.14.0+.

Queries with multi-table joins, heavy aggregations, or window functions over large fact tables are strong initial candidates. Start with one high-cost, frequently executed query. Validate the speedup, then expand to broader MVs as you identify shared patterns across your workload.

Special thanks to everyone who contributed to the automatic query rewrite feature and this blog: Andre Hernich, Leon Lin, Yiyang Chen, Geeta Krishna Panda, Ashok Chintalapati, Muhammad Malik, Rishabh Bhatia, and Giovanni Fumarola.

References

For more detail, see the following resources:


About the authors

Yuzhou Sun

Yuzhou Sun

Yuzhou is a software development engineer for Open Data Analytics Engines at Amazon Web Services.

Srishti Mittal

Srishti Mittal

Srishti is a product manager for Open Data Analytics Engines at Amazon Web Services.

Kinshuk Pahare

Kinshuk Pahare

Kinshuk serves as Head of Product for Analytics Engines at AWS, where he leads the product teams responsible for Amazon Redshift, AWS Glue, Amazon EMR, and Amazon Athena. With over six years at AWS, he brings deep expertise in building and scaling cloud-native analytics platforms that help organizations unlock the value of their data at any scale.

Henry Laih

Henry Laih

Henry is a software development engineer for Open Data Analytics Engines at Amazon Web Services.

Srikanth Kandula

Srikanth Kandula

Srikanth is an engineer who works in analytics and distributed systems at Amazon Web Services.

Shahryar Baki

Shahryar Baki

Shahryar is a software development engineer for Open Data Analytics Engines at Amazon Web Services.

Every team is a data team — bring Amazon Redshift analytics to ChatGPT Work

Post Syndicated from Naresh Chainani original https://aws.amazon.com/blogs/big-data/every-team-is-a-data-team-bring-amazon-redshift-analytics-to-chatgpt-work/

Today, AWS is announcing the AWS Data Analytics plugin for the new Data agent in ChatGPT Work. The plugin helps teams across an organization ask questions in natural language, analyze governed data across their Amazon Redshift data warehouse and data lakes, and create shareable dashboards. All this happens from a conversation in ChatGPT Work.

Tens of thousands of customers choose Amazon Redshift every day to run their most demanding workloads, because it delivers analytics at scale with industry-leading price performance. They love how Amazon Redshift provides access to their data warehouses and data lakes together in one place. Teams can combine curated business data with the broader operational, historical, and third-party data stored in open formats like Apache Iceberg in their data lakes. This gives them a complete picture to make business-critical decisions across their data.

Customers have asked AWS for a way to put that trusted data in the hands of more of their people. That means not only the analysts and engineers who write SQL, but also the sales leaders, operations managers, and finance teams who depend on the results. A sales leader wants to know how the customer pipeline has changed this quarter. An operations manager wants to understand why fulfillment times changed over the past month. That’s why we built the AWS Data Analytics plugin, bringing the power of Amazon Redshift and AWS analytics to ChatGPT Work.

“Business teams can make decisions faster when they can source their own analytics and build the dashboards they need. Our work with AWS gives more people that ability, helping them understand changes in performance and decide where to focus. The AWS Data Analytics plugin connects Amazon Redshift to the Data agent in ChatGPT Work, so employees can analyze trusted company data simply by asking, with their organization’s existing access controls in place.”

— Arpan Shah, General Manager, Technology at OpenAI

The new plugin helps shorten the path from question to decision for everyone. Using the Data agent in ChatGPT Work, employees can explore the data they are authorized to access in Amazon Redshift by asking questions in everyday language. They can then refine the analysis, investigate changes, and turn the results into a dashboard without leaving ChatGPT Work. The plugin works with both Amazon Redshift provisioned clusters and Serverless workgroups. Customers can integrate it into their existing multi-cluster or multi-workgroup environments and benefit from the cost and security controls they’ve already set up.

Consider Maya, a business analyst supporting a revenue operations team. She wants to understand the revenue performance across various segments and regions.

Maya starts by loading the AWS Data Analytics plugin in ChatGPT Work, and then asking:

What are the revenue metrics for the past 30 days compared to the previous 30-day period?

ChatGPT Work conversation asking for revenue metrics over the past 30 days compared to the previous 30-day period

Figure 1: Asking for revenue metrics in ChatGPT Work using the AWS Data Analytics plugin

The plugin translates her question into SQL, or a sequence of queries if needed, and runs them against the relevant data in Amazon Redshift. It returns key revenue performance metrics based on the same curated revenue data that her analytics team maintains.

Table of revenue performance metrics the plugin returned from Amazon Redshift

Figure 2: Revenue performance metrics returned from Amazon Redshift

Maya notices that gross margin is declining and asks a follow-up question:

What is my revenue breakdown by product category and region for the past 90 days?

Revenue results segmented by product category and region for the past 90 days in ChatGPT Work

Figure 3: Revenue breakdown by product category and region for the past 90 days

The plugin carries the context forward, segments the results, and helps Maya understand each segment’s performance for the past 90 days. She can inspect the analysis and ask additional questions to drill down even further to understand why certain regions are lagging or why certain segments are outperforming others.

This conversational workflow doesn’t replace the data models, metric definitions, or governance practices that the analytics team has established. It helps more employees use that data directly, giving analysts more time for high-value work.

The AWS Data Analytics plugin connects ChatGPT Work to Amazon Redshift and uses the context of the connected analytics environment to help answer questions with the Data agent. During a conversation, it can:

  • Discover the schemas, tables, columns, and data types available to the user.
  • Translate a natural-language question into Amazon Redshift SQL.
  • Run the query against the customer’s Amazon Redshift environment.
  • Present the results in a table or concise explanation.
  • Use follow-up questions to filter, compare, or drill into the results.
  • Turn an analysis into an interactive dashboard that teams can share and explore.

Because the analysis runs against the customer’s existing data, teams can continue to use the curated datasets and business definitions they already maintain in Amazon Redshift. Customers whose Amazon Redshift environments query data in both a warehouse and a data lake can also make that data available through the governed datasets exposed to the plugin. The AWS Data Analytics plugin also supports our broader AWS data and analytics services. This includes the ability to work with AWS Glue Data Catalog, Amazon S3 Tables (a capability of Amazon Simple Storage Service (Amazon S3)), Amazon Athena, and vector search on AWS.

Natural-language analytics requires more than passing a prompt to a database. The agent needs to understand SQL specific to Amazon Redshift, discover metadata, choose the right tables and columns, and construct queries that follow service best practices. The plugin was built using Amazon Redshift skills from the Agent Toolkit for AWS. These skills provide tested procedures and service-specific guidance that agents can use when working with Amazon Redshift.

To get started, install the AWS Data Analytics plugin in ChatGPT Work to connect it to Amazon Redshift. Give your teams a conversational path to governed insights across your data warehouse and data lake today.

To learn more, see the following resources:


About the author

Naresh Chainani

Naresh Chainani

Naresh is a Director of Engineering at AWS, where he leads Amazon Redshift, one of the world’s most widely used cloud data warehouses. With over 20 years of experience across IBM and AWS, he is a recognized leader in high-performance database systems, holding more than a dozen patents and numerous publications at top venues including SIGMOD and VLDB. Naresh is passionate about advancing the state of the art in analytics and developing the next generation of engineering talent.

Forever Young. Да поговорим за възхода на „Алтернатива за Германия“

Post Syndicated from Светла Енчева original https://www.toest.bg/forever-young-da-pogovorim-za-vuzhoda-na-alternativa-za-germaniya/

Forever Young. Да поговорим за възхода на „Алтернатива за Германия“

В навечерието на изборите в германската федерална провинция Саксония-Анхалт на 6 септември 2026 г., спечелени от крайнодясната партия „Алтернатива за Германия“ (АзГ), един 42-годишен хит преживя ренесанс. Става въпрос за Forever Young на немската група Alphaville. Няма как да не сте чували тази песен, ако имате съзнателни спомени от 80-те, а е вероятно да ви говори нещо, дори да сте родени по-късно.

Макар привидно да възпява мечтата за вечна младост, песента всъщност е политическа – в нея става дума за превъоръжаването по време на Студената война:

Надяваме се на най-доброто,
но очакваме най-лошото,
ще пуснеш ли бомбата, или не?

Иронично от днешна гледна точка, в песента е цензуриран пасаж, в който става дума за фашизма.

Forever Young се превърна в своеобразен химн на съпротивата срещу АзГ „благодарение“ на недалновидността на организаторите на Фестивала на щастието (Glücksgefühle-Festival) в град Хокенхайм, Баден-Вюртемберг. Те оттеглиха поканата за участие към Alphaville с аргумента, че не искат политически послания на фестивала, а вокалът на групата Мариан Голд е известен с критичното си отношение към АзГ.

В Германия обаче правото на изразяване на демократични ценности се цени високо и за разлика от България, редовно се практикува. Логично, последва скандал. Организаторите се извиниха и „оттеглиха оттеглянето“ на поканата, но Alphaville вече не искаха да се включат.

За сметка на това редица участници изпълниха от сцената на фестивала Forever Young в знак на протест, като не пропуснаха да подчертаят важността на демокрацията. И/или да наругаят АзГ, както направи например мъжки хор от Кьолн.

Какво се случи в Саксония-Анхалт?

Хем беше очаквано, хем настана масова изненада. Така може да се обобщят реакциите по отношение на изборите в Саксония-Анхалт. АзГ получи подкрепата на близо 44% от гласувалите и едва три места я делят от пълно мнозинство в местния парламент. Избирателната активност беше най-високата в тази източногерманска провинция от 1990 г., тоест откакто в нея се провеждат свободни избори – 77,8%. Саксония-Анхалт е провинция с едва около два милиона души население, но отзвукът от резултатите е огромен.

Възходът на крайната десница в Германия – как и защо?

Тайна сбирка на дяснорадикални лидери, на която се е обсъждала „ремиграция“, стана причината за многохилядни протести в Германия. Защо дясната реторика и формации като „Алтернатива за Германия“ стават все по-силни? От Марина Лякова.

Какви са причините за този отзвук? 

За първи път АзГ е толкова близо до вземането на властта, а участието ѝ в управлението би представлявало прекрачване на табу. Победата на крайнодясната формация, макар и в една малка провинция, е в контекста не само на повишаването на подкрепата за партията в цяла Германия. Тя става на фона на възхода на крайнодесните на други места в Европа – примерно, на Марин Льо Пен във Франция. Без да пропускаме немислимата до неотдавна симбиоза между Русия и доскорошния „лидер на демократичния свят“, където по време на втория мандат на Тръмп наблюдаваме антидемократичен завой. И Москва, и Вашингтон изразяват последователна подкрепа за АзГ, а Европа остава все по-самотна в опита си да удържа демократичните ценности.

На всичко отгоре в АзГ съществуват различни фракции, а тази в Саксония-Анхалт е сред най-радикалните от тях. Германските служби квалифицират местната структура на партията като екстремистка организация. А лидера ѝ Улрих Зигмунд вестник Spiegel нарича „най-опасния мъж в Германия“ и пише, че е предводител на дясноекстремистка мрежа, предизвикваща страх дори у ръководството на партията. Същевременно обаче Зигмунд има излъчването на симпатяга, който е близо до хората, и е популярен в социалните мрежи.

А източногерманците, които се чувстват изоставени от системните играчи, като Социалдемократическата партия (СДП) и Християндемократическия съюз (ХДС), имат нужда точно от това – някой да ги чува и да облича неудовлетвореността им в политически послания.

Част от предизборните обещания на АзГ в Саксония-Анхалт са такива, че демократично настроените германци (а и европейци) ги побиват тръпки – например децата с увреждания да не учат с останалите, а да бъдат изпратени в специални училища, нещо като т.нар. училища за бавноразвиващи се, както се наричаха тези учебни заведения по времето на социализма. За децата бежанци също се предвижда да учат отделно от здравите и „нормални“ германчета. За да си знаят, че са в Германия само временно.

Домовете за деца – между институционалното наследство и човешкото лице на грижата

Социалистическото наследство на домовете на деца тегне и днес, когато тези институции са вече уж закрити. Евгения Тонева разказва защо дехуманизиращите нагласи, порядки и стигмата продължават да се възпроизвеждат.

В предизборната програма за ЛГБТИ+ хората се говори като за „отклонения“, които не могат да се възпроизвеждат. Предвижда се изгонване на голяма част от хората с мигрантски произход. А нуждата от работна ръка би се очаквало да се задоволи не с миграция, а с насърчаване на раждаемостта с финансови стимули – мярка с меко казано, спорен ефект.

Дали АзГ ще управлява в Саксония-Анхалт, зависи от това как ще се развият отношенията ѝ с малката партия „Съюз Сара Вагенкнехт“ (ССВ),

която спечели пет места в местния парламент. ССВ е партия, кръстена на председателката ѝ Сара Вагенкнехт и отцепила се от друга партия – „Левицата“. „Левицата“ пък е създадена през 2007 г. от отцепници от СДП и от Партията на социалистическото единство от времето на социализма, тоест БКП-то на ГДР. Въпреки че е против НАТО, критична към ЕС и толерантна към Русия, „Левицата“ застава зад социалнолиберални ценности – човешки права, защита от дискриминация на чужденци, ЛГБТИ+ хора и пр., равенство на половете и т.н.

Партия като „Левицата“ в България нямаме, но Сара Вагенкнехт можем да оприличим на Корнелия Нинова, както и на остатъците от БСП и всичките ѝ производни, включително „Прогресивна България“. „Лявото“ на Вагенкнехт е близо до крайнодясното на АзГ, както Нинова и Костадин Костадинов са си лика-прилика. ССВ е антиимигрантска партия, която недолюбва човешките права и харесва Путин, и затова стана първата партия, готова да подаде ръка на АзГ за съвместно управление. Друг е въпросът дали Улрих Зигмунд ще е склонен на компромиси, каквито изискват коалициите, или ще се опита да предизвика нови избори с цел да вземе цялата власт. Останалите варианти биха били нестабилни опити за правителство на малцинството.

Как е възможно хомосексуална жена да е начело на „Алтернатива за Германия“

В случай че някой се чуди как точно се връзва личността на Алис Вайдел с посоката и позициите на партията ѝ, Светла Енчева дава някои много интересни отговори. И не, „Алтернатива за Германия“ не е германското „Възраждане“, защото радикализацията там върви по съвсем друга линия.

АзГ и Източна Германия

Но да се върнем към историята с Alphaville. Отношението на организаторите на Фестивала на щастието предизвика такова възмущение не на последно място заради културата на паметта, която се възпитава в Западна Германия след Втората световна война. Тя включва съзнание за вината и отговорността за националсоциализма и убеждението, че той не трябва да се допуска никога повече и че колкото по-голяма е опасността, толкова повече и от всяка възможна трибуна трябва да се посочва тя.

ГДР обаче не е минала през подобен процес. Част от идеологията на социалистическите страни е, че те са от „правилната страна на историята“. Осъзнаване и преработване на вина не са нужни – „другите“ са фашисти, „ние“ сме добрите. Ето защо много източногерманци имат чувството, че след Обединението им се натрапва чужда вина. Това е една от причините АзГ, която предлага скъсване с виновното отношение към историята, да вирее по-успешно в източните федерални провинции. Същевременно липсата на имунна система по отношение на националсоциализма е благодатна почва за възраждането му под една или друга форма.

Усещане за онеправданост

Периодът между падането на Берлинската стена и Обединението на Германия е еуфоричен за гражданите на ГДР – те получават свободата да пътуват, да се изразяват, изобщо – да бъдат част от доскоро забранен за тях свят. Освен това Западна Германия е привлекателна и с по-добре развитата си икономика.

Ала когато обединената държава става реалност, еуфорията постепенно отстъпва място на разочарованието. Много хора мигрират в западните провинции, а източните се обезлюдяват. Производството от времето на ГДР се прекратява, а на негово място идват, ако изобщо дойдат, западногермански концерни. Известните от времето на социализма автомобили „Трабант“ и „Вартбург“ например остават в миналото, а в някогашния завод на „Вартбург“ в Айзенах днес се произвежда „Опел“. Към гордостите на ГДР, които вече не се изработват, принадлежат и мотопедите Simson, какъвто демонстративно кара Улрих Зигмунд.

Но не е само индустрията – за източногерманците много от нормите, ценностите и дори немалка част от езика на държавата, от която стават част, са чужди. Уж всички в страната говорят немски, но навлизат нови думи за доскоро несъществували реалности, а езикът, описващ бившата социалистическа реалност, е непонятен за германците на Запад.

Така желаното някога обединение се превръща в усещане за колонизираност – налагане на чужд свят и обезценяване на собственото минало заедно с постиженията и уникалността на всекидневието му.

Между 1995 г. и 2019 г. федералното правителство на Германия и западните провинции отделят общо 238 млрд. евро за източните провинции чрез програма, наречена „Пакт за солидарност“. Първият пакт е до 2004 г. и основната му цел е подобряване на инфраструктурата на територията на бившата ГДР. Вторият е предназначен за компенсиране на трудностите, произтичащи от разделянето на Германия, и за ускоряване на икономическото догонване на западната част от страната.

Всички тези средства обаче не допринасят за премахването на убеждението на голяма част от жителите на източните провинции, че са третирани като втора категория германци. На този фон АзГ обещава да върне достойнството им и предлага визия за миналото и бъдещето на Германия, в която те се припознават. Визия, в която се акцентира върху гордостта и превъзходството, а не върху срама и вината.

Отношение към миграцията

Отрицателното отношение към миграцията, особено от мюсюлмански страни, е основната характеристика на АзГ. Затова на пръв поглед изглежда парадоксално, че партията е толкова популярна точно в източните провинции на Германия. В тях (без да броим столицата Берлин) делът на чужденците и на хората с миграционен произход е значително по-нисък, отколкото в западните. С миграционен произход (това включва чужденци, също хора, получили германско гражданство, както и такива, които може да са родени в Германия, но поне единият от родителите им е от чужбина) е 34,4% от населението в западните провинции, а в източните делът му е почти три пъти по-нисък – 12,1%. Що се отнася конкретно до чужденците (които нямат германско гражданство), в западните провинции делът им е 15,7%, а в източните (без Берлин) – 7,6%, тоест около два пъти по-нисък.

Не е задължително обаче отношението към миграцията да съвпада с реалното ѝ присъствие. В България преди 11 години например, когато „бремето на бежанската вълна“ от Сирия се усещаше като „непосилно“, търсещите закрила бяха малко над 26 000, като по-голямата част от тях не останаха в страната. Но популистки партии насаждаха омраза към бежанците, а хората се страхуваха от тях, понеже не ги познаваха.

Подобна е ситуацията и в източните германски провинции – колкото по-рядко местните хора срещат чужденци, толкова по-чужди са те за тях и толкова по-голяма е вероятността да ги възприемат като опасност и да ги нападат с идеята, че се защитават.

Конкретно в Саксония-Анхалт най-много са чужденците от Украйна (около 36 000) следвани от сирийците (малко над 29 000) и поляците (близо 15 000). Като цяло преобладават чужденци от Източна Европа, включително около 4700 българи и още толкова руснаци. Но АзГ е и против украинските бежанци, а ако плановете на партията за „ремиграция“ се осъществят, е доста вероятно от тях да пострадат и българи.

Случаят Джем (Йоздемир). Защо „Зелените“ победиха в Баден-Вюртемберг

Победата на „Зелените“ изглежда като статистическа грешка – 0,5 пункта пред ХДС. Но е важна, защото зад този резултат стои човек. Джем Йоздемир – син на турски гастарбайтери, „шваба“, както сам се нарича, и попкултурна фигура – се оказа факторът, който преобърна изборите. Как – от Светла Енчева.

Упражнения по демократично безсилие

Докато АзГ в Германия и други антидемократични популисти в Европа набират скорост, европейските институции и партиите, отстояващи принципите на либералната демокрация, реагират със заучена безпомощност.

Първият симптом на тази заучена безпомощност е подчинението пред популистите и убеждението, че ако заприличаме поне малко на тях, ще си запазим демокрацията. Може би сме станали твърде либерални, твърде толерантни, прекалили сме и затова вече не гласуват за нас. Настоящият канцлер на Германия Фридрих Мерц дойде на власт с обещанието за по-твърда ръка, която според него би трябвало да свали подкрепата за АзГ наполовина. Резултатите от изборите в Саксония-Анхалт обаче показват обратното: преполовена е подкрепата за ХДС – партията на Мерц.

Вторият симптом е подценяването и обвиняването на избирателите на популистки партии. Много от тях нямат екстремистки убеждения, но се чувстват изоставени и неразбрани. И когато някой демонстрира, че е на тяхна страна и прехвърля отговорността за неуспехите им върху „другите“, е лесно да му повярват. Когато им се каже „тези са лоши, не гласувайте за тях“, това само ги ожесточава.

Електоралната енигма – защо българите в чужбина гласуват за „Възраждане“

За пореден път след поредните избори се чудим защо българите в чужбина – тази тъй митологизирана група хора – гласуват за „Възраждане“. Марина Лякова прави анализ кои са българите в чужбина, които реално гласуват, и когато го правят, защо вотът им изглежда тъкмо по този начин.

Третият симптом, свързан с предишните два, е, че в настоящия период на тотална несигурност – геополитическа, икономическа, екологична и пр. – демократичният свят като че ли няма вдъхновяващо послание, с което да противостои на популизма. Популистката вълна разполага с конспиративни теории, дезинформационни кампании, инфлуенсъри… Чудовището, родено от симбиозата между ултраконсервативни фундаменталисти и наследството на тоталитарните разузнавателни и репресивни служби, притежава не само умения да влияе, а и много пари да осъществява целите си. И лесно ги постига, защото насреща си има не здрава демократична имунна система, а мрънкане и тюхкане.

Междувременно поколението, което помни Втората световна война, си отива. А с него и демократичният рефлекс „никога повече“. Днес мечтата за бъдещето е мечта за едно идеализирано минало, в което има сигурност и перспективи за всички; в което ние сме си ние – без чужденци, а малцинствата и различните си знаят мястото. Минало, което e forever young.

Водещо изображение: „Синьо небе над Магдебург“, както пише АзГ в страницата си във Facebook броени часове преди излизането на последните изборни резултати. На снимката се вижда и Улрих Зигмунд – лидерът на АзГ в Саксония-Анхалт. Източник: Facebook / AfD

Security updates for Thursday

Post Syndicated from jzb original https://lwn.net/Articles/1093566/

Security updates have been issued by AlmaLinux (389-ds-base, ansible-core, buildah, expat, glib2, gpsd, gpsd-minimal, gzip, kernel, kernel-rt, opentelemetry-collector, osbuild-composer, perl-DBI, python-lxml, python3.12-lxml, qt5-qtbase, thunderbird, valkey, vim, and xz), Debian (pyasn1), Fedora (darktable, freeipa, freerdp2, gdk-pixbuf2, GitPython, libsoup3, openssl, perl-Net-DNS, rust-ppmd-rust, samba, and valkey), Mageia (ceph, firefox, nss, perl-DBI, thunderbird, and wget), Oracle (389-ds-base, buildah, expat, git-lfs, glib2, glibc, gpsd, gpsd-minimal, grafana-pcp, kernel, libssh, nginx, perl-GD, python3.14-cryptography, redis:7, skopeo, thunderbird, valkey, xmlrpc-c, and xz), Slackware (xz), SUSE (bzip2, cpio, curl, dracut, fuse-overlayfs, golang-github-vpenso-prometheus_slurm_exporter, helm, java-1_8_0-ibm, kbfs, kernel, kernel-devel, libopenslide-devel, libsoup, libssh2_org, libusb-1_0, libvirt, libzypp, zypper, mcphost, multipath-tools, NetworkManager, opensc, openssl-3, perl-Net-DNS, python-aiohttp, python-Authlib, python-pip, python-sqlparse, python313-dnspython, python313-idna, rpcbind, sssd, strongswan, systemd, tomcat11, ucode-intel, and wget), and Ubuntu (dotnet8, dotnet10, ffmpeg, flatpak, netty, and perl).

1.1.1.1 now supports post-quantum DNSSEC, all 2,420 bytes of it

Post Syndicated from Sebastiaan Neuteboom original https://blog.cloudflare.com/post-quantum-dnssec-1111/

1.1.1.1 now validates DNSSEC signatures made with ML-DSA-44, a post-quantum signature algorithm standardized by the National Institute of Standards and Technology (NIST). This is a first step toward preparing DNSSEC for a future in which today’s signature algorithms are no longer secure.

Cloudflare plans to achieve full post-quantum security by 2029. Much of the work so far has focused on TLS, but public-key cryptography is used in many other systems, including DNSSEC.

While we began experimenting with post-quantum key agreement in TLS in 2019 and enabled support for all customers in 2022, post-quantum signatures have not yet received comparable testing in DNSSEC. There is also some urgency. Widespread client adoption of post-quantum TLS took years, partly because larger messages exposed assumptions and bugs in existing network software. That experience showed why early large-scale testing matters. We cannot wait until quantum computers become an immediate threat.

The problem is that post-quantum signatures are large. Each ML-DSA-44 signature is 2,420 bytes, exceeding common DNS-over-UDP limits before the response includes anything else. At the same time, zones will need to publish conventional signatures for older resolvers for years, creating a potential downgrade path if not validated correctly. The challenge is carrying these much larger responses reliably, without allowing compatibility with older resolvers to weaken protection for newer ones.

With ML-DSA-44 validation enabled, 1.1.1.1 lets us test both challenges at Internet scale: carrying larger DNS responses and preventing fallback to conventional signatures.

Why post-quantum DNSSEC matters

DNS responses are not authenticated by default. An attacker who can forge a response may be able to redirect users to an address of their choosing. DNSSEC prevents this by signing DNS records. A validating resolver such as 1.1.1.1 follows a chain of signed records from the DNS root to the requested domain, checking that the answer is authentic and has not been modified.

DNSSEC supports multiple signature algorithms, but nearly all of those used today are vulnerable to future quantum computers. RSA and ECDSA rely on mathematical problems that are believed to be infeasible for conventional computers to solve at deployed key sizes. We are preparing for the possibility that in 2030 a sufficiently powerful quantum computer could be built that breaks these keys. An attacker could then recover the corresponding private key and create forged signatures that validators would accept. The attack path is shown below.

Quantum computers capable of carrying out these attacks do not exist today. DNSSEC provides authenticity rather than confidentiality, so it is not subject to “harvest now, decrypt later” attacks. The reason to begin now is that changing DNSSEC requires coordination across authoritative servers, registries, registrars, and validating resolvers. The migration must eventually reach the top of the DNS hierarchy, where a compromised key has the greatest impact. An attacker who recovers a root zone signing key using a quantum computer could forge a validation path to any zone below it: “break once, forge everywhere”. ML-DSA-44 gives that migration a standardized starting point, and supporting it in 1.1.1.1 lets us, and the DNS ecosystem at large, gain operational experience.

Why replacing the algorithm is difficult

DNSSEC was designed to support new algorithms. In principle, supporting ML-DSA-44 means publishing its public key and teaching validators to verify its signatures. In practice, two properties make the transition difficult: the signatures are large, and the old algorithm cannot always be removed safely.

A 2,420-byte signature changes the packet

DNSSEC algorithms commonly used today produce relatively small signatures. ECDSA P-256, for example, produces a 64-byte signature. An ML-DSA-44 signature is 2,420 bytes, almost 38 times larger.

That difference matters because many of the systems that send, carry, and receive DNS messages are sensitive to message size. DNS originally restricted messages sent over UDP to 512 bytes. EDNS(0) later allowed a resolver to advertise the largest UDP response it is willing to accept from a nameserver. Many DNS implementations use a conservative UDP payload limit of 1,232 bytes, chosen to fit within IPv6’s minimum MTU (maximum transmission unit) of 1,280 bytes. More recently, RFC 9715 recommended a maximum of 1,400 bytes for DNS over UDP. An ML-DSA-44 signature exceeds that budget on its own, before accounting for the signed RRset, domain names, DNS headers, and other DNSSEC records. Sending such a response as fragmented UDP is unreliable and should be avoided. Instead, the authoritative server should return a truncated response, prompting the resolver to retry using another transport protocol, usually TCP.

The effect is most visible in DNSKEY responses, which contain the keys a resolver needs to validate the zone. An ML-DSA-44 public key is 1,312 bytes, and the DNSKEY RRset also carries a 2,420-byte signature. ML-DSA-44 cannot fully replace conventional signing algorithms until it is widely supported across the DNS ecosystem, a process likely to take years. Until then, DNSKEY responses may contain both conventional and post-quantum keys and signatures to remain compatible with older validators. Key rollovers can add still more keys, making these responses larger again.

Handling DNS over transports other than UDP is not itself unusual. Cloudflare Radar shows that around 85% of queries to 1.1.1.1 arrive over UDP. The platform behind 1.1.1.1, Big Pineapple, also powers other DNS services, including Gateway DNS. Across all services handled by Big Pineapple, around 60% of queries arrive over UDP. The remaining 40% use transports such as TCP, DNS over TLS (DoT), and DNS over HTTPS (DoH).

Those figures describe how queries reach Cloudflare’s resolver services, not how 1.1.1.1 communicates with authoritative servers. Large ML-DSA-44 responses can still cause additional TCP retries on that side, but handling DNS over transports other than UDP is already a normal part of operating 1.1.1.1 at scale.

Supporting two algorithms introduces a downgrade risk

Replacing an existing DNSSEC algorithm cannot happen all at once. If a zone publishes only ML-DSA-44, resolvers that do not support it cannot validate the zone. The practical migration path is therefore to publish conventional and post-quantum keys and signatures together.

That preserves compatibility, but it does not provide post-quantum security by itself. RFC 6840 specifies that “validators SHOULD accept any single valid path.” This rule lets validators use whichever published algorithm they support.

Once a conventional algorithm such as ECDSA is no longer secure, however, the same behavior creates a downgrade path. An attacker could forge an ECDSA-only answer that a resolver accepts despite supporting ML-DSA-44, as illustrated below.

Preventing this downgrade requires an authenticated signal that a zone should be validated with ML-DSA-44. 1.1.1.1 uses DS records published by the parent zone for this purpose. If the authenticated DS RRset contains a record for a supported post-quantum algorithm, the signal is present.

1.1.1.1 then deliberately applies a more restrictive local validation policy. It requires at least one valid post-quantum validation path; a conventional path is no longer sufficient. If no ML-DSA-44 path validates, validation fails. This is not (yet) normal DNSSEC validation behavior, but RFC 4035 allows local resolver policy to determine whether additional signatures must be checked and how conflicting results are handled.

Conventional signatures can remain available for older resolvers without allowing post-quantum-capable resolvers to fall back to them. The downgrade signal is only post-quantum secure if ML-DSA-44 deployment and downgrade protection extend from the trust anchor through every delegation. Rotating the zone key more frequently does not solve the problem: an attacker can target a vulnerable key anywhere higher in the chain and forge every delegation below it.

The road to post-quantum DNSSEC

Adding a post-quantum algorithm to DNSSEC requires more than standardizing the cryptography. It needs implementations in cryptographic libraries, an IANA-assigned DNSSEC algorithm number, support from authoritative servers and validating resolvers, and adoption throughout the DNS delegation chain. ML-DSA-44 now has the initial prerequisites for deployment. NIST has standardized it, and common cryptographic libraries implement it. Its use in DNSSEC is described in the ML-DSA for DNSSEC Internet-Draft, and IANA recently assigned it DNSSEC algorithm number 18.

Adding ML-DSA-44 validation to resolvers is one of the first deployment steps, but it does not create a complete post-quantum chain of trust. Authoritative servers must sign zones with ML-DSA-44, registrars must accept and submit the corresponding DS records, and registries must publish them in parent zones.

This adoption must extend through every parent zone to the DNS root. The root must adopt ML-DSA-44, and its post-quantum key must become a trust anchor for validating resolvers. Any level without post-quantum protection remains a downgrade point.

There is little value in signing a zone with ML-DSA-44 if no resolver validates its signatures. Enabling ML-DSA-44 validation by default on 1.1.1.1 is therefore an important early step. It lets us measure the operational cost of signature verification, additional bandwidth, and increased TCP use between resolvers and authoritative servers.

As with previous migrations, we will also test real-world deployability using background probes on a small fraction of Cloudflare Challenge Pages. These probes will test whether clients can resolve and reach an ML-DSA-44-signed test domain across real networks. We invite other DNS operators and implementers to begin testing ML-DSA-44 at scale. Together, these measurements will show what adjustments are needed as adoption grows.

What this means for you

If you use 1.1.1.1, you do not need to change anything. ML-DSA-44 validation happens automatically when a zone publishes the necessary DNSSEC records, while existing DNSSEC zones continue to validate as before.

This work covers the resolver side of DNS. Our next step is adding ML-DSA-44 signing support to Cloudflare Authoritative DNS and corresponding DS record support to Cloudflare Registrar, which will be available to all customers for free. That will let us test the complete path, from generating signatures and publishing DNSKEY records to transporting and validating them through 1.1.1.1.

Want to see post-quantum DNSSEC in action… all 2,420 bytes of it? Query our dnstest.dev zone using 1.1.1.1:

You can also use Is your DNS resolver post-quantum ready? to test your current resolver. The community is tracking ML-DSA-44 software support on GitHub.

Вътрешни езикови правила за външна употреба (на ваш риск)

Post Syndicated from original https://www.toest.bg/vutreshni-ezikovi-pravila-za-vunshna-upotreba-na-vash-risk/

Вътрешни езикови правила за външна употреба (на ваш риск)

Редовните читатели на „Тоест“, вярвам, са забелязали, че се стараем да поднасяме не само съдържателни, но и езиково издържани статии. Всеки публикуван материал, след като е бил написан от автора, е минал през ума и очите (а понякога и през сърцето) на поне две инстанции – редактор(ка) и моя милост, коректор(ка). В медията зорко следим текстовете да са съобразени с книжовноезиковите норми. Имаме обаче и някои разминавания, които сме уговорили в нашите Вътрешни правила за стил, граматика, правопис и пунктуация.

Стандарти, кодекси, наръчници

Надали е случайно, че световноизвестни медии и информационни агенции като The Washington Post, The Guardian, Der Spiegel, BBC, Reuters имат редакционни/етични кодекси, в които са заложени основни журналистически стандарти за неутралност, проверка на фактите, етично отношение и т.н. Свой редакционен кодекс има и „Тоест“. С прокламирането на тези стандарти – и с придържането към тях, разбира се – медиите се ангажират да бъдат лоялни към читателите, да им предоставят обективна и достоверна информация, но същевременно улесняват работата в самата редакция, предпазват се от съдебни дела и т.н.

Някои медии си изготвят и собствени езикови правила, скрепени в специални наръчници. Сред най-известните примери са Libro de estilo¹ на испанския El País и Manual of Style and Usage на американския The New York Times, които съдържат стотици страници. С течение на времето тези справочници са станали авторитетни и служат като ръководство за добър стил на много пишещи хора.

Българските медии като че ли са плахи в това отношение и засега освен „Тоест“ ми е известен само още един сайт – „Нула32“, който е заявил публично своята езикова политика.

Тук също може да се запитаме защо е необходимо да има отделни езикови правила, валидни за дадена медия, особено след като разполагаме с подробната кодификация в БЕРОН. Ето го и отговора в синтезиран вид, даден в наръчника на El País:

Наръчникът по стил не е граматика или речник в общоприетия смисъл. Той е вътрешният правилник на редакцията на определено средство за информация, който се опитва да уеднакви изразни системи и форми, така че медията да добие собствен облик и да улесни задачата на читателя.

И така, две са основните причини или по-скоро цели. По-важна ми се струва втората, защото медиите съществуват, за да са посредници² между събитията и читателите. Затова водещо и за авторите, и за редакторите е старанието информацията да се предава максимално точно, ясно и разбираемо за по-широк кръг хора, за да могат те бързо да възприемат прочетеното³. Основното средство за постигане на тази прагматична цел е езикът. А книжовният език с все нормите и правилата си (нека си сложим ръката на сърцето) е малко или много скован. По-точната дума всъщност е ригиден, защото освен „скован“ означава също „неподатлив или трудно податлив на въздействие“ – и ето го, надявам се, нагледно проявен този стремеж да бъдем разбираеми и за онези хора, които не са срещали чуждата дума.

Бързо, скоростно, моментално

Това е повикът на нашето време. Макар да сме декларирали, че журналистиката в „Тоест“ е бавна, сме наясно, че когато са в интернет, повечето читатели включват поне на четвърта скорост, а в много случаи просто сканират текста.

Едно от нашите правила, съдействащи за по-бързото четене, е, че

собствените имена и заглавията, написани с латиница, са в курсив.

Примери има само няколко абзаца по-горе – „Libro de estilo на испанския El País и Manual of Style and Usage на американския The New York Times“. БЕРОН указва в тези случаи да не се използват кавички, защото чуждата азбука разграничава името или заглавието от останалите думи в изречението. В редакцията обаче смятаме, че не е достатъчно, и с курсива сигнализираме, че това е различен код (латински букви) и оригинално име/заглавие.

Въпреки че слятото, полуслятото и разделното писане създават неоправдано много проблеми в реалната езикова практика, ние се придържаме към официалните правила и се разграничаваме от тях само в някои случаи:

1.  Пишем като две думи изразите отгоре надолу, отляво надясно, оттогава досега и под. Според БЕРОН те се пишат като три или четири думи: от горе надолу, от ляво надясно, от тогава до сега. След като читателят е свикнал със слято написаните отгоре, надолу, отляво, надясно, оттогава и досега, когато ги среща употребени поотделно, той би се запитал – и съвсем основателно – защо пък в други изрази се налага да ги разделяме. И защо веднъж ги делим на три думи, а друг път – на четири. Филологическото обяснение сигурно е, че в съчетанието от ляво надясно имаме начална точка и посока (в пространството), а в от тогава до сега – начална и крайна точка (във времето), но уважаеми колеги, постановили тези изключения, наистина ли и в момента продължавате да смятате, че си струват?

2. Пишем винаги страна членка и държава членка, дори и когато се посочва част от коя организация е тя, например:

Позорно е за страна членка на ЕС да подлага руски дисиденти на такъв зловещ кафкиански административен ад.

Според официалните правила страна членка (респ. държава членка), се пише разделно, но ако се добави пояснение – на ЕС, вече членка на ЕС се третира като обособена част и следва да се огради с тире и запетая или с две тирета: Позорно е за страна – членка на ЕС, да подлага… Отново смятаме, че това е ненужно издребняване, защото в резултат текстът се натоварва с препинателни знаци, които по-скоро спъват читателя, отколкото го улесняват при възприемането на информацията. За мен лично обособяването тук изобщо не е задължително.

3. Пишем разделно сложните съществителни с първа част арт – арт инсталация, арт галерия, арт карта, макар че арт не се употребява самостоятелно в българския език и тези думи следва да се пишат слято. Със сигурност четенето се затруднява, когато втората част започва с гласна: артинсталация, артидея, артогледало, затова сме приели разделното писане.

В статиите, публикувани в „Тоест“, се разграничаваме и от официално приетия начин за писане на числителните редни имена с арабски цифри и букви: 1-ви, 2-ри, 3-ти, 4-ти, но 5-и, 6-и и т.н. Правилото и всъщност обяснението на кодификатора е, че се пишат тези „букви от края на числителното редно, които не съвпадат със съответното числително бройно“. Добре, за пет – пети, шест – шести и т.н. това важи, но в един – първи, две – втори, три – трети и четири – четвърти сякаш имаме повече несъвпадащи букви. Ако се придържаме строго към това правило, изобщо не можем да напишем първи и втори с арабски цифри, а 3-ети и 4-върти следва да са в този вид.

Затова сме решили да пишем числителните редни имена винаги с последната сричка от думата след дефиса: 1-ви, 2-ри, 3-ти, 4-ти, 5-ти, 6-ти и т.н. Факт е, че в езиковата практика това е преобладаващият начин и много хора се изненадват, когато разберат, че в детската градина и в училище са изработвали поздравителни картички за празника на мама с грешен (спрямо официалните правила) надпис: Честит 8-ми март!

Критика приемаме аргументирана (ние също имаме аргументи)

Когато обявяваш, че в практиката си се разграничаваш от някои официални правила и следваш свои, трябва да си подготвен за критика. Получавали сме и ние – например за това, че употребяваме глаголните форми на  в състава на учтивата форма в мъжки или в женски род ед.ч., като се съобразяваме с пола на събеседника. В интервютата в „Тоест“ може да срещнете правил сте, бихте искала вместо кодифицираните правили сте, бихте искали.

Официалното правило се нарушава често, особено в устната реч, и е едно от най-разколебаните в българския книжовен език. Важно е, че се нарушава не от необразовани люде, а от хора, които иначе имат сравнително висока езикова култура, включително от журналисти в устни интервюта. Обяснението е във факта, че правилото е извънсистемно – всички други имена и причастия освен миналото свършено деятелно (правили) се употребяват в мъжки или в женски род: любезен/любезна сте, уведомен/уведомена сте. В нашата медия сме решили да бъдем по-близо до съвременната езикова практика.

Срещали сме хапливи забележки и относно предпочитанието ни на каталунски и каталунец пред каталонски и каталонец. В БЕРОН формите са дублетни и дори само това е достатъчно, за да не се налага да влизаме в обяснителен режим. Все пак, избрали сме да пишем Каталуния, а не Каталония, тъй като е по-близо до оригиналното име: Cataluña – на испански; Catalunya – на каталунски. След като сме казали А, е редно да кажем и Б – каталунец и каталунски, за да сме последователни.

Това, че Христо Стоичков и спортните журналисти са популяризирали преди години тези форми, както отбелязват критикуващите, не означава, че трябва да ги отречем тотално. Как да каже човекът каталонски или каталонци, като е живял седем години в столицата на Catalunya и е чувал името на провинцията точно в тази форма? Езикът не е само на високограмотните (за каквито често се имаме) – той е обществено явление, а книжовната му форма следва да зачита реалните езикови употреби все пак.

Медиите по презумпция трябва да са актуални, да са в крак със събитията, проблемите и промените в обществото. На тази актуалност в плана на съдържанието би трябвало да съответства и актуална езикова форма. Книжовният език по природа е консервативен и крета след говоримия – не можем да му се сърдим толкова, но можем да го подсетим, че е време за някакви промени.

В „Тоест“ уважаваме книжовните норми и се придържаме максимално близо до тях. Сами може да прочетете нашите вътрешни правила и да прецените в каква степен ревизираме официалните. Вкопчването в кодификацията обаче и придържането към нея на всяка цена ни прави сковани, по-точно ригидни.

1 Това е заглавието на наръчника, дадено от El País, но копия от него носят и заглавието Manual de estilo.

2 Думата медия води началото си от латинския език, в който едно от значенията на прилагателното medius e „посредничещ“.

3 Естествено, има медии с по-тясна и/или специализирана аудитория.

4 Правилото е формулирано в Нов правописен речник на българския език. София: БАН, Хейзъл, 2002, с. 115, т. 83.11. В следващото хартиено издание – Официален правописен речник на българския език. София: БАН, Просвета, 2012, както и в БЕРОН то липсва; дадени са само примерите 1-ви, 5-и, 5-ия, 5-ият за употребата на дефиса. Дали пък кодификаторът не е решил, че правилото не е издържано, и затова го е спестил?

Езикът може да е вкусен и извън блюдото – онзи, българският език, на който говорим от малки и на който около 24 май се кълнем в обич. А той в същността си е средство за общуване и за да ни служи добре, непрекъснато се променя. Да го погледнем в неговата динамика и да се опитаме да разберем какво става и защо, кои са движещите механизми и как те са свързани с обществените процеси. И тъй като задачата не е лека, ще го правим постепенно – на порции.

Признанието като самопризнание

Post Syndicated from Дарина Сарелска original https://www.toest.bg/priznanieto-kato-samopriznanie/

Това е признание за всички вас. За българските медии, които предоставят територия за многоликото ни общество и възможности за диалог. 

Признанието като самопризнание

С тези думи Кирил Вълчев обясни защо е приел поканата на Илияна Йотова да се кандидатира за неин вицепрезидент. С което стана поредният в списъка с бивши журналисти, пристанали на моментен политически интерес. Бивш, защото през 2021 г. оглави БТА и така излезе от активната журналистика, която допреди това пак съвместяваше с друга професия – освен водещ на „Седмицата“ по Дарик радио беше и юридически консултант на медията (това само по себе си е особен хибрид, но да не придиряме). 

Иначе в кампанията ще си е напълно настоящ шеф на БТА, макар и в неплатен отпуск. Да, точно така, журналистите от БТА ще отразяват „безпристрастно“ и „равноотдалечено“ кампанията на своя началник, който съвсем реално може да се завърне в кабинета си на „Цариградско шосе“, ако „Дондуков“ се окаже негостоприемен. Но отразяването, разбира се, ще е професионално. Все пак няма да ни е за първи път! Пак така професионално преди две години Петър Волгин изкара една кампания в неплатен отпуск, преди да прескочи от журналист на общественото БНР до народен представител на „Възраждане“ в Европарламента. 

„Няма места.“ Журналистиката след журналистите

Ако се чудите какво стана с медиите в България, този текст ви е напълно достатъчен, за да си дадете отговори на много въпроси. А иначе, вие въпроси може и да си задавате, но в много медии у нас вече няма кой да ги задава – гледайте какво нещо… Защо стана така – от Дарина Сарелска.

От Клара Маринова до Антон Хекимян

От 1990 г. до днес поне една дузина разпознаваеми журналисти от БТА, БНТ, БНР, bTV, TV7, Nova и други национални медии преминават в политиката – като депутати, евродепутати, кметове или кандидати за президент. За същото това време доверието на българските граждани в новините чертае последователен и устойчив спад: според последния доклад на Института „Ройтерс“ то пада до рекордно ниските 21%, което е срив от 5 процентни пункта само за година. С това страната ни се нарежда сред държавите с най-ниско доверие в медиите, два пъти по-ниско спрямо средните стойности в глобален мащаб.

Не твърдя, че има причинно-следствена връзка. Но връзка има. И трябва да сме слепи, за да не видим дебелата не-винаги-червена линия, която разделя обществото на себеобслужващи се елити и пренебрегната и подценена публика. Когато аудиторията види „днес си водещ/директор, утре си кандидат на властта“, „днес интервюираш премиера в поза „уж критичен журналист“, а утре се снимаш с него в предизборен клип“ това размива доверието не само в конкретния човек, а в цялата система. 

Защото журналистиката по дефиниция е срещу властта. Не против конкретна партия, а срещу всяка власт. 

Добрата журналистика винаги е критична, проверяваща и възпираща нагона на властта. Когато водещи медийни лица преминават от другата страна на тази желязна завеса, това девалвира освен техните авторитетни имена – най-ценното им, пак по думите на Вълчев, но и самата идея за журналистиката като критичен агент и обществен контрол. 

И нека не се чудим защо тази година социалните мрежи настигнаха телевизиите като предпочитан източник на новини за българите, а догодина се очаква и да ги задминат. С всички мрачни последствия от това под формата на заливаща ни пропаганда, конспиративни теории, поляризация, радикализация и обикновено Дънинг-Крюгер оглупяване. Последствия, които берем къде с наивна детска изненада, къде с високомерната претенция за интелектуално превъзходство.

Но добре ще е следващия път, като се яви някой Тръмп или местен искащ-да-бъде-важен и получи залпова обществена подкрепа само защото „всички други са маскари“, да спрем за малко, преди да отсъдим. Да не бързаме със заключението „Ето, хората са прости“. И да погледнем дали наистина не се препълни с маскари, и то в редиците на елитите: умните, добре артикулираните, медийно симпатичните емблеми на всякакви кръгове, гилдии и общества, брандирани с признание и статус. Натрупали социален капитал под значката „равноотдалечени от всяка власт“ и скочили скоропостижно в листите на точно всяка власт, която ги пожелае.

Краят на журналистиката

Журналистиката губи не само пари и трафик, а и необходимостта да я има. Алгоритми, нюзинфлуенсъри и политици, които вече говорят директно на публиката, променят правилата на играта. Въпросът вече e не дали медиите са в криза, а дали обществото изобщо още иска журналистика. От Дарина Сарелска.

Първата вълна

Моделът „журналисти, преминали под партиен пагон“ не е нов. И не е само наш. Но у нас се вижда ясно в две вълни: първата – в края на 90-те, когато голямата политическа промяна трябва да се захрани с доверието, инвестирано в разпознаваеми лица и имена от единствените дотогава държавни медии, основно БНТ; втората – след 2005 г., когато частните телевизии стават стартова площадка за политически проекти.

В първата вълна се помнят имената на спортната журналистка Клара Маринова, после депутатка от БСП, както и на Асен Агов и Диляна Грозданова. Грозданова успява да сбъдне мечтата на всеки опортюнист и прави завъртане на 360 градуса. Първо взема завоя от емблематично лице на БНТ към политиката като пиар на Стефан Софиянски, влиза и сред учредителите на партията му „Съюз на свободните демократи“; след това застава и на депутатската банка (2001–2005) в редиците на НДСВ, а после се връща в медиите като изпълнителна директорка и водеща на частната TV7, чийто собственик тогава е съпругът ѝ Любомир Павлов. 

Асен Агов пък минава през БТА, БНР и БНТ, където стига до директор на новините, а после и на цялата телевизия след идването на власт на СДС (1992–1993). За да няма никакви съмнения кои са двигателите зад кариерното му развитие, е уволнен веднага след падането на правителството на Филип Димитров и преминава в активна политическа кариера с дълга поредица депутатски мандати от листата на СДС. Години след него този висш пилотаж пробва и Антон Хекимян, но стигна само до поста общински съветник от ГЕРБ в София.

Да, ама не

Единствен Петко Бочаров казва своето прословуто „Да, ама не“ на предложенията за политическа кариера. Дългогодишен журналист в БТА, по-късно зам.-главен редактор, добил популярност през 80-те като лице на предаването „Всяка неделя“, през 1991 г. е предложен за депутат от СДС, но отказва, защото смята депутатстването за несъвместимо с журналистическата си роля. Запомнете това. Защото е 

първият документиран публичен дебат в България за конфликта на интереси между медийна и политическа роля след промените. И първият публичен отказ. Следват тихи отлагания или признателни съглашателства. 

Между другото, Петко Бочаров е сред малкото публични личности с минало на сътрудници на Държавна сигурност, които сами го изваждат на светло, преди то да бъде огласено официално, и се разкайват за това. Изглежда, интегритетът понякога позволява на човек да демонстрира доблестно поведение дори с подобна биография. Обратното обаче също важи: фактът, че името ти никога не е било в архивите на един мракобесен апарат, сам по себе си не те прави по-достоен.

Да не се посочваме!

Властта в България може да се смени, да се прекръсти на „прогресивна“ и да обещае нов обществен договор, но едно остава непроменено – страхът от журналистически въпроси. А когато медиите са заключени в мазето, „демокрацията“ неизбежно започва да си говори сама със себе си. От Дарина Сарелска.

Частните телевизии като политически стартови площадки

Периодът на ширпотребата идва със зората на частните телевизии. Пионери са Волен Сидеров и неговата проруска партия „Атака“, която се ражда като политически проект от едноименното предаване на Сидеров по телевизия СКАТ, а само няколко години по-късно се изкачва до четвърта политическа сила в 40-тото Народно събрание.

Николай Бареков се опитва да повтори модела през 2014 г. След седем години, в които гради образа си в най-гледания сутрешен блок – на bTV, и то в най-силните години на телевизията, за кратко става началник в TV7 на банкера Цветан Василев, който тогава все още е в съдружие с Делян Пеевски. На 25 януари 2014 г. Бареков учредява партия „България без цензура“, с която достига до мандат в европарламента. Бареков е може би най-яркият пример за употребата на медия като политически трамплин. По-късно сам заявява: „Аз помогнах на Пеевски да разврати медиите“ – самопризнание, което независимо от мотивацията илюстрира дълбочината на проблема.

Интересното е, че по пътя си Бареков успява да приласкае и друг влиятелен за времето си телевизионен журналист – Росен Петров, който обръща палачинката на живо в ефира на bTV. По време на интервюто си с политика Бареков в предаването си „Нека говорят“ на 9 февруари 2014 г. водещият Петров подарява на госта си своята офицерска сабя и му се врича във вярност в ефир, като напуска телевизията с изчитане на нарочна декларация, за да се влее в редиците на Барековата партия. Без цензура. Един от най-срамните моменти, записани от камера в най-новата ни телевизионна история, е все още достъпен в интернет, макар и не на страницата на bTV, насладете се. 

Списъкът продължавa с Елена Йончева, Тома Томов, водещите от Nova Калина Крумова (започнала кариерата си от СКАТ) и Цвета Кирилова, Александър Симов и така до Антон Хекимян и Петър Волгин. През 2023 bTV поне от кумова срама изпрати Хекимян на партийна служба, приемайки оставката му с „незабавен ефект“ и демонстрирайки престорена институционална чувствителност към репутационния риск.

За да гаси имиджовия пожар тогава, телевизията обеща външен мониторинг на обективността на новините и актуалните предавания. Не се чу какво е установила тази проверка. Макар другата проверка – публичната, Хекимян системно да не издържаше години преди това, утвърждавайки се като предпочитан интервюиращ на Бойко Борисов, който в най-мрачните времена на брутално политическо превземане на прокуратурата започваше интервютата си с главния прокурор Цацаров с въпроса какво значи името Сотир (значи „спасител“) и с покана да сподели кого последно бил спасил от кабинета си в Съдебната палата. Това само му вдигна цената до шеф на новините и неуспял кандидат-кмет на ГЕРБ. 

И така до днес, когато никой не се скандализира при прескачането на шефовете на медии в политиката. Няма нужда да се правят проверки наужким, нито да се мятат оставки. Просто си пускаш неплатен. Така Кирил Вълчев е и възможен, и направо закономерен кандидат за вицепрезидент, а в инициативните комитети се прескачат журналист през журналиста – от Константин Вълков при Андрей Гюров, до Валерия Велева, Кристина Патрашкова и Явор Дачков при Илияна Йотова. 

Има за всички. Хубаво е, и е готово

Хубавото е, че става видимо. Журналисти с двойно предназначение се самоосветяват, заемайки видими публични позиции. Тази прозрачност, макар да убива доверието в професията, все пак е и малко полезна. Защото вдига завесата пред тези авторитети под прикритие. Разбира се, не бива да сме наивни – със сигурност се отглеждат приемливи фасади от ново поколение. А и границата отдавна е твърде размита. 

Да, между журналистиката и политическата власт трябва да има защитна стена. 

За съжаление, все по-често тя прилича на въртяща се врата. Съвсем нормализирана е вече практиката действащи журналисти да предлагат медийни обучения и консултантски PR услуги – и на корпоративни, и на партийни клиенти. Защо пък да не водят направо и собствените си кампании от студиата на новините!

Къде е границата? 

Журналистите, разбира се, могат и е нормално да бъдат политически хора – с убеждения, с позиция, с обществен ангажимент. Безпристрастността не означава безразличие. Границата минава другаде – 

да не злоупотребяваш с капитала на собственото си доверие. Да не го търгуваш, да не го превръщаш в разменна монета за пост или привилегия. 

Журналистите имат право на гражданска активност, дори и на граждански протест – защото това е лична позиция. Не злоупотреба или тайно превалутирано доверие в полза на кампания или на конкретен политически интерес. Стандартът за конфликт на интереси и недопускане на пристрастност е описан ясно и с примери в принципите на Associated Press – световния аналог на БТА, с който родната агенционна журналистика иначе обича да се сравнява:

От служителите в редакцията се очаква стриктно да избягват всякаква политическа дейност, независимо дали редовно отразяват политика, или не. Те не могат да се кандидатират за политически длъжности или да приемат политически назначения, нито да извършват дейност по връзки с обществеността за политици или техни организации. При никакви обстоятелства не бива да даряват средства на политически организации или за политически кампании. Те трябва да преценяват особено внимателно дали да членуват, или да правят дарения в други организации, които могат да заемат политически позиции.

Дори служителите извън редакцията – разбирайте счетоводители, шофьори и юрисконсулти, трябва да се въздържат от политическа дейност и от дарения, освен ако не получат одобрение от прекия си ръководител. Ограничения има даже за членовете на техните семейства, чиито политически каузи и ангажименти също подлежат на публично деклариране. 

Разбира се, преквалификацията на журналисти в политици не е само роден феномен – справка: от Мусолини, през Уинстън Чърчил, до Борис Джонсън. Но и тук има нюанс и той е в наличието на т.нар. охлаждащ период. 

Има ли кой да ги накаже? За забранителните списъци в bTV и кебапчетата в медиите

Имало едно време един Асен. Вървял, вървял през девет телевизии в десета и попаднал в bTV, където решил, че ще е „яли, пили и се веселили“, докато той каже и само с когото той прецени. Извинявайте, но няма нищо приказно в тази история. От Дарина Сарелска.

Липса на „охлаждащ период“ 

Според етичните стандарти в много страни, когато журналист става политик, се изисква, или поне силно се препоръчва, пауза между двете роли, за да не се компрометира доверието в медиите. Нали заради това доверие се търсят подобни кандидати все пак?! Не е много умно да се реже клонът, на който седиш. 

Така преходът е плавен и бившите журналисти стават политици обикновено след като вече са изградили партийна кариера (говорители, съветници, експерти). Такъв е примерът и на самата Илияна Йотова, която е доста последователна в кариерната си траектория: започва като репортер, налага се като разпознаваемо лице в БНТ, после оставя журналистиката зад гърба си, заема се с комуникациите на БСП, откъдето бавно, полека и отвътре изгражда партийна кариера, за да стигне днес до президент. Това е класическият и по-приемлив път. При Вълчев и при повечето български примери преходът изглежда рязък: от днес за утре. Без междинни стъпки в партийната йерархия или време за хигиенна дистанция. Нещо като да вдигнеш сватба, преди комшиите да са разбрали, че си се развел.

Но да се върнем към (само)признанието на Кирил Вълчев: 

Приемам поканата на президента като признание не за мен, а за БТА – институция на съгласие, на общуване с българите по света, на памет, нещо, от което има нужда в Президентството.

А Илияна Йотова допълва: 

Дълги години имаме обща кауза с господин Вълчев. Работихме заедно за тази кауза – за опазване на българщината, за развитието на българската идентичност, на българския дух, на българската писменост, на буквите.

Да, от такава БТА има нужда Президентството. От такива медии имат нужда всички овластени. Институции на дългогодишното съгласие. Медии, тихи за злоупотребите на властта и споделящи шумно нейните каузи – днес буквите и българщината на „Прогресивна България“, вчера евроатлантизмът ала ГЕРБ и ДПС – Ново начало, утре – каквото нуждата покаже. Стига да е споделена. 

Good night, and good luck, motherf*ckers

Историята на американското предаване „60 минути“ е разказ за механизмите, чрез които се опитомяват медиите. И тези механизми са удивително сходни, независимо от пазара или знамето пред сградата на телевизията. Един текст в стил „Думам ти, дъще, сещай се, журналистическа снахо“ от Дарина Сарелска.

А журналистиката – тя отдавна е пратена в отпуск. Обикновено платен. Така стигаме до реалността, в която нищо не е вярно и всичко е възможно. Времена, в които всеки, който има YouTube канал, се пише журналист. Всеки, който е натрупал два грама доверие като журналист, може да го капитализира за политически пост. Всеки новоизлюпен политик може да привижда в собствените си котерии обществения интерес, обяснявайки ни как „работи за хората“. А пък хората гледат „Ергенът“. Може би там някъде е бъдещият спасител. 

The collective thoughts of the interwebz