diff --git a/conn.go b/conn.go
index 5fcc4727c..532a4b348 100644
--- a/conn.go
+++ b/conn.go
@@ -19,14 +19,7 @@ package main
 
 import (
 	"bytes"
-	"crypto"
-	"crypto/rsa"
-	"crypto/sha256"
-	"crypto/x509"
-	"encoding/hex"
 	"encoding/json"
-	"encoding/pem"
-	"errors"
 	"fmt"
 	"net/http"
 	"os"
@@ -114,7 +107,7 @@ func uploadHandler(c *gin.Context) {
 			return
 		}
 
-		err := verifyCommandLine(data.Commandline, data.Signature)
+		err := utilities.VerifyInput(data.Commandline, data.Signature)
 
 		if err != nil {
 			c.String(http.StatusBadRequest, "signature is invalid")
@@ -140,7 +133,11 @@ func uploadHandler(c *gin.Context) {
 	}
 
 	for _, extraFile := range data.ExtraFiles {
-		path := filepath.Join(tmpdir, extraFile.Filename)
+		path, err := utilities.SafeJoin(tmpdir, extraFile.Filename)
+		if err != nil {
+			c.String(http.StatusBadRequest, err.Error())
+			return
+		}
 		filePaths = append(filePaths, path)
 		log.Printf("Saving %s on %s", extraFile.Filename, path)
 
@@ -150,7 +147,7 @@ func uploadHandler(c *gin.Context) {
 			return
 		}
 
-		err := os.WriteFile(path, extraFile.Hex, 0644)
+		err = os.WriteFile(path, extraFile.Hex, 0644)
 		if err != nil {
 			c.String(http.StatusBadRequest, err.Error())
 			return
@@ -215,23 +212,6 @@ func send(args map[string]string) {
 	h.broadcastSys <- mapB
 }
 
-func verifyCommandLine(input string, signature string) error {
-	sign, _ := hex.DecodeString(signature)
-	block, _ := pem.Decode([]byte(*signatureKey))
-	if block == nil {
-		return errors.New("invalid key")
-	}
-	key, err := x509.ParsePKIXPublicKey(block.Bytes)
-	if err != nil {
-		return err
-	}
-	rsaKey := key.(*rsa.PublicKey)
-	h := sha256.New()
-	h.Write([]byte(input))
-	d := h.Sum(nil)
-	return rsa.VerifyPKCS1v15(rsaKey, crypto.SHA256, d, sign)
-}
-
 func wsHandler() *WsServer {
 	server, err := socketio.NewServer(nil)
 	if err != nil {
diff --git a/design/pkgs.go b/design/pkgs.go
index f47ca0fe0..300bc9058 100644
--- a/design/pkgs.go
+++ b/design/pkgs.go
@@ -110,20 +110,29 @@ var ToolPayload = Type("arduino.tool", func() {
 	TypeName("ToolPayload")
 
 	Attribute("name", String, "The name of the tool", func() {
-		Example("avrdude")
+		Example("bossac")
 	})
 	Attribute("version", String, "The version of the tool", func() {
-		Example("6.3.0-arduino9")
+		Example("1.7.0-arduino3")
 	})
 	Attribute("packager", String, "The packager of the tool", func() {
 		Example("arduino")
 	})
 
 	Attribute("url", String, `The url where the package can be found. Optional. 
-	If present checksum must also be present.`)
+	If present checksum must also be present.`, func() {
+		Example("http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz")
+	})
 
 	Attribute("checksum", String, `A checksum of the archive. Mandatory when url is present. 
-	This ensures that the package is downloaded correcly.`)
+	This ensures that the package is downloaded correcly.`, func() {
+		Example("SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100")
+	})
+
+	Attribute("signature", String, `The signature used to sign the url. Mandatory when url is present.
+	This ensure the security of the file downloaded`, func() {
+		Example("382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0")
+	})
 
 	Required("name", "version", "packager")
 })
diff --git a/gen/http/cli/arduino_create_agent/cli.go b/gen/http/cli/arduino_create_agent/cli.go
index 75ec883ef..d2153965b 100644
--- a/gen/http/cli/arduino_create_agent/cli.go
+++ b/gen/http/cli/arduino_create_agent/cli.go
@@ -297,11 +297,12 @@ Install implements install.
 
 Example:
     %[1]s tools install --body '{
-      "checksum": "Beatae dolor adipisci nulla et quam voluptas.",
-      "name": "avrdude",
+      "checksum": "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100",
+      "name": "bossac",
       "packager": "arduino",
-      "url": "Deserunt voluptatem impedit iusto libero.",
-      "version": "6.3.0-arduino9"
+      "signature": "382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0",
+      "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz",
+      "version": "1.7.0-arduino3"
    }'
 `, os.Args[0])
 }
@@ -317,8 +318,9 @@ Remove implements remove.
 
 Example:
     %[1]s tools remove --body '{
-      "checksum": "Ipsa minima quia.",
-      "url": "Expedita rem ipsum quasi harum nostrum."
-   }' --packager "arduino" --name "avrdude" --version "6.3.0-arduino9"
+      "checksum": "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100",
+      "signature": "382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0",
+      "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"
+   }' --packager "arduino" --name "bossac" --version "1.7.0-arduino3"
 `, os.Args[0])
 }
diff --git a/gen/http/openapi.json b/gen/http/openapi.json
index e6a796113..093633ef5 100644
--- a/gen/http/openapi.json
+++ b/gen/http/openapi.json
@@ -1 +1 @@
-{"swagger":"2.0","info":{"title":"Arduino Create Agent","description":"A companion of Arduino Create. \n\tAllows the website to perform operations on the user computer, \n\tsuch as detecting which boards are connected and upload sketches on them.","version":""},"host":"localhost:80","basePath":"/v2","consumes":["application/json","plain/text"],"produces":["application/json","application/xml","application/gob"],"paths":{"/pkgs/indexes":{"get":{"tags":["indexes"],"summary":"list indexes","operationId":"indexes#list","responses":{"200":{"description":"OK response.","schema":{"type":"array","items":{"type":"string","example":"Repudiandae dignissimos consectetur eos molestiae culpa soluta."}}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesListInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/indexes/add":{"post":{"tags":["indexes"],"summary":"add indexes","operationId":"indexes#add","parameters":[{"name":"AddRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/IndexesAddRequestBody","required":["url"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/IndexesAddResponseBody"}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesAddInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/indexes/delete":{"post":{"tags":["indexes"],"summary":"remove indexes","operationId":"indexes#remove","parameters":[{"name":"RemoveRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/IndexesRemoveRequestBody","required":["url"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/IndexesRemoveResponseBody"}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesRemoveInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/tools/available":{"get":{"tags":["tools"],"summary":"available tools","operationId":"tools#available","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsToolResponseCollection"}}},"schemes":["http"]}},"/pkgs/tools/installed":{"get":{"tags":["tools"],"summary":"installed tools","operationId":"tools#installed","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsToolResponseCollection"}}},"schemes":["http"]},"post":{"tags":["tools"],"summary":"install tools","operationId":"tools#install","parameters":[{"name":"InstallRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/ToolsInstallRequestBody","required":["name","version","packager"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsInstallResponseBody"}}},"schemes":["http"]}},"/pkgs/tools/installed/{packager}/{name}/{version}":{"delete":{"tags":["tools"],"summary":"remove tools","operationId":"tools#remove","parameters":[{"name":"packager","in":"path","description":"The packager of the tool","required":true,"type":"string"},{"name":"name","in":"path","description":"The name of the tool","required":true,"type":"string"},{"name":"version","in":"path","description":"The version of the tool","required":true,"type":"string"},{"name":"RemoveRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/ToolsRemoveRequestBody"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsRemoveResponseBody"}}},"schemes":["http"]}}},"definitions":{"IndexesAddInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":true},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":true},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":false}},"description":"url invalid (default view)","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":false,"timeout":false},"required":["name","id","message","temporary","timeout","fault"]},"IndexesAddRequestBody":{"title":"IndexesAddRequestBody","type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"IndexesAddResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"AddResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"IndexesListInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":true},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":false},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":false}},"description":"url invalid (default view)","example":{"fault":true,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":true,"timeout":true},"required":["name","id","message","temporary","timeout","fault"]},"IndexesRemoveInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":false},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":true},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":true}},"description":"url invalid (default view)","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":true,"timeout":false},"required":["name","id","message","temporary","timeout","fault"]},"IndexesRemoveRequestBody":{"title":"IndexesRemoveRequestBody","type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"IndexesRemoveResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"RemoveResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolResponse":{"title":"Mediatype identifier: application/vnd.arduino.tool; view=default","type":"object","properties":{"name":{"type":"string","description":"The name of the tool","example":"avrdude"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"version":{"type":"string","description":"The version of the tool","example":"6.3.0-arduino9"}},"description":"A tool is an executable program that can upload sketches. (default view)","example":{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},"required":["name","version","packager"]},"ToolsInstallRequestBody":{"title":"ToolsInstallRequestBody","type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"Totam cum inventore exercitationem in."},"name":{"type":"string","description":"The name of the tool","example":"avrdude"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"Totam vero ipsum corporis nihil voluptatem id."},"version":{"type":"string","description":"The version of the tool","example":"6.3.0-arduino9"}},"example":{"checksum":"Modi dolorem reprehenderit perspiciatis illo aspernatur.","name":"avrdude","packager":"arduino","url":"Officia optio inventore atque in voluptatibus qui.","version":"6.3.0-arduino9"},"required":["name","version","packager"]},"ToolsInstallResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"InstallResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolsRemoveRequestBody":{"title":"ToolsRemoveRequestBody","type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"Et qui id et cumque illo."},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"Officia maiores reiciendis est nemo."}},"example":{"checksum":"Corporis eum et numquam sapiente.","url":"Est voluptatem eos reprehenderit quo sint quod."}},"ToolsRemoveResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"RemoveResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolsToolResponseCollection":{"title":"Mediatype identifier: application/vnd.arduino.tool; type=collection; view=default","type":"array","items":{"$ref":"#/definitions/ToolResponse"},"description":"AvailableResponseBody is the result type for an array of ToolResponse (default view)","example":[{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"}]}}}
\ No newline at end of file
+{"swagger":"2.0","info":{"title":"Arduino Create Agent","description":"A companion of Arduino Create. \n\tAllows the website to perform operations on the user computer, \n\tsuch as detecting which boards are connected and upload sketches on them.","version":""},"host":"localhost:80","basePath":"/v2","consumes":["application/json","plain/text"],"produces":["application/json","application/xml","application/gob"],"paths":{"/pkgs/indexes":{"get":{"tags":["indexes"],"summary":"list indexes","operationId":"indexes#list","responses":{"200":{"description":"OK response.","schema":{"type":"array","items":{"type":"string","example":"Pariatur laudantium inventore qui."}}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesListInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/indexes/add":{"post":{"tags":["indexes"],"summary":"add indexes","operationId":"indexes#add","parameters":[{"name":"AddRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/IndexesAddRequestBody","required":["url"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/IndexesAddResponseBody"}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesAddInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/indexes/delete":{"post":{"tags":["indexes"],"summary":"remove indexes","operationId":"indexes#remove","parameters":[{"name":"RemoveRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/IndexesRemoveRequestBody","required":["url"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/IndexesRemoveResponseBody"}},"400":{"description":"Bad Request response.","schema":{"$ref":"#/definitions/IndexesRemoveInvalidURLResponseBody"}}},"schemes":["http"]}},"/pkgs/tools/available":{"get":{"tags":["tools"],"summary":"available tools","operationId":"tools#available","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsToolResponseCollection"}}},"schemes":["http"]}},"/pkgs/tools/installed":{"get":{"tags":["tools"],"summary":"installed tools","operationId":"tools#installed","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsToolResponseCollection"}}},"schemes":["http"]},"post":{"tags":["tools"],"summary":"install tools","operationId":"tools#install","parameters":[{"name":"InstallRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/ToolsInstallRequestBody","required":["name","version","packager"]}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsInstallResponseBody"}}},"schemes":["http"]}},"/pkgs/tools/installed/{packager}/{name}/{version}":{"delete":{"tags":["tools"],"summary":"remove tools","operationId":"tools#remove","parameters":[{"name":"packager","in":"path","description":"The packager of the tool","required":true,"type":"string"},{"name":"name","in":"path","description":"The name of the tool","required":true,"type":"string"},{"name":"version","in":"path","description":"The version of the tool","required":true,"type":"string"},{"name":"RemoveRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/ToolsRemoveRequestBody"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/ToolsRemoveResponseBody"}}},"schemes":["http"]}}},"definitions":{"IndexesAddInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":true},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":true},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":true}},"description":"url invalid (default view)","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":true,"timeout":false},"required":["name","id","message","temporary","timeout","fault"]},"IndexesAddRequestBody":{"title":"IndexesAddRequestBody","type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"IndexesAddResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"AddResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"IndexesListInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":false},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":false},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":true}},"description":"url invalid (default view)","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":false,"timeout":true},"required":["name","id","message","temporary","timeout","fault"]},"IndexesRemoveInvalidURLResponseBody":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":true},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":false},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":false}},"description":"url invalid (default view)","example":{"fault":true,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":true,"timeout":true},"required":["name","id","message","temporary","timeout","fault"]},"IndexesRemoveRequestBody":{"title":"IndexesRemoveRequestBody","type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"IndexesRemoveResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"RemoveResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolResponse":{"title":"Mediatype identifier: application/vnd.arduino.tool; view=default","type":"object","properties":{"name":{"type":"string","description":"The name of the tool","example":"bossac"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"version":{"type":"string","description":"The version of the tool","example":"1.7.0-arduino3"}},"description":"A tool is an executable program that can upload sketches. (default view)","example":{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},"required":["name","version","packager"]},"ToolsInstallRequestBody":{"title":"ToolsInstallRequestBody","type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"},"name":{"type":"string","description":"The name of the tool","example":"bossac"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"signature":{"type":"string","description":"The signature used to sign the url. Mandatory when url is present.\n\tThis ensure the security of the file downloaded","example":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"},"version":{"type":"string","description":"The version of the tool","example":"1.7.0-arduino3"}},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","name":"bossac","packager":"arduino","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz","version":"1.7.0-arduino3"},"required":["name","version","packager"]},"ToolsInstallResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"InstallResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolsRemoveRequestBody":{"title":"ToolsRemoveRequestBody","type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"},"signature":{"type":"string","description":"The signature used to sign the url. Mandatory when url is present.\n\tThis ensure the security of the file downloaded","example":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"}},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"}},"ToolsRemoveResponseBody":{"title":"Mediatype identifier: application/vnd.arduino.operation; view=default","type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"description":"RemoveResponseBody result type (default view)","example":{"status":"ok"},"required":["status"]},"ToolsToolResponseCollection":{"title":"Mediatype identifier: application/vnd.arduino.tool; type=collection; view=default","type":"array","items":{"$ref":"#/definitions/ToolResponse"},"description":"AvailableResponseBody is the result type for an array of ToolResponse (default view)","example":[{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"}]}}}
\ No newline at end of file
diff --git a/gen/http/openapi.yaml b/gen/http/openapi.yaml
index 4079b44c9..fd351cf28 100644
--- a/gen/http/openapi.yaml
+++ b/gen/http/openapi.yaml
@@ -26,7 +26,7 @@ paths:
                         type: array
                         items:
                             type: string
-                            example: Repudiandae dignissimos consectetur eos molestiae culpa soluta.
+                            example: Pariatur laudantium inventore qui.
                 "400":
                     description: Bad Request response.
                     schema:
@@ -193,14 +193,14 @@ definitions:
             timeout:
                 type: boolean
                 description: Is the error a timeout?
-                example: false
+                example: true
         description: url invalid (default view)
         example:
             fault: false
             id: 123abc
             message: parameter 'p' must be an integer
             name: bad_request
-            temporary: false
+            temporary: true
             timeout: false
         required:
             - name
@@ -241,7 +241,7 @@ definitions:
             fault:
                 type: boolean
                 description: Is the error a server-side fault?
-                example: true
+                example: false
             id:
                 type: string
                 description: ID is a unique identifier for this particular occurrence of the problem.
@@ -261,14 +261,14 @@ definitions:
             timeout:
                 type: boolean
                 description: Is the error a timeout?
-                example: false
+                example: true
         description: url invalid (default view)
         example:
-            fault: true
+            fault: false
             id: 123abc
             message: parameter 'p' must be an integer
             name: bad_request
-            temporary: true
+            temporary: false
             timeout: true
         required:
             - name
@@ -284,7 +284,7 @@ definitions:
             fault:
                 type: boolean
                 description: Is the error a server-side fault?
-                example: false
+                example: true
             id:
                 type: string
                 description: ID is a unique identifier for this particular occurrence of the problem.
@@ -300,19 +300,19 @@ definitions:
             temporary:
                 type: boolean
                 description: Is the error temporary?
-                example: true
+                example: false
             timeout:
                 type: boolean
                 description: Is the error a timeout?
-                example: true
+                example: false
         description: url invalid (default view)
         example:
-            fault: false
+            fault: true
             id: 123abc
             message: parameter 'p' must be an integer
             name: bad_request
             temporary: true
-            timeout: false
+            timeout: true
         required:
             - name
             - id
@@ -352,7 +352,7 @@ definitions:
             name:
                 type: string
                 description: The name of the tool
-                example: avrdude
+                example: bossac
             packager:
                 type: string
                 description: The packager of the tool
@@ -360,12 +360,12 @@ definitions:
             version:
                 type: string
                 description: The version of the tool
-                example: 6.3.0-arduino9
+                example: 1.7.0-arduino3
         description: A tool is an executable program that can upload sketches. (default view)
         example:
-            name: avrdude
+            name: bossac
             packager: arduino
-            version: 6.3.0-arduino9
+            version: 1.7.0-arduino3
         required:
             - name
             - version
@@ -377,29 +377,36 @@ definitions:
             checksum:
                 type: string
                 description: "A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly."
-                example: Totam cum inventore exercitationem in.
+                example: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
             name:
                 type: string
                 description: The name of the tool
-                example: avrdude
+                example: bossac
             packager:
                 type: string
                 description: The packager of the tool
                 example: arduino
+            signature:
+                type: string
+                description: |-
+                    The signature used to sign the url. Mandatory when url is present.
+                    	This ensure the security of the file downloaded
+                example: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
             url:
                 type: string
                 description: "The url where the package can be found. Optional. \n\tIf present checksum must also be present."
-                example: Totam vero ipsum corporis nihil voluptatem id.
+                example: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
             version:
                 type: string
                 description: The version of the tool
-                example: 6.3.0-arduino9
+                example: 1.7.0-arduino3
         example:
-            checksum: Modi dolorem reprehenderit perspiciatis illo aspernatur.
-            name: avrdude
+            checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+            name: bossac
             packager: arduino
-            url: Officia optio inventore atque in voluptatibus qui.
-            version: 6.3.0-arduino9
+            signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+            url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
+            version: 1.7.0-arduino3
         required:
             - name
             - version
@@ -424,14 +431,21 @@ definitions:
             checksum:
                 type: string
                 description: "A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly."
-                example: Et qui id et cumque illo.
+                example: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+            signature:
+                type: string
+                description: |-
+                    The signature used to sign the url. Mandatory when url is present.
+                    	This ensure the security of the file downloaded
+                example: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
             url:
                 type: string
                 description: "The url where the package can be found. Optional. \n\tIf present checksum must also be present."
-                example: Officia maiores reiciendis est nemo.
+                example: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
         example:
-            checksum: Corporis eum et numquam sapiente.
-            url: Est voluptatem eos reprehenderit quo sint quod.
+            checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+            signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+            url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
     ToolsRemoveResponseBody:
         title: 'Mediatype identifier: application/vnd.arduino.operation; view=default'
         type: object
@@ -452,9 +466,15 @@ definitions:
             $ref: '#/definitions/ToolResponse'
         description: AvailableResponseBody is the result type for an array of ToolResponse (default view)
         example:
-            - name: avrdude
+            - name: bossac
+              packager: arduino
+              version: 1.7.0-arduino3
+            - name: bossac
+              packager: arduino
+              version: 1.7.0-arduino3
+            - name: bossac
               packager: arduino
-              version: 6.3.0-arduino9
-            - name: avrdude
+              version: 1.7.0-arduino3
+            - name: bossac
               packager: arduino
-              version: 6.3.0-arduino9
+              version: 1.7.0-arduino3
diff --git a/gen/http/openapi3.json b/gen/http/openapi3.json
index 200367bbf..fb26d68bf 100644
--- a/gen/http/openapi3.json
+++ b/gen/http/openapi3.json
@@ -1 +1 @@
-{"openapi":"3.0.3","info":{"title":"Arduino Create Agent","description":"A companion of Arduino Create. \n\tAllows the website to perform operations on the user computer, \n\tsuch as detecting which boards are connected and upload sketches on them.","version":"1.0"},"servers":[{"url":"http://localhost:80","description":"Default server for arduino-create-agent"}],"paths":{"/v2/pkgs/indexes":{"get":{"tags":["indexes"],"summary":"list indexes","operationId":"indexes#list","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","example":"Eveniet iure nihil optio qui."},"example":["Et perferendis eveniet voluptas.","Ut aut illum eaque dolor magni.","Amet illo veritatis laudantium optio."]},"example":["Illo enim vero qui rerum ut inventore.","Dolorem nihil autem minima alias."]}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/indexes/add":{"post":{"tags":["indexes"],"summary":"add indexes","operationId":"indexes#add","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestBody"},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/indexes/delete":{"post":{"tags":["indexes"],"summary":"remove indexes","operationId":"indexes#remove","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestBody"},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/tools/available":{"get":{"tags":["tools"],"summary":"available tools","operationId":"tools#available","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolCollection"},"example":[{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"}]}}}}}},"/v2/pkgs/tools/installed":{"get":{"tags":["tools"],"summary":"installed tools","operationId":"tools#installed","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolCollection"},"example":[{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"}]}}}}},"post":{"tags":["tools"],"summary":"install tools","operationId":"tools#install","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallRequestBody"},"example":{"checksum":"Beatae dolor adipisci nulla et quam voluptas.","name":"avrdude","packager":"arduino","url":"Deserunt voluptatem impedit iusto libero.","version":"6.3.0-arduino9"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}}}}},"/v2/pkgs/tools/installed/{packager}/{name}/{version}":{"delete":{"tags":["tools"],"summary":"remove tools","operationId":"tools#remove","parameters":[{"name":"packager","in":"path","description":"The packager of the tool","required":true,"schema":{"type":"string","description":"The packager of the tool","example":"arduino"},"example":"arduino"},{"name":"name","in":"path","description":"The name of the tool","required":true,"schema":{"type":"string","description":"The name of the tool","example":"avrdude"},"example":"avrdude"},{"name":"version","in":"path","description":"The version of the tool","required":true,"schema":{"type":"string","description":"The version of the tool","example":"6.3.0-arduino9"},"example":"6.3.0-arduino9"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveRequestBody"},"example":{"checksum":"Ipsa minima quia.","url":"Expedita rem ipsum quasi harum nostrum."}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}}}}}},"components":{"schemas":{"AddRequestBody":{"type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"ArduinoTool":{"type":"object","properties":{"name":{"type":"string","description":"The name of the tool","example":"avrdude"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"version":{"type":"string","description":"The version of the tool","example":"6.3.0-arduino9"}},"description":"A tool is an executable program that can upload sketches.","example":{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},"required":["name","version","packager"]},"Error":{"type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":false},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":false},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":false}},"description":"url invalid","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":false,"timeout":true},"required":["name","id","message","temporary","timeout","fault"]},"InstallRequestBody":{"type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"Sint odio sed consequatur numquam."},"name":{"type":"string","description":"The name of the tool","example":"avrdude"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"Et quo doloremque sapiente atque."},"version":{"type":"string","description":"The version of the tool","example":"6.3.0-arduino9"}},"example":{"checksum":"Mollitia commodi sunt.","name":"avrdude","packager":"arduino","url":"Quae reprehenderit provident provident debitis illo.","version":"6.3.0-arduino9"},"required":["name","version","packager"]},"Operation":{"type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"example":{"status":"ok"},"required":["status"]},"RemoveRequestBody":{"type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"Ea culpa."},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"Odit officiis illo qui quia provident illo."}},"example":{"checksum":"Rerum eum esse corporis ex.","url":"Molestiae dolor quaerat enim."}},"ToolCollection":{"type":"array","items":{"$ref":"#/components/schemas/ArduinoTool"},"example":[{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"},{"name":"avrdude","packager":"arduino","version":"6.3.0-arduino9"}]}}},"tags":[{"name":"indexes","description":"The indexes service manages the package_index files"},{"name":"tools","description":"The tools service manages the available and installed tools"}]}
\ No newline at end of file
+{"openapi":"3.0.3","info":{"title":"Arduino Create Agent","description":"A companion of Arduino Create. \n\tAllows the website to perform operations on the user computer, \n\tsuch as detecting which boards are connected and upload sketches on them.","version":"1.0"},"servers":[{"url":"http://localhost:80","description":"Default server for arduino-create-agent"}],"paths":{"/v2/pkgs/indexes":{"get":{"tags":["indexes"],"summary":"list indexes","operationId":"indexes#list","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"array","items":{"type":"string","example":"Rerum et soluta laudantium."},"example":["Et deserunt.","Impedit iusto libero explicabo.","Dolor adipisci nulla.","Quam voluptas voluptates expedita rem ipsum."]},"example":["Dignissimos consectetur eos molestiae culpa soluta deserunt.","Nobis sint dolorem unde.","Quia doloremque.","Atque iusto tempore sit quod dolor repellat."]}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/indexes/add":{"post":{"tags":["indexes"],"summary":"add indexes","operationId":"indexes#add","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestBody"},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/indexes/delete":{"post":{"tags":["indexes"],"summary":"remove indexes","operationId":"indexes#remove","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestBody"},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}},"400":{"description":"invalid_url: url invalid","content":{"application/vnd.goa.error":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v2/pkgs/tools/available":{"get":{"tags":["tools"],"summary":"available tools","operationId":"tools#available","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolCollection"},"example":[{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"}]}}}}}},"/v2/pkgs/tools/installed":{"get":{"tags":["tools"],"summary":"installed tools","operationId":"tools#installed","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolCollection"},"example":[{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"}]}}}}},"post":{"tags":["tools"],"summary":"install tools","operationId":"tools#install","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallRequestBody"},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","name":"bossac","packager":"arduino","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz","version":"1.7.0-arduino3"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}}}}},"/v2/pkgs/tools/installed/{packager}/{name}/{version}":{"delete":{"tags":["tools"],"summary":"remove tools","operationId":"tools#remove","parameters":[{"name":"packager","in":"path","description":"The packager of the tool","required":true,"schema":{"type":"string","description":"The packager of the tool","example":"arduino"},"example":"arduino"},{"name":"name","in":"path","description":"The name of the tool","required":true,"schema":{"type":"string","description":"The name of the tool","example":"bossac"},"example":"bossac"},{"name":"version","in":"path","description":"The version of the tool","required":true,"schema":{"type":"string","description":"The version of the tool","example":"1.7.0-arduino3"},"example":"1.7.0-arduino3"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveRequestBody"},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Operation"},"example":{"status":"ok"}}}}}}}},"components":{"schemas":{"AddRequestBody":{"type":"object","properties":{"url":{"type":"string","description":"The url of the index file","example":"https://downloads.arduino.cc/packages/package_index.json"}},"example":{"url":"https://downloads.arduino.cc/packages/package_index.json"},"required":["url"]},"ArduinoTool":{"type":"object","properties":{"name":{"type":"string","description":"The name of the tool","example":"bossac"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"version":{"type":"string","description":"The version of the tool","example":"1.7.0-arduino3"}},"description":"A tool is an executable program that can upload sketches.","example":{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},"required":["name","version","packager"]},"Error":{"type":"object","properties":{"fault":{"type":"boolean","description":"Is the error a server-side fault?","example":false},"id":{"type":"string","description":"ID is a unique identifier for this particular occurrence of the problem.","example":"123abc"},"message":{"type":"string","description":"Message is a human-readable explanation specific to this occurrence of the problem.","example":"parameter 'p' must be an integer"},"name":{"type":"string","description":"Name is the name of this class of errors.","example":"bad_request"},"temporary":{"type":"boolean","description":"Is the error temporary?","example":true},"timeout":{"type":"boolean","description":"Is the error a timeout?","example":false}},"description":"url invalid","example":{"fault":false,"id":"123abc","message":"parameter 'p' must be an integer","name":"bad_request","temporary":true,"timeout":false},"required":["name","id","message","temporary","timeout","fault"]},"InstallRequestBody":{"type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"},"name":{"type":"string","description":"The name of the tool","example":"bossac"},"packager":{"type":"string","description":"The packager of the tool","example":"arduino"},"signature":{"type":"string","description":"The signature used to sign the url. Mandatory when url is present.\n\tThis ensure the security of the file downloaded","example":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"},"version":{"type":"string","description":"The version of the tool","example":"1.7.0-arduino3"}},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","name":"bossac","packager":"arduino","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz","version":"1.7.0-arduino3"},"required":["name","version","packager"]},"Operation":{"type":"object","properties":{"status":{"type":"string","description":"The status of the operation","example":"ok"}},"example":{"status":"ok"},"required":["status"]},"RemoveRequestBody":{"type":"object","properties":{"checksum":{"type":"string","description":"A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly.","example":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"},"signature":{"type":"string","description":"The signature used to sign the url. Mandatory when url is present.\n\tThis ensure the security of the file downloaded","example":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0"},"url":{"type":"string","description":"The url where the package can be found. Optional. \n\tIf present checksum must also be present.","example":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"}},"example":{"checksum":"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100","signature":"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0","url":"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"}},"ToolCollection":{"type":"array","items":{"$ref":"#/components/schemas/ArduinoTool"},"example":[{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"},{"name":"bossac","packager":"arduino","version":"1.7.0-arduino3"}]}}},"tags":[{"name":"indexes","description":"The indexes service manages the package_index files"},{"name":"tools","description":"The tools service manages the available and installed tools"}]}
\ No newline at end of file
diff --git a/gen/http/openapi3.yaml b/gen/http/openapi3.yaml
index 84ccfb1a9..8608590fe 100644
--- a/gen/http/openapi3.yaml
+++ b/gen/http/openapi3.yaml
@@ -22,14 +22,17 @@ paths:
                                 type: array
                                 items:
                                     type: string
-                                    example: Eveniet iure nihil optio qui.
+                                    example: Rerum et soluta laudantium.
                                 example:
-                                    - Et perferendis eveniet voluptas.
-                                    - Ut aut illum eaque dolor magni.
-                                    - Amet illo veritatis laudantium optio.
+                                    - Et deserunt.
+                                    - Impedit iusto libero explicabo.
+                                    - Dolor adipisci nulla.
+                                    - Quam voluptas voluptates expedita rem ipsum.
                             example:
-                                - Illo enim vero qui rerum ut inventore.
-                                - Dolorem nihil autem minima alias.
+                                - Dignissimos consectetur eos molestiae culpa soluta deserunt.
+                                - Nobis sint dolorem unde.
+                                - Quia doloremque.
+                                - Atque iusto tempore sit quod dolor repellat.
                 "400":
                     description: 'invalid_url: url invalid'
                     content:
@@ -108,15 +111,15 @@ paths:
                             schema:
                                 $ref: '#/components/schemas/ToolCollection'
                             example:
-                                - name: avrdude
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
-                                - name: avrdude
+                                  version: 1.7.0-arduino3
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
-                                - name: avrdude
+                                  version: 1.7.0-arduino3
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
+                                  version: 1.7.0-arduino3
     /v2/pkgs/tools/installed:
         get:
             tags:
@@ -131,15 +134,15 @@ paths:
                             schema:
                                 $ref: '#/components/schemas/ToolCollection'
                             example:
-                                - name: avrdude
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
-                                - name: avrdude
+                                  version: 1.7.0-arduino3
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
-                                - name: avrdude
+                                  version: 1.7.0-arduino3
+                                - name: bossac
                                   packager: arduino
-                                  version: 6.3.0-arduino9
+                                  version: 1.7.0-arduino3
         post:
             tags:
                 - tools
@@ -152,11 +155,12 @@ paths:
                         schema:
                             $ref: '#/components/schemas/InstallRequestBody'
                         example:
-                            checksum: Beatae dolor adipisci nulla et quam voluptas.
-                            name: avrdude
+                            checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+                            name: bossac
                             packager: arduino
-                            url: Deserunt voluptatem impedit iusto libero.
-                            version: 6.3.0-arduino9
+                            signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+                            url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
+                            version: 1.7.0-arduino3
             responses:
                 "200":
                     description: OK response.
@@ -189,8 +193,8 @@ paths:
                   schema:
                     type: string
                     description: The name of the tool
-                    example: avrdude
-                  example: avrdude
+                    example: bossac
+                  example: bossac
                 - name: version
                   in: path
                   description: The version of the tool
@@ -198,8 +202,8 @@ paths:
                   schema:
                     type: string
                     description: The version of the tool
-                    example: 6.3.0-arduino9
-                  example: 6.3.0-arduino9
+                    example: 1.7.0-arduino3
+                  example: 1.7.0-arduino3
             requestBody:
                 required: true
                 content:
@@ -207,8 +211,9 @@ paths:
                         schema:
                             $ref: '#/components/schemas/RemoveRequestBody'
                         example:
-                            checksum: Ipsa minima quia.
-                            url: Expedita rem ipsum quasi harum nostrum.
+                            checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+                            signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+                            url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
             responses:
                 "200":
                     description: OK response.
@@ -237,7 +242,7 @@ components:
                 name:
                     type: string
                     description: The name of the tool
-                    example: avrdude
+                    example: bossac
                 packager:
                     type: string
                     description: The packager of the tool
@@ -245,12 +250,12 @@ components:
                 version:
                     type: string
                     description: The version of the tool
-                    example: 6.3.0-arduino9
+                    example: 1.7.0-arduino3
             description: A tool is an executable program that can upload sketches.
             example:
-                name: avrdude
+                name: bossac
                 packager: arduino
-                version: 6.3.0-arduino9
+                version: 1.7.0-arduino3
             required:
                 - name
                 - version
@@ -277,7 +282,7 @@ components:
                 temporary:
                     type: boolean
                     description: Is the error temporary?
-                    example: false
+                    example: true
                 timeout:
                     type: boolean
                     description: Is the error a timeout?
@@ -288,8 +293,8 @@ components:
                 id: 123abc
                 message: parameter 'p' must be an integer
                 name: bad_request
-                temporary: false
-                timeout: true
+                temporary: true
+                timeout: false
             required:
                 - name
                 - id
@@ -303,29 +308,36 @@ components:
                 checksum:
                     type: string
                     description: "A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly."
-                    example: Sint odio sed consequatur numquam.
+                    example: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
                 name:
                     type: string
                     description: The name of the tool
-                    example: avrdude
+                    example: bossac
                 packager:
                     type: string
                     description: The packager of the tool
                     example: arduino
+                signature:
+                    type: string
+                    description: |-
+                        The signature used to sign the url. Mandatory when url is present.
+                        	This ensure the security of the file downloaded
+                    example: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
                 url:
                     type: string
                     description: "The url where the package can be found. Optional. \n\tIf present checksum must also be present."
-                    example: Et quo doloremque sapiente atque.
+                    example: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
                 version:
                     type: string
                     description: The version of the tool
-                    example: 6.3.0-arduino9
+                    example: 1.7.0-arduino3
             example:
-                checksum: Mollitia commodi sunt.
-                name: avrdude
+                checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+                name: bossac
                 packager: arduino
-                url: Quae reprehenderit provident provident debitis illo.
-                version: 6.3.0-arduino9
+                signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+                url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
+                version: 1.7.0-arduino3
             required:
                 - name
                 - version
@@ -347,31 +359,35 @@ components:
                 checksum:
                     type: string
                     description: "A checksum of the archive. Mandatory when url is present. \n\tThis ensures that the package is downloaded correcly."
-                    example: Ea culpa.
+                    example: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+                signature:
+                    type: string
+                    description: |-
+                        The signature used to sign the url. Mandatory when url is present.
+                        	This ensure the security of the file downloaded
+                    example: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
                 url:
                     type: string
                     description: "The url where the package can be found. Optional. \n\tIf present checksum must also be present."
-                    example: Odit officiis illo qui quia provident illo.
+                    example: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
             example:
-                checksum: Rerum eum esse corporis ex.
-                url: Molestiae dolor quaerat enim.
+                checksum: SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100
+                signature: 382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0
+                url: http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz
         ToolCollection:
             type: array
             items:
                 $ref: '#/components/schemas/ArduinoTool'
             example:
-                - name: avrdude
-                  packager: arduino
-                  version: 6.3.0-arduino9
-                - name: avrdude
+                - name: bossac
                   packager: arduino
-                  version: 6.3.0-arduino9
-                - name: avrdude
+                  version: 1.7.0-arduino3
+                - name: bossac
                   packager: arduino
-                  version: 6.3.0-arduino9
-                - name: avrdude
+                  version: 1.7.0-arduino3
+                - name: bossac
                   packager: arduino
-                  version: 6.3.0-arduino9
+                  version: 1.7.0-arduino3
 tags:
     - name: indexes
       description: The indexes service manages the package_index files
diff --git a/gen/http/tools/client/cli.go b/gen/http/tools/client/cli.go
index c6b125ff9..cfeb0b9fa 100644
--- a/gen/http/tools/client/cli.go
+++ b/gen/http/tools/client/cli.go
@@ -22,15 +22,16 @@ func BuildInstallPayload(toolsInstallBody string) (*tools.ToolPayload, error) {
 	{
 		err = json.Unmarshal([]byte(toolsInstallBody), &body)
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"checksum\": \"Beatae dolor adipisci nulla et quam voluptas.\",\n      \"name\": \"avrdude\",\n      \"packager\": \"arduino\",\n      \"url\": \"Deserunt voluptatem impedit iusto libero.\",\n      \"version\": \"6.3.0-arduino9\"\n   }'")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"checksum\": \"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100\",\n      \"name\": \"bossac\",\n      \"packager\": \"arduino\",\n      \"signature\": \"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0\",\n      \"url\": \"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz\",\n      \"version\": \"1.7.0-arduino3\"\n   }'")
 		}
 	}
 	v := &tools.ToolPayload{
-		Name:     body.Name,
-		Version:  body.Version,
-		Packager: body.Packager,
-		URL:      body.URL,
-		Checksum: body.Checksum,
+		Name:      body.Name,
+		Version:   body.Version,
+		Packager:  body.Packager,
+		URL:       body.URL,
+		Checksum:  body.Checksum,
+		Signature: body.Signature,
 	}
 
 	return v, nil
@@ -44,7 +45,7 @@ func BuildRemovePayload(toolsRemoveBody string, toolsRemovePackager string, tool
 	{
 		err = json.Unmarshal([]byte(toolsRemoveBody), &body)
 		if err != nil {
-			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"checksum\": \"Ipsa minima quia.\",\n      \"url\": \"Expedita rem ipsum quasi harum nostrum.\"\n   }'")
+			return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n      \"checksum\": \"SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100\",\n      \"signature\": \"382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0\",\n      \"url\": \"http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz\"\n   }'")
 		}
 	}
 	var packager string
@@ -60,8 +61,9 @@ func BuildRemovePayload(toolsRemoveBody string, toolsRemovePackager string, tool
 		version = toolsRemoveVersion
 	}
 	v := &tools.ToolPayload{
-		URL:      body.URL,
-		Checksum: body.Checksum,
+		URL:       body.URL,
+		Checksum:  body.Checksum,
+		Signature: body.Signature,
 	}
 	v.Packager = packager
 	v.Name = name
diff --git a/gen/http/tools/client/types.go b/gen/http/tools/client/types.go
index 0b2a81488..77a8dc8a2 100644
--- a/gen/http/tools/client/types.go
+++ b/gen/http/tools/client/types.go
@@ -28,6 +28,9 @@ type InstallRequestBody struct {
 	// A checksum of the archive. Mandatory when url is present.
 	// This ensures that the package is downloaded correcly.
 	Checksum *string `form:"checksum,omitempty" json:"checksum,omitempty" xml:"checksum,omitempty"`
+	// The signature used to sign the url. Mandatory when url is present.
+	// This ensure the security of the file downloaded
+	Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"`
 }
 
 // RemoveRequestBody is the type of the "tools" service "remove" endpoint HTTP
@@ -39,6 +42,9 @@ type RemoveRequestBody struct {
 	// A checksum of the archive. Mandatory when url is present.
 	// This ensures that the package is downloaded correcly.
 	Checksum *string `form:"checksum,omitempty" json:"checksum,omitempty" xml:"checksum,omitempty"`
+	// The signature used to sign the url. Mandatory when url is present.
+	// This ensure the security of the file downloaded
+	Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"`
 }
 
 // AvailableResponseBody is the type of the "tools" service "available"
@@ -77,11 +83,12 @@ type ToolResponse struct {
 // "install" endpoint of the "tools" service.
 func NewInstallRequestBody(p *tools.ToolPayload) *InstallRequestBody {
 	body := &InstallRequestBody{
-		Name:     p.Name,
-		Version:  p.Version,
-		Packager: p.Packager,
-		URL:      p.URL,
-		Checksum: p.Checksum,
+		Name:      p.Name,
+		Version:   p.Version,
+		Packager:  p.Packager,
+		URL:       p.URL,
+		Checksum:  p.Checksum,
+		Signature: p.Signature,
 	}
 	return body
 }
@@ -90,8 +97,9 @@ func NewInstallRequestBody(p *tools.ToolPayload) *InstallRequestBody {
 // "remove" endpoint of the "tools" service.
 func NewRemoveRequestBody(p *tools.ToolPayload) *RemoveRequestBody {
 	body := &RemoveRequestBody{
-		URL:      p.URL,
-		Checksum: p.Checksum,
+		URL:       p.URL,
+		Checksum:  p.Checksum,
+		Signature: p.Signature,
 	}
 	return body
 }
diff --git a/gen/http/tools/server/types.go b/gen/http/tools/server/types.go
index 6aaeb823f..d9b05d7a4 100644
--- a/gen/http/tools/server/types.go
+++ b/gen/http/tools/server/types.go
@@ -28,6 +28,9 @@ type InstallRequestBody struct {
 	// A checksum of the archive. Mandatory when url is present.
 	// This ensures that the package is downloaded correcly.
 	Checksum *string `form:"checksum,omitempty" json:"checksum,omitempty" xml:"checksum,omitempty"`
+	// The signature used to sign the url. Mandatory when url is present.
+	// This ensure the security of the file downloaded
+	Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"`
 }
 
 // RemoveRequestBody is the type of the "tools" service "remove" endpoint HTTP
@@ -39,6 +42,9 @@ type RemoveRequestBody struct {
 	// A checksum of the archive. Mandatory when url is present.
 	// This ensures that the package is downloaded correcly.
 	Checksum *string `form:"checksum,omitempty" json:"checksum,omitempty" xml:"checksum,omitempty"`
+	// The signature used to sign the url. Mandatory when url is present.
+	// This ensure the security of the file downloaded
+	Signature *string `form:"signature,omitempty" json:"signature,omitempty" xml:"signature,omitempty"`
 }
 
 // ToolResponseCollection is the type of the "tools" service "available"
@@ -100,11 +106,12 @@ func NewRemoveResponseBody(res *toolsviews.OperationView) *RemoveResponseBody {
 // NewInstallToolPayload builds a tools service install endpoint payload.
 func NewInstallToolPayload(body *InstallRequestBody) *tools.ToolPayload {
 	v := &tools.ToolPayload{
-		Name:     *body.Name,
-		Version:  *body.Version,
-		Packager: *body.Packager,
-		URL:      body.URL,
-		Checksum: body.Checksum,
+		Name:      *body.Name,
+		Version:   *body.Version,
+		Packager:  *body.Packager,
+		URL:       body.URL,
+		Checksum:  body.Checksum,
+		Signature: body.Signature,
 	}
 
 	return v
@@ -113,8 +120,9 @@ func NewInstallToolPayload(body *InstallRequestBody) *tools.ToolPayload {
 // NewRemoveToolPayload builds a tools service remove endpoint payload.
 func NewRemoveToolPayload(body *RemoveRequestBody, packager string, name string, version string) *tools.ToolPayload {
 	v := &tools.ToolPayload{
-		URL:      body.URL,
-		Checksum: body.Checksum,
+		URL:       body.URL,
+		Checksum:  body.Checksum,
+		Signature: body.Signature,
 	}
 	v.Packager = packager
 	v.Name = name
diff --git a/gen/tools/service.go b/gen/tools/service.go
index 783204c4f..63510ecc0 100644
--- a/gen/tools/service.go
+++ b/gen/tools/service.go
@@ -69,6 +69,9 @@ type ToolPayload struct {
 	// A checksum of the archive. Mandatory when url is present.
 	// This ensures that the package is downloaded correcly.
 	Checksum *string
+	// The signature used to sign the url. Mandatory when url is present.
+	// This ensure the security of the file downloaded
+	Signature *string
 }
 
 // MakeNotFound builds a goa.ServiceError from an error.
diff --git a/globals/globals.go b/globals/globals.go
new file mode 100644
index 000000000..d7cb09a17
--- /dev/null
+++ b/globals/globals.go
@@ -0,0 +1,22 @@
+// Copyright 2022 Arduino SA
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+package globals
+
+// DefaultIndexURL is the default index url
+var (
+	// SignatureKey is the public key used to verify commands and url sent by the builder
+	SignatureKey = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF\nIE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1\nZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1\npFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z\nCeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn\n2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9\ntwIDAQAB\n-----END PUBLIC KEY-----"
+)
diff --git a/main.go b/main.go
index 9f021af27..a73b2c558 100755
--- a/main.go
+++ b/main.go
@@ -34,6 +34,7 @@ import (
 	cors "github.com/andela/gin-cors"
 	cert "github.com/arduino/arduino-create-agent/certificates"
 	"github.com/arduino/arduino-create-agent/config"
+	"github.com/arduino/arduino-create-agent/globals"
 	"github.com/arduino/arduino-create-agent/systray"
 	"github.com/arduino/arduino-create-agent/tools"
 	"github.com/arduino/arduino-create-agent/updater"
@@ -78,7 +79,7 @@ var (
 	logDump        = iniConf.String("log", "off", "off = (default)")
 	origins        = iniConf.String("origins", "", "Allowed origin list for CORS")
 	regExpFilter   = iniConf.String("regex", "usb|acm|com", "Regular expression to filter serial port list")
-	signatureKey   = iniConf.String("signatureKey", "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF\nIE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1\nZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1\npFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z\nCeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn\n2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9\ntwIDAQAB\n-----END PUBLIC KEY-----", "Pem-encoded public key to verify signed commandlines")
+	signatureKey   = iniConf.String("signatureKey", globals.SignatureKey, "Pem-encoded public key to verify signed commandlines")
 	updateURL      = iniConf.String("updateUrl", "", "")
 	verbose        = iniConf.Bool("v", true, "show debug logging")
 	crashreport    = iniConf.Bool("crashreport", false, "enable crashreport logging")
diff --git a/main_test.go b/main_test.go
index 238ae2a2d..658094ab7 100644
--- a/main_test.go
+++ b/main_test.go
@@ -20,6 +20,7 @@ import (
 	"crypto/x509"
 	"encoding/json"
 	"encoding/pem"
+	"fmt"
 	"io"
 	"net/http"
 	"net/http/httptest"
@@ -28,6 +29,7 @@ import (
 
 	"github.com/arduino/arduino-create-agent/config"
 	"github.com/arduino/arduino-create-agent/gen/tools"
+	"github.com/arduino/arduino-create-agent/upload"
 	v2 "github.com/arduino/arduino-create-agent/v2"
 	"github.com/gin-gonic/gin"
 	"github.com/stretchr/testify/require"
@@ -48,34 +50,103 @@ func TestValidSignatureKey(t *testing.T) {
 	require.NotNil(t, key)
 }
 
-func TestInstallToolDifferentContentType(t *testing.T) {
+func TestInstallToolV2(t *testing.T) {
 	r := gin.New()
 	goa := v2.Server(config.GetDataDir().String())
 	r.Any("/v2/*path", gin.WrapH(goa))
 	ts := httptest.NewServer(r)
 
-	URL := "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"
-	Checksum := "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"
-	request := tools.ToolPayload{
+	type test struct {
+		request      tools.ToolPayload
+		responseCode int
+		responseBody string
+	}
+
+	BossacURL := "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz"
+	BossacChecksum := "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100"
+	BossacSignature := "382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0"
+	bossacInstallURLOK := tools.ToolPayload{
+		Name:      "bossac",
+		Version:   "1.7.0-arduino3",
+		Packager:  "arduino",
+		URL:       &BossacURL,
+		Checksum:  &BossacChecksum,
+		Signature: &BossacSignature,
+	}
+
+	WrongSignature := "wr0ngs1gn4tur3"
+	bossacInstallWrongSig := tools.ToolPayload{
+		Name:      "bossac",
+		Version:   "1.7.0-arduino3",
+		Packager:  "arduino",
+		URL:       &BossacURL,
+		Checksum:  &BossacChecksum,
+		Signature: &WrongSignature,
+	}
+
+	bossacInstallNoURL := tools.ToolPayload{
 		Name:     "bossac",
 		Version:  "1.7.0-arduino3",
 		Packager: "arduino",
-		URL:      &URL,
-		Checksum: &Checksum,
 	}
 
-	payload, err := json.Marshal(request)
-	require.NoError(t, err)
+	tests := []test{
+		{bossacInstallURLOK, http.StatusOK, "ok"},
+		{bossacInstallWrongSig, http.StatusInternalServerError, "verification error"},
+		{bossacInstallNoURL, http.StatusBadRequest, "tool not found"}, //because the index is not added
+	}
+
+	for _, test := range tests {
+		t.Run(fmt.Sprintf("Installing %s", test.request.Name), func(t *testing.T) {
+			payload, err := json.Marshal(test.request)
+			require.NoError(t, err)
+
+			// for some reason the fronted sends requests with "text/plain" content type.
+			// Even if the request body contains a json object.
+			// With this test we verify is parsed correctly.
+			for _, encoding := range []string{"encoding/json", "text/plain"} {
+				resp, err := http.Post(ts.URL+"/v2/pkgs/tools/installed", encoding, bytes.NewBuffer(payload))
+				require.NoError(t, err)
+				body, err := io.ReadAll(resp.Body)
+				require.NoError(t, err)
+				require.Contains(t, string(body), test.responseBody)
+				require.Equal(t, test.responseCode, resp.StatusCode)
+			}
+		})
+	}
+}
+func TestUploadHandlerAgainstEvilFileNames(t *testing.T) {
+	r := gin.New()
+	r.POST("/", uploadHandler)
+	ts := httptest.NewServer(r)
+
+	uploadEvilFileName := Upload{
+		Port:       "/dev/ttyACM0",
+		Board:      "arduino:avr:uno",
+		Extra:      upload.Extra{Network: true},
+		Hex:        []byte("test"),
+		Filename:   "../evil.txt",
+		ExtraFiles: []additionalFile{{Hex: []byte("test"), Filename: "../evil.txt"}},
+	}
+	uploadEvilExtraFile := Upload{
+		Port:       "/dev/ttyACM0",
+		Board:      "arduino:avr:uno",
+		Extra:      upload.Extra{Network: true},
+		Hex:        []byte("test"),
+		Filename:   "file.txt",
+		ExtraFiles: []additionalFile{{Hex: []byte("test"), Filename: "../evil.txt"}},
+	}
 
-	// for some reason the fronted sends requests with "text/plain" content type.
-	// Even if the request body contains a json object.
-	// With this test we verify is parsed correctly.
-	for _, encoding := range []string{"encoding/json", "text/plain"} {
-		resp, err := http.Post(ts.URL+"/v2/pkgs/tools/installed", encoding, bytes.NewBuffer(payload))
+	for _, request := range []Upload{uploadEvilFileName, uploadEvilExtraFile} {
+		payload, err := json.Marshal(request)
 		require.NoError(t, err)
+
+		resp, err := http.Post(ts.URL, "encoding/json", bytes.NewBuffer(payload))
+		require.NoError(t, err)
+		require.Equal(t, http.StatusBadRequest, resp.StatusCode)
+
 		body, err := io.ReadAll(resp.Body)
 		require.NoError(t, err)
-		require.Contains(t, string(body), "ok")
-		require.Equal(t, http.StatusOK, resp.StatusCode)
+		require.Contains(t, string(body), "unsafe path join")
 	}
 }
diff --git a/utilities/utilities.go b/utilities/utilities.go
index 075310b03..5fdd45f27 100644
--- a/utilities/utilities.go
+++ b/utilities/utilities.go
@@ -18,12 +18,23 @@ package utilities
 import (
 	"archive/zip"
 	"bytes"
+	"crypto"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/hex"
+	"encoding/pem"
 	"errors"
+	"fmt"
 	"io"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
+
+	"strings"
+
+	"github.com/arduino/arduino-create-agent/globals"
 )
 
 // SaveFileonTempDir creates a temp directory and saves the file data as the
@@ -32,15 +43,21 @@ import (
 // Returns an error if the filename doesn't form a valid path.
 //
 // Note that path could be defined and still there could be an error.
-func SaveFileonTempDir(filename string, data io.Reader) (path string, err error) {
-	// Create Temp Directory
+func SaveFileonTempDir(filename string, data io.Reader) (string, error) {
 	tmpdir, err := os.MkdirTemp("", "arduino-create-agent")
 	if err != nil {
 		return "", errors.New("Could not create temp directory to store downloaded file. Do you have permissions?")
 	}
+	return saveFileonTempDir(tmpdir, filename, data)
+}
 
+func saveFileonTempDir(tmpDir, filename string, data io.Reader) (string, error) {
+	path, err := SafeJoin(tmpDir, filename)
+	if err != nil {
+		return "", err
+	}
 	// Determine filename
-	filename, err = filepath.Abs(tmpdir + "/" + filename)
+	filename, err = filepath.Abs(path)
 	if err != nil {
 		return "", err
 	}
@@ -141,3 +158,35 @@ func Unzip(zippath string, destination string) (err error) {
 	}
 	return
 }
+
+// VerifyInput will verify an input against a signature
+// A valid signature is indicated by returning a nil error.
+func VerifyInput(input string, signature string) error {
+	sign, _ := hex.DecodeString(signature)
+	block, _ := pem.Decode([]byte(globals.SignatureKey))
+	if block == nil {
+		return errors.New("invalid key")
+	}
+	key, err := x509.ParsePKIXPublicKey(block.Bytes)
+	if err != nil {
+		return err
+	}
+	rsaKey := key.(*rsa.PublicKey)
+	h := sha256.New()
+	h.Write([]byte(input))
+	d := h.Sum(nil)
+	return rsa.VerifyPKCS1v15(rsaKey, crypto.SHA256, d, sign)
+}
+
+// SafeJoin performs a filepath.Join of 'parent' and 'subdir' but returns an error
+// if the resulting path points outside of 'parent'.
+func SafeJoin(parent, subdir string) (string, error) {
+	res := filepath.Join(parent, subdir)
+	if !strings.HasSuffix(parent, string(os.PathSeparator)) {
+		parent += string(os.PathSeparator)
+	}
+	if !strings.HasPrefix(res, parent) {
+		return res, fmt.Errorf("unsafe path join: '%s' with '%s'", parent, subdir)
+	}
+	return res, nil
+}
diff --git a/utilities/utilities_test.go b/utilities/utilities_test.go
new file mode 100644
index 000000000..6511a1719
--- /dev/null
+++ b/utilities/utilities_test.go
@@ -0,0 +1,48 @@
+package utilities
+
+import (
+	"bytes"
+	"fmt"
+	"path/filepath"
+	"runtime"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestSaveFileonTemp(t *testing.T) {
+	filename := "file"
+	tmpDir := t.TempDir()
+
+	path, err := saveFileonTempDir(tmpDir, filename, bytes.NewBufferString("TEST"))
+	require.NoError(t, err)
+	require.Equal(t, filepath.Join(tmpDir, filename), path)
+}
+
+func TestSaveFileonTempDirWithEvilName(t *testing.T) {
+	evilFileNames := []string{
+		"/",
+		"..",
+		"../",
+		"../evil.txt",
+		"../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+		"some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+		"/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+		"/some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+	}
+	if runtime.GOOS == "windows" {
+		evilFileNames = []string{
+			"..\\",
+			"..\\evil.txt",
+			"..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+			"some\\path\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+			"\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+			"\\some\\path\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+		}
+	}
+	for _, evilFileName := range evilFileNames {
+		_, err := saveFileonTempDir(t.TempDir(), evilFileName, bytes.NewBufferString("TEST"))
+		require.Error(t, err, fmt.Sprintf("with filename: '%s'", evilFileName))
+		require.ErrorContains(t, err, "unsafe path join")
+	}
+}
diff --git a/v2/pkgs/tools.go b/v2/pkgs/tools.go
index 13189c9e4..c153884cb 100644
--- a/v2/pkgs/tools.go
+++ b/v2/pkgs/tools.go
@@ -31,6 +31,7 @@ import (
 	"strings"
 
 	"github.com/arduino/arduino-create-agent/gen/tools"
+	"github.com/arduino/arduino-create-agent/utilities"
 	"github.com/codeclysm/extract/v3"
 )
 
@@ -135,10 +136,16 @@ func (c *Tools) Installed(ctx context.Context) (tools.ToolCollection, error) {
 func (c *Tools) Install(ctx context.Context, payload *tools.ToolPayload) (*tools.Operation, error) {
 	path := filepath.Join(payload.Packager, payload.Name, payload.Version)
 
-	if payload.URL != nil {
+	//if URL is defined and is signed we verify the signature and override the name, payload, version parameters
+	if payload.URL != nil && payload.Signature != nil && payload.Checksum != nil {
+		err := utilities.VerifyInput(*payload.URL, *payload.Signature)
+		if err != nil {
+			return nil, err
+		}
 		return c.install(ctx, path, *payload.URL, *payload.Checksum)
 	}
 
+	// otherwise we install from the loaded indexes
 	list, err := c.Indexes.List(ctx)
 	if err != nil {
 		return nil, err
@@ -216,8 +223,12 @@ func (c *Tools) install(ctx context.Context, path, url, checksum string) (*tools
 // Remove deletes the tool folder from Tools Folder
 func (c *Tools) Remove(ctx context.Context, payload *tools.ToolPayload) (*tools.Operation, error) {
 	path := filepath.Join(payload.Packager, payload.Name, payload.Version)
+	pathToRemove, err := utilities.SafeJoin(c.Folder, path)
+	if err != nil {
+		return nil, err
+	}
 
-	err := os.RemoveAll(filepath.Join(c.Folder, path))
+	err = os.RemoveAll(pathToRemove)
 	if err != nil {
 		return nil, err
 	}
diff --git a/v2/pkgs/tools_test.go b/v2/pkgs/tools_test.go
index 581b30b1f..70236cff3 100644
--- a/v2/pkgs/tools_test.go
+++ b/v2/pkgs/tools_test.go
@@ -27,6 +27,7 @@ import (
 	"github.com/arduino/arduino-create-agent/gen/indexes"
 	"github.com/arduino/arduino-create-agent/gen/tools"
 	"github.com/arduino/arduino-create-agent/v2/pkgs"
+	"github.com/stretchr/testify/require"
 )
 
 // TestTools performs a series of operations about tools, ensuring it behaves as expected.
@@ -150,6 +151,33 @@ func TestTools(t *testing.T) {
 	if len(installed) != 1 {
 		t.Fatalf("expected %d == %d (%s)", len(installed), 1, "len(installed)")
 	}
+
+	t.Run("payload containing evil names", func(t *testing.T) {
+		evilFileNames := []string{
+			"/",
+			"..",
+			"../",
+			"../evil.txt",
+			"../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+			"some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt",
+		}
+		if runtime.GOOS == "windows" {
+			evilFileNames = []string{
+				"..\\",
+				"..\\evil.txt",
+				"..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+				"some\\path\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\tmp\\evil.txt",
+			}
+		}
+		for _, evilFileName := range evilFileNames {
+			// Here we could inject malicious name also in the Packager and Version field.
+			// Since the path is made by joining all of these 3 fields, we're using only the Name,
+			// as it won't change the result and let us keep the test small and readable.
+			_, err := service.Remove(ctx, &tools.ToolPayload{Name: evilFileName})
+			require.Error(t, err, evilFileName)
+			require.ErrorContains(t, err, "unsafe path join")
+		}
+	})
 }
 
 func strpoint(s string) *string {