<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Francois Falala-Sechet</title>
    <description>The latest articles on Forem by Francois Falala-Sechet (@frsechet).</description>
    <link>https://forem.com/frsechet</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F317478%2F40453e09-4e8b-4713-977b-904080a12ca4.jpeg</url>
      <title>Forem: Francois Falala-Sechet</title>
      <link>https://forem.com/frsechet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/frsechet"/>
    <language>en</language>
    <item>
      <title>Language Playgrounds are Cool</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Wed, 28 Apr 2021 08:59:35 +0000</pubDate>
      <link>https://forem.com/frsechet/playgrounds-for-programming-languages-are-cool-448k</link>
      <guid>https://forem.com/frsechet/playgrounds-for-programming-languages-are-cool-448k</guid>
      <description>&lt;p&gt;A few years ago, we've built an open-source programming language called &lt;a href="https://csml.dev"&gt;CSML&lt;/a&gt;, that makes it super easy to build powerful chatbots. It's a complete programming language, with loops, conditions, variables etc., and it is super easy to learn as it is close to human language (say stuff, remember stuff, do stuff). It helps handling the conversation state, the user's memory, connexions with 3rd-party APIs...&lt;/p&gt;

&lt;p&gt;However, to test it, you need to &lt;a href="https://github.com/CSML-by-Clevy/csml-engine"&gt;download a package from Github&lt;/a&gt;, find out how to install it, setup your machine and local environment developments... all of which make it hard to simply get started with the language.&lt;/p&gt;

&lt;p&gt;So we decided to create an open, browser-based, no-install, no-login IDE. You get the kind of immediate WYSIWYG experience: code something, build, run, see what works (and what doesn't). It's a great place to learn and test your ideas.&lt;/p&gt;

&lt;p&gt;Many languages have one, even the hard ones: Rust has &lt;a href="https://play.rust-lang.org/"&gt;https://play.rust-lang.org/&lt;/a&gt;, Go has &lt;a href="https://play.golang.org/"&gt;https://play.golang.org/&lt;/a&gt;, etc. Then there are the obvious ones, like Codepen or Glitch, for the more common languages. In my opinion, all languages should have one. It makes learning the language a breeze!&lt;/p&gt;

&lt;p&gt;If you want to try out CSML, you can do so on our brand new Playground: &lt;a href="https://play.csml.dev"&gt;https://play.csml.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you want, you can also support us and leave a review on our Product Hunt launch: &lt;a href="https://www.producthunt.com/posts/csml-playground"&gt;https://www.producthunt.com/posts/csml-playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoy programming languages as much as I do 🤓!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ide</category>
      <category>language</category>
    </item>
    <item>
      <title>Solving Chatbot-Based User Authentication 🔑: Introducing NoPass.me</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Sat, 20 Mar 2021 18:25:38 +0000</pubDate>
      <link>https://forem.com/frsechet/solving-chatbot-based-user-authentication-introducing-nopass-me-417e</link>
      <guid>https://forem.com/frsechet/solving-chatbot-based-user-authentication-introducing-nopass-me-417e</guid>
      <description>&lt;p&gt;Making sure that a user is who they say they are is a very common problem that almost all applications have to solve at one point or another. In the case of a chatbot, you sometimes need to perform actions on behalf of a user, who doesn't necessarily have an account they can authenticate with in the chatbot. How do you verify their identity?&lt;/p&gt;

&lt;p&gt;Short answer: with &lt;a href="https://nopass.me"&gt;NoPass.me&lt;/a&gt;! 🤯&lt;/p&gt;

&lt;h1&gt;
  
  
  What is NoPass.me?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://nopass.me"&gt;NoPass.me&lt;/a&gt; is an open-source, accountless, identity verification service, dedicated to chatbots. It was created by &lt;a href="https://clevy.io"&gt;Clevy.io&lt;/a&gt;, the team behind the open-source chatbot-oriented &lt;a href="https://csml.dev"&gt;CSML programming language&lt;/a&gt;. It lets you easily verify that a user is the rightful owner of an email address (or a phone number, via SMS), by generating and sending a one-time password and validating it on your behalf.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy is at the heart of this service&lt;/strong&gt;, which you can also host on your own servers, as it is fully open source. For example, while other similar services usually force you to create an identity in their system for each user you want to verify, NoPass.me lets you simply verify any email address without storing any user information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is also completely secure&lt;/strong&gt;. Each email address (or phone number) and authentication code is irreversibly hashed with a state-of-the-art encryption process before it is stored in the database, making it impossible to decode even with privileged access to the data. As no personal information is ever stored in clear text by the service, there is no risk of leaking user information even in worst-case scenarios. The data is also automatically removed either when the authentication code expires or when a code is entered for the user, right or wrong.&lt;/p&gt;

&lt;p&gt;Last but not least: &lt;a href="https://nopass.me"&gt;NoPass.me&lt;/a&gt; is free for up to 5000 email and 200 phone number identity verification API calls. This is perfect for startups and indie devs!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Clevyio/nopass.me"&gt;The source code of NoPass.me is entirely open source&lt;/a&gt;. I encourage you to go and read it&lt;/strong&gt;, which is also always a good idea when using a security product.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using NoPass.me in a Chatbot
&lt;/h1&gt;

&lt;p&gt;To get started with NoPass.me, request a free API key on the website (or install the open-source version), then continue reading this article. I'll wait! 😉&lt;/p&gt;

&lt;p&gt;The process for verifying a user with NoPass.me is quite straightforward. There are only 2 easy steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate an authentication code for the user you want to verify&lt;/li&gt;
&lt;li&gt;Get the user to enter the code they received and verify it with NoPass.me&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a simple flow diagram of how this usually comes together:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ao5OBbCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kv897pq0tuxd61ym785j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ao5OBbCa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kv897pq0tuxd61ym785j.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To demonstrate the process, I have created a simple example chatbot on [CSML Playground](&lt;a href="https://playground.csml.dev"&gt;https://playground.csml.dev&lt;/a&gt; that you can use as a starting point (obviously, you will need to set your own API keys): &lt;a href="https://playground.csml.dev/bot/aa958f0d-8fb8-4ead-8905-b17551919eda"&gt;https://playground.csml.dev/bot/aa958f0d-8fb8-4ead-8905-b17551919eda&lt;/a&gt;. Let's break it down and see how it works!&lt;/p&gt;

&lt;p&gt;First, we retrieve our target user's email address. In this case, we are simply going to ask for the information but we could also retrieve it from an external API or another part of the conversation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * This CSML Chatbot demonstrates how NoPass.me works
 * when used in a CSML chatbot. The same principles apply
 * with every other programming language, as long as there
 * is a HTTP client library!
 */&lt;/span&gt;
&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"Hello! 👋"&lt;/span&gt;
  &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"Before I can give you access to this service, let me verify your identity"&lt;/span&gt;
  &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;getEmail&lt;/span&gt;

&lt;span class="n"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"What's your email address?"&lt;/span&gt;
  &lt;span class="n"&gt;hold&lt;/span&gt;

  &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_email&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"This is not a valid email address"&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;getEmail&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;remember&lt;/span&gt; &lt;span class="n"&gt;userEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;

  &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;verifInit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can initiate the verification process by calling the &lt;code&gt;/verify/init&lt;/code&gt; endpoint of the NoPass.me API, using our API key. You can check the full documentation of this endpoint on &lt;a href="https://www.nopass.me/docs.html#post-/verify/init"&gt;this address&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Initiate the verification process:
 * Let NoPass.me send them an email with an authentication code
 * 
 * The only mandatory parameter is the target email address to verify,
 * all other parameters have sensible defaults.
 *
 * Check the docs on https://nopass.me/docs
 */&lt;/span&gt;
&lt;span class="n"&gt;verifInit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"target_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"subject"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Your Verification Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Hi!&amp;lt;/h1&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Your verification code is %code%."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"expires_in"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt; &lt;span class="c1"&gt;// 15 minutes&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nopass.me/v1/verify/init"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"X-Api-Key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YOUR_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"There was an issue with your request. Please verify your parameters"&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;getEmail&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;verifCode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few seconds, our user receives an email with a random authentication code (more precisely, a one-time password). Let's verify it with the following process, as &lt;a href="https://www.nopass.me/docs.html#post-/verify/validate"&gt;documented on this page&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Finish the verification process:
 * Let NoPass.me check if the given authentication code is valid
 * 
 * Check the docs on https://nopass.me/docs
 */&lt;/span&gt;
&lt;span class="n"&gt;verifCode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"OK, please check your email and enter the verification code:"&lt;/span&gt;
  &lt;span class="n"&gt;hold&lt;/span&gt;

  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"target_type"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.nopass.me/v1/verify/validate"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"X-Api-Key"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"YOUR_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"There was an issue with your request. Please verify your parameters"&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;getEmail&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="s"&gt;"The code is valid! Welcome!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the end result of this exact code, when run with a working API key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S3J3aL_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0lf45gyw8o5728gaoi41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S3J3aL_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0lf45gyw8o5728gaoi41.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, this process is extremely easy to implement in your own code. This service is particularly helpful in situations where you can not authenticate the user otherwise (using an OAuth or SAMLv2 identity provider for instance) but still need a high degree of confidence that the visitor is who they say they are.&lt;/p&gt;

&lt;p&gt;We're extremely happy to launch this very powerful service today and hope that you will use it for your own projects!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 Support us by starring the repo on Github: &lt;a href="https://github.com/Clevyio/nopass.me"&gt;https://github.com/Clevyio/nopass.me&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 Request your free NoPass.me API key: &lt;a href="https://nopass.me"&gt;https://nopass.me&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>auth</category>
      <category>security</category>
      <category>mfa</category>
      <category>api</category>
    </item>
    <item>
      <title>What's New in CSML v1.5.0</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Sat, 20 Mar 2021 18:12:30 +0000</pubDate>
      <link>https://forem.com/frsechet/what-s-new-in-csml-v1-5-0-pa</link>
      <guid>https://forem.com/frsechet/what-s-new-in-csml-v1-5-0-pa</guid>
      <description>&lt;p&gt;We just released &lt;a href="https://github.com/CSML-by-Clevy/csml-engine/releases/tag/v1.5.0"&gt;CSML v1.5.0&lt;/a&gt;! 🎉  Let's have a quick look together at some of the highlights of this release...&lt;/p&gt;

&lt;h2&gt;
  
  
  Crypto Utils
&lt;/h2&gt;

&lt;p&gt;Most systems nowadays require some sort of specific authentication or encoding to communicate securely. In this release, we introduced support for Base64 and Hex encoding/decoding, creating and validating JWTs, as well as hashing and HMAC functions.&lt;/p&gt;

&lt;p&gt;Here are some examples of what you can do with the new Crypto utils:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;say&lt;/span&gt; &lt;span class="n"&gt;Crypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World 😆"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;create_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sha256"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hex"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;JWT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SECRET_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Base64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user:password"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="s"&gt;"Authorization"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Basic {{auth}}"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 &lt;a href="https://docs.csml.dev/language/standard-library/crypto"&gt;Link to the documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Steps and Flows
&lt;/h2&gt;

&lt;p&gt;Dynamically navigating to other steps and flows was quite hard and cumbersome to achieve until today. It usually required a long list of &lt;code&gt;if (x) goto y&lt;/code&gt; in your code, similar to &lt;a href="https://github.com/Owlie-le-Chatbot/Owlie/blob/main/flows/Default.csml"&gt;this example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, you can use the new $ syntax used for referencing variables in flow and step names instead: &lt;code&gt;goto $stepname@$flowname&lt;/code&gt;. This helps make code much more concise and reusable!&lt;/p&gt;

&lt;p&gt;Using dynamic steps and flows, the example from above can easily be refactored like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// redirect to a random flow in a list of possible targets&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;flows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"flowA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"flowB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"flowC"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;targetFlow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OneOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;targetFlow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 &lt;a href="https://docs.csml.dev/language/standard-library/crypto"&gt;Link to the documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bot Environment Variables
&lt;/h2&gt;

&lt;p&gt;Efficiently and securely storing and accessing bot-wide variables (such as API keys, default configuration values, etc.) was quite difficult to do until now in CSML, since it usually required either writing these variables in clear text in many places in your bot, or replicating them in each user's memory.&lt;/p&gt;

&lt;p&gt;With the new &lt;code&gt;_env&lt;/code&gt; global read-only variable, you can access bot-wide environment variables everywhere in your bot, without ever needing to remember them or replicating the value written in clear text anywhere in the bot.&lt;/p&gt;

&lt;p&gt;For instance, if the bot communicates with a 3rd-party API, you can store this value under &lt;code&gt;MY_API_KEY&lt;/code&gt; and use it anywhere in the bot with &lt;code&gt;_env.MY_API_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://docs.csml.dev/language/memory/global-variables"&gt;Link to the documentation&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  CSML Studio Updates
&lt;/h1&gt;

&lt;p&gt;CSML Studio also received some love with the latest update. Here are some of our favorite new features!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing: Bot Snapshots
&lt;/h2&gt;

&lt;p&gt;It is a good practice to never work directly on your production code, in order to avoid impacting your end users when updating your code. This is why we just introduced Bot Snapshots: you can think of snapshots as git tags or github releases for your chatbot.&lt;/p&gt;

&lt;p&gt;Using Snapshots, you can easily create tagged versions of your bot, pin them to your production channels as to not risk any disruption during development, or revert your code to a previous version at any time!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xOlrRTbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3j6iuai0eyg7xdhozbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xOlrRTbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z3j6iuai0eyg7xdhozbq.png" alt="image"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  New Bot Sharing Experience
&lt;/h2&gt;

&lt;p&gt;In the latest release of CSML Studio, we changed the way you can share bots with other users. You can now share any individual bot with any user, rather than all of your bots with a group of users who will also share their bots with you in return.&lt;/p&gt;

&lt;p&gt;This is especially useful if you are working on bots that you need to share with different sets of users. For instance, if one team is working on a bot and another team is working on a different bot, you can now work on both bots without creating 2 separate accounts or giving access to both bots to both teams.&lt;/p&gt;

&lt;p&gt;To invite a user or revoke someone's access to a bot, visit your bot's &lt;strong&gt;Settings &amp;gt; Team &amp;gt; Manage team&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FDv8fw37--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dudqgdkup7mjggrah2hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FDv8fw37--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dudqgdkup7mjggrah2hb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an upcoming release, we will also introduce roles, with differentiated access rights to each bot. Stay tuned!&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Improvements!
&lt;/h2&gt;

&lt;p&gt;In this latest update, we also released:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a brand new IDE with better support for CSML language, autocompletion and syntax highlighting 👩‍💻&lt;/li&gt;
&lt;li&gt;a new "Sign-in with facebook" button to make it easier for facebook users to create a free &lt;a href="https://studio.csml.dev"&gt;CSML Studio&lt;/a&gt; account 🔑&lt;/li&gt;
&lt;li&gt;a standardized experience for NLU-enabled chatbots — check the details here 💬&lt;/li&gt;
&lt;li&gt;... and also a lot of little tweaks and bugfixes 🤓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these new features are already live on &lt;a href="https://studio.csml.dev"&gt;CSML Studio&lt;/a&gt;. Try them out today and let us know what you think!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>chatbots</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to connect a Google Assistant action with a custom chatbot backend</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Wed, 22 Jan 2020 13:24:33 +0000</pubDate>
      <link>https://forem.com/frsechet/how-to-connect-a-google-assistant-action-with-a-custom-chatbot-backend-3c1j</link>
      <guid>https://forem.com/frsechet/how-to-connect-a-google-assistant-action-with-a-custom-chatbot-backend-3c1j</guid>
      <description>&lt;p&gt;How easy is it to create a chatbot for Google Actions and Google Assistant-powered devices (Google/Nest Hub, Google Home, etc.)? Let’s find out!&lt;/p&gt;

&lt;p&gt;Out of the box, Google does not make it as easy as it seems to connect a voice assistant to a custom chatbot. They are trying very hard to make you use Dialogflow (a Google product since they bought api.ai a few years ago), however there are ways to bypass Dialogflow and connect Actions to your preferred custom chatbot backend, in our case the &lt;a href="https://studio.csml.dev"&gt;CSML Studio&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Creating the chatbot
&lt;/h1&gt;

&lt;p&gt;For this example, let’s create a simple CSML-powered chatbot that guides users through step by step instructions to fix a printer running out of toner. Not the most fun example, but still very useful as this is one of the most common operations you will have to do on any printer!&lt;/p&gt;

&lt;p&gt;As usual creating a chatbot is very easy with CSML: simply describe the steps one by one until you are done with the conversation. One thing to keep in mind is that Google Actions have some specific requirements. &lt;br&gt;
Among the main ones are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more than two simple text components per step&lt;/li&gt;
&lt;li&gt;No more than 640 characters per text component&lt;/li&gt;
&lt;li&gt;If you want to display an image, there must be a text before and at least one button after&lt;/li&gt;
&lt;li&gt;Same thing with audio files, which will also automatically emit a “FINISHED” event when it is done playing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are quite a few other rules but these are the main ones that we will be considering today. Here is a &lt;a href="https://developers.google.com/assistant/conversational/responses"&gt;link to the documentation&lt;/a&gt; so you know what is possible and what are the requirements.&lt;/p&gt;

&lt;p&gt;Knowing that, here is the flow we will be using for our Action. It is quite straightforward but of course let me know in the comments if anything is unclear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start:
  use Button("Yes", accept=["oui", "yes", "y"]) as btny
  use Button("No", accept=["non", "no", "nop", "nope"]) as btnn
  say "Many printer issues come from empty cartridges."
  say Question("Is that your case?", buttons=[btny, btnn])
  hold
  if (event match btnn) goto comments
  say "Let's follow these simple steps to replace your ink cartridge!"
  say "Step 1: Lift up the scanner unit and open the cartridge older."
  say Image("https://cdn.csml.dev/customers/4140eea8-4825-4df6-981d-c1ee239884bc/files/29f64cb9-308b-4ff4-8e7c-ad2dfe20c37b/etape1.jpg")
  say Button("Next")
  hold

  say "Step 2: Remove the yellow tape from the side of the cartridge."
  say Image("https://kb.epson.eu/pf/12/webfiles/Article%20Images/Inkjet%20Printers/yellow_tab.jpg")
  say Button("Next")
  hold

  say "Step 3: Insert the new cartridge into the holder and push it down until it clicks into place."
  say Image("https://kb.epson.eu/pf/12/webfiles/Article%20Images/Inkjet%20Printers/click_in_place.jpg")
  say Button("Next")
  hold

  say "Step 4: Close the lid of the printer."
  say Image("https://kb.epson.eu/pf/12/webfiles/Article%20Images/Inkjet%20Printers/lift_up_lid_old.jpg")
  say Button("Next")
  hold
  goto printerresolved

printerresolved:
  use Button("Yes", accept=["oui", "yes", "y"]) as btny
  use Button("No", accept=["non", "no", "nop", "nope"]) as btnn
  say Question("Did this solve your issue?", buttons=[btny, btnn])
  hold

  if (event match btny) {
    say "Glad I could help!"
    say "Good bye!"
    goto end
  }

  say "I'm sorry I could not help you."
  say "Please open a ticket on Service Now to get additional help!"
  goto end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One more thing to consider is that Google Actions are available on devices with or without a screen. In our scenario we focused on a device with a screen, but remember that some users will not see the images you show them. You might want to provide a different scenario in that case; luckily CSML provides you that information with the &lt;code&gt;_metadata.capabilities.SCREEN_OUTPUT&lt;/code&gt; context variable (true or false). You can use it to say different things depending on how your users are using the Action. There are a &lt;a href="https://developers.google.com/assistant/conversational/surface-capabilities#response_branching"&gt;few other variables available&lt;/a&gt;, check them out!&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Connecting the bot to Actions on Google
&lt;/h1&gt;

&lt;p&gt;Sadly, Google does not make it too easy to connect your action to a custom backend without using Dialogflow — the option to do so is actually quite hidden and not well documented. Most annoyingly, you will need to be able to run a command from your machine, which should not be a problem if you are already familiar with a terminal. Luckily, this is only a one-time setup: once you have done it, you are all set!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the Google Actions console and create a new project:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s7LiOr-y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c5015u0u7n7vd7po5ye8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s7LiOr-y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c5015u0u7n7vd7po5ye8.png" alt="You can select the language for your action in this step, but we can also change that later."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select Actions SDK as the type of action you want to build.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is important to not miss, as other options will not let you connect your own conversational backend to your action!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vFBiW1Cu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3836/1%2A9WBSYPvxbOXrNAy6z4vSyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vFBiW1Cu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3836/1%2A9WBSYPvxbOXrNAy6z4vSyw.png" alt="Actions SDK is not very visible, at the bottom of the screen!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Actions SDK is not very visible, at the bottom of the screen!&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the next screen, simply copy the project ID from the given command:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;gactions update --action package PACKAGE_NAME --project PROJECT_ID&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.google.com/assistant/tools/gactions-cli"&gt;Download and install gactions-cli&lt;/a&gt; with the appropriate package for your computer (Mac, Windows, Linux…).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back to the CSML studio, go to Connectors, then select Create a new Channel, and click on &lt;strong&gt;Google Assistant&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SWBrWrLp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2050/1%2ASNUEd7n1cNctbM8gpB2Epw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SWBrWrLp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2050/1%2ASNUEd7n1cNctbM8gpB2Epw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a name and description for your channel, then paste the Project ID from step 4. In our case, we were assigned project ID fir-csml by Google, as well as the lowercase 2-letter language code for the actions main language (defaults to en if you leave it empty), then click submit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_NJoXnNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3712/1%2AuTvv79dKsuadvgxWPH5anA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_NJoXnNL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3712/1%2AuTvv79dKsuadvgxWPH5anA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;After submitting, you will be invited to download a gactions package (in JSON format). Download it, then run the provided command after replacing PACKAGE_NAME with the actual path where you saved the gactions package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The command may ask you to authentify yourself with Google. Go to the provided URL inside your web browser, complete the authentification, copy the provided code and paste it in your terminal where you entered the command before.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zZyD232B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/5760/1%2A_noBD0fW-2YoV3oAV2Nm1Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zZyD232B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/5760/1%2A_noBD0fW-2YoV3oAV2Nm1Q.png" alt="Authorization flow example with gactions CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finally, back on the Actions on Google console, go to Develop &amp;gt; Invocation and pick an invocation (how people are going to call your action, for example “Super Demo” — beware, Google has quite a strict naming convention, requiring a 2-word name that does not use one of many forbidden terms).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BpUtlmpN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/4592/1%2A2h3gMh7kHkZMPRxTBXPf0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BpUtlmpN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/4592/1%2A2h3gMh7kHkZMPRxTBXPf0g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;That's it! You are now all set to test and publish your Google Assistant action made with CSML. I hope this guide was helpful to get started, as Google really does not make life easy with their Actions SDK. Let us know what fun or interesting chatbots you decide to build with CSML!&lt;/p&gt;

</description>
      <category>chatbot</category>
      <category>googleassistant</category>
    </item>
    <item>
      <title>Managing secrets in CI/CD with AWS Secrets Manager
description</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Tue, 14 Jan 2020 21:40:11 +0000</pubDate>
      <link>https://forem.com/frsechet/managing-secrets-in-ci-cd-with-aws-secrets-manager-description-2iln</link>
      <guid>https://forem.com/frsechet/managing-secrets-in-ci-cd-with-aws-secrets-manager-description-2iln</guid>
      <description>&lt;p&gt;Managing API keys, database passwords, and other secret variables in CI has always been a tiny bit painful and often a massive security loophole in most organisations.&lt;/p&gt;

&lt;p&gt;Let’s try to see how we can improve the situation with &lt;a href="https://aws.amazon.com/secrets-manager/"&gt;AWS Secrets Manager&lt;/a&gt;, &lt;a href="https://cloud.docker.com/u/clevy/repository/docker/clevy/awssecrets/general"&gt;this simple wrapper&lt;/a&gt;, and your favorite CI provider (in our case, &lt;a href="https://about.gitlab.com/product/continuous-integration/"&gt;Gitlab CI&lt;/a&gt; — but it should work relatively similarly with most providers).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XknNHdPf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2880/1%2Az2lLrLCCnlTsC2XsMFnvQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XknNHdPf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2880/1%2Az2lLrLCCnlTsC2XsMFnvQw.png" alt="Let’s use AWS Secrets Manager to help you secure your CI stages."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Let’s use AWS Secrets Manager to help you secure your CI stages.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;By definition, secrets are meant to be… secret. But CI should not be a black box, accessible by a few chosen ones, only so that you can protect your precious secrets! CI is basically the last time you get to touch your app before it ships to your customers or users. All developers should be able to inspect the logs of previous builds and run builds on their own.&lt;/p&gt;

&lt;p&gt;Let’s start by stating the obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you can get away in doing what you are doing without using any secrets and just making everything already public, great. But chances are you can’t.&lt;/li&gt;
&lt;li&gt;  Secrets are obviously meant to be secret, but at least one person will need to know them at some point, and people are weak.&lt;/li&gt;
&lt;li&gt;  Security through obscurity is not security. Hiding secrets, for example inside CI stages, is not security.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In that case, what’s a good (as in “&lt;em&gt;easy and I can do it without having a whole costly devops team&lt;/em&gt;”) way to deal with secrets? Let’s consider your probable situation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You can setup secrets in the CI provider’s configuration panel. This is great as it enables you to pass any variable to any project very easily. However, when you have hundreds of projects, and quite possibly some shared variables between projects, it can become a little bit difficult to manage. You also need to setup the environment properly before the first build, which means letting someone know of the variable, which means introducing a weak point.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NipPs0Bu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2184/1%2AwRH_FxAWPmG-RnW8m8rOHg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NipPs0Bu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2184/1%2AwRH_FxAWPmG-RnW8m8rOHg.png" alt="The “Variables” panel inside Gitlab’s CI configuration for a given project."&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The “Variables” panel inside Gitlab’s CI configuration for a given project.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Secrets usually have a lot of power attached to them (otherwise they wouldn’t be secret). CI stages will often need to retrieve private packages, perform some private task, access a private database, or publish a new release of your app that could ultimately get in the hands of your users. If someone were to get access to a secret used in CI, they usually gain a LOT of power, and it’s not necessarily easy to detect right away.&lt;/li&gt;
&lt;li&gt;  Perhaps you want to hide your secrets and not make them available to your developers. You can use the “protected” setting above and some security setting in the access rules, but it does not completely prevent developers to log the secret in a hidden part of their code that would miraculously pass all the code reviews (&lt;em&gt;you have code reviews, right?&lt;/em&gt;), and there you have your secret available in plain text to anyone with read access to the CI logs — which should be most of your developers, if you ask me.&lt;/li&gt;
&lt;li&gt;  How hard would it be to replace all your secrets, right now? Let’s say one of your engineers, tasked with setting up these environments, leaves the company. What damage can they do with the keys they know? What if a database password, used in a few different projects, needs to be replaced for some reason — in how many places is it used across all your repositories? Do you really want to spend half a day updating 50 repositories every time somebody leaves the company, or as a routine task every few weeks because your policy says you should rotate all secrets regularly?&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  So, what can we do?
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;The only way to make your secrets more secure&lt;/strong&gt; (given the limitation that you can not get away with &lt;em&gt;not&lt;/em&gt; having secrets at all, AND no matter what you do to prevent it, people will be able to access them one way or another at some point) is to make them more volatile. They should be revokable at any given time, without causing much damage, and as often as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should not care about who knows about what secret at any given time (because people will find out).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The only way you can practically consider revoking your secrets often&lt;/strong&gt; (and not spend a considerable amount of time manually replacing them everywhere if you have hundreds of them)  is to have them managed centrally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should not care about having to replace the secret every once in a while (because it’s a painless operation).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The only way you can guarantee that secrets will be revoked often&lt;/strong&gt; is by automating their rotation. Human is lazy, forgets, goes on vacation, is busy, sleeps…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should not care about this at all because you have better things to do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Secrets are meant to be volatile.
&lt;/h3&gt;

&lt;p&gt;I think the problem lies in the word &lt;em&gt;secret&lt;/em&gt;. &lt;strong&gt;People naturally think that secrets are effectively secret AND rely on them to stay secret&lt;/strong&gt;. The truth is, secrets &lt;em&gt;do&lt;/em&gt; get exposed. It is an unavoidable part of their lifecycle: the longer a secret stays in place, the higher the risk that it gets exposed, and then what?&lt;/p&gt;

&lt;p&gt;If your entire business relies on the sole concept of secrets staying secret, I feel sorry for you.&lt;/p&gt;

&lt;p&gt;On the other hand, if you actively &lt;em&gt;prepare&lt;/em&gt; for your secrets to be exposed at some point, and make it a natural event of your application to just casually change secrets every once in a while without having to even think about, then you solve a much, much large issue: peace of mind. It is very, very comparable to the concept of continuous integration: deploying to production often makes it an absolute non-event.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Consider you are terrible at security. Consider any secret as compromised if it does not get recycled every few hours/days/weeks. Make the rotation of your passwords a non-event. It’s as natural an operation as it gets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Secrets are a volatile piece of data, nothing more.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Enter AWS Secrets Manager
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/secrets-manager/"&gt;AWS Secrets Manager&lt;/a&gt; is a relatively new service by AWS which is similar to some sort of API-fied, cloud-enabled, 1Password on steroids.&lt;/p&gt;

&lt;p&gt;Basically, your main password is as usual with AWS, your AWS credentials (instance role, IAM user, etc.), which gives you access to fine-grained access settings (who can read/update secrets stored in the service). I am not going to go into how to setup an AWS account or the basic IAM concepts here, there are countless great resources about it online! Let’s consider you can access the AWS console, and know how to do so, and have heard about IAM before.&lt;/p&gt;

&lt;p&gt;The main features we are interested in here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Centralize management of as many secrets as you want without making them directly available to any particular entity. Instead, they are meant to be consumed on-demand, by using regular AWS credentials, and limiting access via standard IAM rules. &lt;strong&gt;This is a great example of responsibility separation by design&lt;/strong&gt;: use IAM for ACL, Secrets Manager for safe secrets management, and combine both on demand. Secrets should not care who has access to them as it should simply be considered as a piece of data, and by defining group or role based ACLs, you can give or revoke access to any secret values at all times.&lt;/li&gt;
&lt;li&gt;  Automate secrets rotation as often as you like with a Lambda function. Set once and forget. What this buys you is that as soon as you revoke access to Secrets Manager to anyone (or anything), they &lt;em&gt;might&lt;/em&gt; still access the current secrets for a little while, but as soon as this rotation script runs… who cares what secret they know?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By making secrets access &lt;strong&gt;volatile&lt;/strong&gt; and &lt;strong&gt;identity-based&lt;/strong&gt;, this service solves a bunch of security problems for all devops engineers who don’t need to reinvent the wheel for secrets management (or put their whole company’s security at risk if they don’t address it properly).&lt;/p&gt;
&lt;h3&gt;
  
  
  Using AWS Secrets Manager in CI/CD
&lt;/h3&gt;

&lt;p&gt;Since the setup of AWS Secrets Manager takes about 5 minutes, the main complexity is to make this easy to integrate into your CI project. To help you with that, we released &lt;a href="https://hub.docker.com/r/clevy/awssecrets"&gt;https://hub.docker.com/r/clevy/awssecrets&lt;/a&gt;, a tool that helps you retrieve secrets to use in your projects’ CI steps. If you prefer to build from source for something this sensitive (you should), you can find them here: &lt;a href="https://github.com/Clevyio/docker-awssecrets"&gt;https://github.com/Clevyio/docker-awssecrets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following is our current production setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Private gitlab runners on EC2 instances with a GitlabCiInstance IAM role attached. These instances run in a VPC, which means that their access to/from outside is enforced by any security rules we can control.&lt;/li&gt;
&lt;li&gt;  An IAM policy for limiting read access to Secrets Manager, attached to the GitlabCiInstance role access that looks something like this (you can of course limit what secrets it has access to, but you get the idea):
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GitlabCiPolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;  
                &lt;/span&gt;&lt;span class="s2"&gt;"secretsmanager:GetSecretValue"&lt;/span&gt;&lt;span class="w"&gt;  
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;  
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;  
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;  Some secrets stored in AWS Secrets Manager with auto-rotation enabled, some projects in our gitlab repositories with CI enabled, etc. :-)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following would resemble a typical .gitlab-ci.yml file defining our CI process, with usually a first step that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;secrets:
  stage: secrets
  image: clevy/awssecrets
  script:
    - awssecrets --region eu-west-1 --secret my-secrets &amp;gt; .ci-secrets
  artifacts:
    # you want to set this to a value high enough to be used in all your stages,
    # but low enough that it gets invalidated quickly and needs to be regenerated later
    expire_in: 30 min
     paths:
      # this will be available by default in all the next stages
      - .ci-secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things to note here: there is no need to pass AWS credentials to aws secrets: remember, the instance has a role attached to it that automatically gives access to the service! So all calls are “automatically” authed, and there is no risk of leaking AWS credentials that could give access to your secrets, as this must be used in an instance role in an authorized EC2, which you do not want to grant to just anybody.&lt;/p&gt;

&lt;p&gt;This will produce an artifact, which is a fancy word for any file or folder you decide to pass to later stages. In our case, we have simply created a .ci-secrets file. This file looks like this:&lt;/p&gt;

&lt;p&gt;SOME_SECRET=poepoe&lt;br&gt;
OTHER_SECRET=tutu&lt;br&gt;
VERY_SECRET=lalala&lt;/p&gt;

&lt;p&gt;Because we set a &lt;code&gt;expire\_in&lt;/code&gt; value, gitlab will automatically remove the artifact after 30 minutes. If your CI process take longer to run, of course you can adjust this duration. With this feature you can somewhat control the risk of leaking secrets in the long run, but it is not technically a security measure!&lt;/p&gt;

&lt;p&gt;Then, in the following steps, you can simply use the .ci-secrets file that was just created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release:
  stage: deploy
  image: node
  before_script:
    # export the contents of the secrets file in your environment
    - export $(cat .ci-secrets | xargs)
    - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" &amp;gt;&amp;gt; ~/.npmrc
  script:
    - npm install -q
    - npm publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This step effectively publishes an image on a npm repository, so this secret contains a NPM_TOKEN with write access to a package— quite sensitive!&lt;/p&gt;

&lt;h3&gt;
  
  
  Worst case scenario
&lt;/h3&gt;

&lt;p&gt;Let’s consider a few &lt;em&gt;plausible&lt;/em&gt; worst case scenarios directly concerning your secrets. (I am not going to consider a scenario like “somebody got access to my gitlab runner instance and can do whatever they want because of the instance role”: this is a completely different security issue, not linked with exposing secrets, and should normally be taken care of at least with VPC and security group access rules.)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Somebody from your organisation that you absolutely trust gets full access to the CI configuration and somehow manages to output all your precious secret variables in clear text in the CI logs, making them visible to anyone else with read access. Shit happens!
Now one of your employees saw those, got terminated the following day, returns home and wants to hurt you badly. Since we have setup AWS Secrets Manager for auto-rotation of our keys every day, by the time they get home the token will already have been rotated. They try to use the NPM_TOKEN above, but get a 403 Forbidden error, and move on with their lives.&lt;/li&gt;
&lt;li&gt; Somebody outside of your organisation somehow got access to some very secret variable and you urgently need to replace it everywhere: simply run the rotation function once and go back to bed, you deserve it!&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;My take on this is that we should &lt;strong&gt;stop worrying about secrets&lt;/strong&gt; at once and just make them &lt;strong&gt;volatile&lt;/strong&gt;. Of course you shouldn’t put secrets in clear text in public repositories. But maybe you were drunk one night, tried to do something stupid at 3AM, forgot to update the .gitignore and published them in clear text. You are only human!&lt;/p&gt;

&lt;p&gt;What do you think?&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cryptography</category>
      <category>ci</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>Announcing CSML, a new open-source language dedicated to building powerful, enterprise-ready and interoperable chatbots</title>
      <dc:creator>Francois Falala-Sechet</dc:creator>
      <pubDate>Tue, 14 Jan 2020 19:40:54 +0000</pubDate>
      <link>https://forem.com/frsechet/announcing-csml-a-new-open-source-language-dedicated-to-building-powerful-enterprise-ready-and-interoperable-chatbots-cb6</link>
      <guid>https://forem.com/frsechet/announcing-csml-a-new-open-source-language-dedicated-to-building-powerful-enterprise-ready-and-interoperable-chatbots-cb6</guid>
      <description>&lt;p&gt;Chatbots are a powerful tool as a universal UX to solving automation issues at scale. Like the web before, followed by mobile applications, chatbots are very good at providing an easy-to-use interface for end users to effortlessly perform repetitive or complex actions in a natural interface.&lt;/p&gt;

&lt;p&gt;However, creating a scalable, enterprise-ready chatbot today is still unnecessarily complex. All chatbots in 2019 are created with one of only two methods: either by using any of the available free or inexpensive drag and drop graphical tools, which enables non-technical people to get started quickly, but scales very poorly, can not be versioned using standard tooling, and does not easily allow for exportation (strong vendor lock-in); or by using a generic programming language (javascript, PHP, python…), which lacks a common standard, requires a lot of unnecessary and repeated boilerplate to achieve even basic features like memory handling, and often induces high development costs and slow goto market.&lt;/p&gt;

&lt;p&gt;Market consolidation has already proven that Javascript has won the battle for the web, and most serious iOS applications today are written in Swift, while Java is used for Android applications. As most large companies worldwide are now involved in at least one conversational program, the underlying technology and tooling is outdated and due for a global standardisation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XrnKNpdh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1726/1%2AQoR3pppB9si6cGtX13GtzQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XrnKNpdh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1726/1%2AQoR3pppB9si6cGtX13GtzQ.png" alt="CSML logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introducing CSML, a new programming language for conversational design
&lt;/h1&gt;

&lt;p&gt;The &lt;a href="https://clevy.io"&gt;Clevy&lt;/a&gt; team is proud to release today a new solution to this long-standing problem in an open beta program: the &lt;a href="https://csml.dev"&gt;Conversational Standard Meta Language (CSML)&lt;/a&gt;, a common language for all chatbots.&lt;br&gt;
CSML’s objective is to make designing conversational experiences as intuitive as possible, drastically reducing the time and costs to create and deploy any chatbot at scale compared to all existing platforms and make it as easy as possible to connect any human with any machine.&lt;br&gt;
Written itself in Rust (a low-level, fast, memory-efficient and safe programming language), and fully Turing-complete, the CSML acts as a linguistic/syntactic abstraction layer, designed for humans who want to let other humans interact with any machine, in any setting. The syntax is designed to be learned in a matter of minutes, but also scales to any complexity of chatbot.&lt;/p&gt;

&lt;p&gt;CSML automatically does the heavy-lifting of all conversational concepts without any added complexity for the developer: memory, context, metadata, message formatting for the target channels, conversational logic, interoperability with third-party systems, API-agnostic integrations…&lt;/p&gt;

&lt;p&gt;The documentation of the language is publicly available on &lt;a href="https://docs.csml.dev"&gt;https://docs.csml.dev&lt;/a&gt;. We also provide a free, full-featured development studio (REPL) on &lt;a href="https://studio.csml.dev"&gt;https://studio.csml.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  All conversations start with a common language
&lt;/h1&gt;

&lt;p&gt;The principle used by CSML is to treat the entire conversation as a series of separate events, linked by the same conversational context, instead of request by request. Each event is a reaction — potentially cumulatively — to the event preceding it; a trigger for an event that must follow it; or totally independent.&lt;/p&gt;

&lt;p&gt;Nominally, the language itself is structured like the train of thought of a young child: everything is sequential and consists of descriptions. When asking a child about their day, they would usually answer somewhat like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I went to school, and then I had lunch, where I ate a steak and fries, then I played with my friend Kevin, and then we had ice cream.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This also means that after this last part, the conversation can end there, continue (“do you like ice cream?”) or a new subject can be picked up (“let’s go to the swimming pool now”). The sequential nature of a child’s reasoning makes a great comparison with how current chatbots can handle conversations: as a stream of individual bits of information, that can either be taken independently, or attached to other bits of information in a sequence.&lt;/p&gt;

&lt;p&gt;Either way, a child learns from their interactions. The more the bot chats with the user, the more it learns about the user and their preferences. Everything is memorized and saved in the bot’s memory about the user to be reused later, so that no information needs to be asked twice.&lt;/p&gt;

&lt;p&gt;We have worked for many months with computational linguists to transpose this inherent logic of natural conversations (and not just natural language) into the CSML. The result is an incredibly simple and natural framework to build just any chatbot about as easily as imagining a conversation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ALhYfSjz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3656/1%2AZyKW_krqnCtSbPp_I05SSQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ALhYfSjz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/3656/1%2AZyKW_krqnCtSbPp_I05SSQ.png" alt="A simple CSML chatbot flow to receive non-stop cat gifs 😸"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A simple CSML chatbot flow to receive non-stop cat gifs 😸&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Connecting humans with any machine
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://csml.dev"&gt;CSML&lt;/a&gt; is designed to be interoperable with any API-enabled third-party system. We understand that many of our users will want to run their own code directly inside the conversational engine, which is why we make it possible to integrate any language runtime (using any FaaS platform, in the cloud or on-premise) that enables chatbot developers to execute custom code in Javascript, Python, Go, Java, C#, or interconnect with their other systems natively from any CSML script.&lt;/p&gt;

&lt;p&gt;The immediate benefit is that CSML makes it possible to reuse existing code with no or very little modifications, or use built-in connectors with popular systems (ServiceNow, SAP, Microsoft Office 365, Zapier, Workday, Salesforce…) or communication channels (Messenger, Teams, Slack, Workplace, Discord, Skype, Hangouts, Alexa, Google Home, Twilio, websockets…).&lt;/p&gt;

&lt;h2&gt;
  
  
  CSML is open-source
&lt;/h2&gt;

&lt;p&gt;We are committed to helping the community benefit from this new programming language as much as possible.&lt;/p&gt;

&lt;p&gt;To ensure that any entity, company or person, involved in a conversational program, can commit to using this new game-changing language, we will be releasing the full CSML source code in the coming months.&lt;/p&gt;

&lt;p&gt;Chatbots are no more than natural interfaces to machines. As a language dedicated to creating chatbots easily, the CSML engine natively includes a modern package system, allowing developers to create, share, or download reusable bots or parts of bots. We will also be providing original content (bots, functions, integrations…) in the form of plugins, that can be added to any bot as installable dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSML is secure
&lt;/h2&gt;

&lt;p&gt;One of the side-effects of open-sourcing the CSML is that you can ensure that nobody can ever access your previous customer data by running it on your own servers. Some of our early users have been using the CSML in entirely private environments, sometimes even inaccessible from the internet; others prefer to run it in their own cloud environment: by default, CSML comes with easy-to-use bindings to AWS services like DynamoDB for storing the bot’s databases and AWS Lambda to execute code in any major programming language, in addition to SQLite and FaaS platforms like OpenFaas or FnProject for custom runtime executions. The CSML engine also comes with easy-to-deploy, stateless Docker containers.&lt;br&gt;
In addition to network separation and deployment flexibility, one of the leading design principles of CSML has been to ensure that all data is stored safely and securely: by default, all sensitive user data is stored encrypted using strong 256-bit AES encryption — the gold standard for military-grade encryption.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSML is scalable
&lt;/h2&gt;

&lt;p&gt;CSML is built with large enterprises in mind, who want to go beyond the proof-of-concept phase without inducing immense development and product management costs, while not limiting themselves in what they can or can not do with their chatbot. We want to empower developers to create what they want without technical barriers. We want to make sure that CSML chatbots can accept any number of conversations. We want to make CSML available in the cloud, on-premises, or even offline.&lt;/p&gt;

&lt;p&gt;The architecture of the CSML engine was designed to address all these constraints and handle any number of conversation, from a few to a few millions, without any restriction. Small bots can be created in minutes, then expanded to any arbitrary size of enterprise-grade bots later. With CSML, you are in control of your chatbot development project with very little boilerplate and a standardized lifecycle and development process, maximizing return on investment for your team.&lt;/p&gt;

&lt;h1&gt;
  
  
  Build your CSML chatbot in minutes!
&lt;/h1&gt;

&lt;p&gt;If you are intrigued by this new language, give it a try! You can setup your chatbot in minutes by signing up for free to the beta at &lt;a href="https://studio.csml.dev"&gt;https://studio.csml.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>chatbots</category>
      <category>programminglanguage</category>
      <category>ai</category>
      <category>rust</category>
    </item>
  </channel>
</rss>
