
Scala & Akka: How to secure your code.

Scala & Akka—how to secure your code. Scala is a modern, high-level programming language that combines object-oriented and functional programming. It is designed to be concise, scalable, and type-safe. It compiles to run on the Java Virtual Machine (JVM) for ease of use with existing Java libraries. Due to its expressive syntax and powerful features, Scala is very versatile, regardless of experience.
Scala and cybersecurity
Is Scala secure by default? Well, just like any programming language, Scala isn’t inherently secure. However, some of its features contribute to its safety when used correctly. Let’s check them out.
Type Safety
Scala’s static type system helps catch most common programming errors during compilation. This reduces the risk of runtime exceptions and security vulnerabilities.
Immutable Data Structures
Scala is very much about immutability, which is great because it can prevent accidental data modification and enhance security even further. Such data structures are less prone to race conditions and side effects.
Functional Programming
Scala has functional programming that promotes pure functions, referential transparency, and code free of side effects. This leads to a more predictable and secure application behavior.
Secure Scala code with Akka
What is Akka? It’s a powerful toolkit for building concurrent, distributed and fault-tolerant systems in Scala. Akka is definitely worth using – here’s why.
Akka Actor Model
Akka uses the actor model, which isolates components into lightweight, independent actors. Each actor processes messages sequentially, reducing the risk of shared-memory vulnerabilities.
import akka.actor.{Actor, ActorSystem, Props}
class MyActor extends Actor {
def receive: Receive = {
case message: String => println(s"Received: $message")
}
}
val system = ActorSystem("MySystem")
val myActor = system.actorOf(Props[MyActor], "myActor")
myActor ! "Hello, World!"Supervision
Akka’s supervision hierarchy allows actors to handle their failures gracefully. When an actor encounters an error, its supervisor can restart it or take other actions.
import akka.actor.{Actor, ActorSystem, Props, OneForOneStrategy}
import akka.actor.SupervisorStrategy._
class Supervisor extends Actor {
override val supervisorStrategy: OneForOneStrategy =
OneForOneStrategy(maxNrOfRetries = 3) {
case _: ArithmeticException => Resume
case _: NullPointerException => Restart
case _: Exception => Escalate
}
def receive: Receive = {
case props: Props => sender() ! context.actorOf(props)
}
}
val system = ActorSystem("SupervisionSystem")
val supervisor = system.actorOf(Props[Supervisor], "supervisor")Remoting and Clustering
Akka provides secure communication between distributed actors, and it can be configured with secure comms using TLS/SSL.
import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory
val config = ConfigFactory.parseString("""
akka {
actor.provider = remote
remote.netty.tcp.hostname = "127.0.0.1"
remote.netty.tcp.port = 2552
}
""")
val system = ActorSystem("ClusterSystem", config)
val remoteActor = system.actorOf(Props[MyActor], "remoteActor")Persistence
Akka Persistence ensures that the actor state is durable and can be recovered. This is crucial for the integrity and security of your data.
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorSystem, Behavior, PostStop}
object MyPersistentActor {
sealed trait Command
case class Event(data: String) extends Command
case class CommandReceived(data: String) extends Command
def apply(): Behavior[Command] = Behaviors.setup { context =>
context.log.info("MyPersistentActor started")
val initialState: List[String] = Nil
Behaviors.receiveMessage {
case CommandReceived(data) =>
context.log.info(s"Received: $data")
context.spawnAnonymous(PersistentActor(data))
Behaviors.same
} receiveSignal {
case (_, PostStop) =>
context.log.info("MyPersistentActor stopped")
Behaviors.same
}
}
}
object PersistentActor {
def apply(data: String): Behavior[Command] = Behaviors.receiveMessage {
case Event(eventData) =>
val newState = eventData :: Nil
// Add your Akka Persistence API to persist the newState, and adjust your application.conf
Behaviors.same
}
}
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem(MyPersistentActor(), "PersistenceSystem")
system ! MyPersistentActor.CommandReceived("Sample data")
}
}Further tweaks to securing Scala code with Akka
Whether you’re just setting up your Akka or already have an existing setup, continually refining your code for maximum security is a good practice.
Adding TLS to Remoting
If you’d like to expand on remoting and clustering with more security, you can configure TLS. First, ensure you have valid SSL certificates installed on all Akka Remote Hosts. When writing your own code, do not hardcode passwords and other sensitive data in the configuration file! Use environment variables instead, and keep them confidential.
akka.remote.artery {
transport = tls-tcp
ssl.config-ssl-engine {
key-store = "/path/to/mykeystore.jks"
trust-store = "/path/to/mytruststore.jks"
key-store-password = ${SSL_KEY_STORE_PASSWORD}
key-password = ${SSL_KEY_PASSWORD}
trust-store-password = ${SSL_TRUST_STORE_PASSWORD}
protocol = "TLSv1.2"
enabled-algorithms = [TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
}
}HTTPS support for Akka
If you’re serving HTTP API using Akka HTTP, you can increase its security by enabling HTTPS (TLS) as well. Remember to have a valid SSL certificate and replace the data with comments with your configuration.
import akka.http.scaladsl.{Http, HttpsConnectionContext}
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer
val httpsContext: HttpsConnectionContext = // SSL context here
val routes: Route = // Akka HTTP routes here
val bindingFuture = Http().bindAndHandle(routes, "localhost", 8443, connectionContext = httpsContext)Securing your Scala code with Akka: Closing notes
As you can see, despite being just another programming language, Scala has plenty of features that make it an attractive choice when building your apps. Paired with Akka, you can create robust and secure applications that can endure any strain on the system. There’s a good reason why tech giants such as Netflix, Twitter, Facebook, or even Google use Scala under the hood.
Remember that security isn’t something to be postponed and done later. If you adopt the security-first mindset, your application or your company will also be secured from headaches caused by data breaches or prolonged application unavailability to paying customers.
One last piece of parting advice: always validate your inputs, sanitize your data, and be on guard against injection attacks. Don’t forget to encrypt your communication while at it!
What about your experiences with securing Scala, whether by using Akka or with other methods? Let’s talk about the security of your code!




