Typesense 30.2
Overview
This guide covers launching and using the Typesense 30.2 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud vector databases and RAG listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.
Typesense is an open-source search engine with a REST API. It returns typo-tolerant results in milliseconds. It supports filters, facets, sorting, grouping, synonyms, geo search, and vector search over embeddings you store with your documents, alone or combined with keyword relevance (hybrid search). Applications send documents to a collection and query it over HTTPS. Official client libraries exist for most languages.
What you get:
- Keys unique to your instance. First boot generates a 64-character admin (bootstrap) API key on the instance and creates a search-only key through Typesense's keys API. Both are written to
/root/typesense-credentials.txt(root-only). No key is baked into the image. - HTTPS from the first boot. nginx serves the API on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS. Typesense itself listens on
127.0.0.1:8108only, and its cluster (peering) port listens on127.0.0.1:8107only. - Closed until first boot, and fail closed. Typesense cannot start before first boot has written its key, and nginx ships switched off. First boot opens the public listener only after Typesense works on loopback and an authenticated check passes. If anything fails, the listener is closed again. The service also refuses to start if its configuration loses the key, listens on a public address, or finds its data volume missing.
- Your data on its own disk. The Typesense data directory
/var/lib/typesenseis a separate 30 GiB EBS volume that you can resize independently of the operating system. - Hardened defaults. Typesense runs as its own unprivileged account in a systemd sandbox that can write only to its data and log directories. It can reach loopback only, with no outbound connection and no instance metadata access unless you choose to open outbound access (see Step 11). nginx is blocked from the instance metadata service too, and it closes Typesense's
/proxyand/personalizationendpoints. Only the Typesense service account can connect to the cluster port. The AMI requires IMDSv2. Requests for any host name the instance does not serve are dropped. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
- What is on the image: Typesense 30.2 (the official release binary from dl.typesense.org, checksum pinned) at
/opt/typesense/typesense-server, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The data volume ships empty, with no collection, document or key. - Defaults: default user
ubuntu, architecture x86_64, recommended instance type m5.large.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair, and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH), TCP 443 (the Typesense API) and TCP 80 (redirects to HTTPS) from your own networks only.
- Never open 8108 or 8107. Typesense listens on the instance's loopback address only.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Typesense 30.2 on Ubuntu 24.04 as the software version, choose your Region, then choose Launch through EC2.
Choose m5.large, your key pair and a security group as above. Typesense keeps its indexes in memory, so size the instance's memory for your dataset.
The AMI brings two EBS volumes: the root volume and a 30 GiB data volume for /var/lib/typesense. Enlarge the data volume at launch if you expect a large dataset.
Or launch with the AWS CLI. Replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--block-device-mappings 'DeviceName=/dev/sdf,Ebs={VolumeSize=100,VolumeType=gp3}' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=typesense}]'Connect to your instance
For Typesense 30.2 on Ubuntu 24.04, the SSH user is ubuntu. Connect with your key pair:
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
First boot generates the certificate and the keys, starts Typesense, opens nginx and runs an authenticated check before it finishes. This takes well under a minute. Confirm the services are active:
systemctl is-active typesense nginx typesense-firstboot typesense-peering-guard
sudo test -f /var/lib/sac/data/typesense-firstboot.done && echo FIRSTBOOT_DONEactive active active active FIRSTBOOT_DONEOnly SSH and nginx listen on public addresses. Typesense listens on loopback. List the listening sockets:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sort0.0.0.0:22 users:(("sshd",...)) 0.0.0.0:443 users:(("nginx",...)) 0.0.0.0:80 users:(("nginx",...)) 127.0.0.1:8107 users:(("typesense-serve",...)) 127.0.0.1:8108 users:(("typesense-serve",...)) [::]:22 users:(("sshd",...)) [::]:443 users:(("nginx",...)) [::]:80 users:(("nginx",...))Get your URL and keys
Read the URL and keys from the credentials file:
sudo grep -E '^TYPESENSE_' /root/typesense-credentials.txtOnly root can read the file. It contains:
TYPESENSE_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ TYPESENSE_API_KEY=<TYPESENSE_API_KEY> TYPESENSE_SEARCH_API_KEY=<TYPESENSE_SEARCH_API_KEY>TYPESENSE_URLis the API endpoint. It uses the instance's public DNS name from EC2 instance metadata, or the public IP address when the subnet has no public DNS names. The certificate also names the public and private IP addresses. To serve Typesense under your own DNS name, see Step 9.TYPESENSE_API_KEYis the admin (bootstrap) key. It can do everything, including creating keys. Use it from your backend only.TYPESENSE_SEARCH_API_KEYcan only search, in every collection. Use it from a web or mobile front end.
Send a key in the X-TYPESENSE-API-KEY header. The examples below read the key from the credentials file and hand it to curl on standard input (-H @-), so it never appears on a command line or in your shell history.
Avoid passing a key as a URL parameter, because URLs end up in logs and browser history. nginx on this image does not log the query string, but other systems might.
Confirm the API requires a key
Send requests with no key and with a wrong key, then with the admin key, and check the health endpoint:
C=/etc/ssl/typesense/typesense.crt; U=https://127.0.0.1 curl -s --cacert $C -o /dev/null -w 'no key -> HTTP %{http_code}\n' $U/collections printf 'X-TYPESENSE-API-KEY: %s\n' wrong-key | curl -s --cacert $C -o /dev/null -w 'wrong key -> HTTP %{http_code}\n' -H @- $U/collections
sudo sed -n 's/^TYPESENSE_API_KEY=/X-TYPESENSE-API-KEY: /p' /root/typesense-credentials.txt | curl -s --cacert $C -H @- $U/debug; echo curl -s --cacert $C $U/health; echono key -> HTTP 401 wrong key -> HTTP 401 {"state":1,"version":"30.2"} {"ok":true}The /health endpoint stays open for load balancers and reveals nothing. From another machine, use TYPESENSE_URL instead of https://127.0.0.1. Add -k or the instance's certificate, because the certificate is self-signed.
Create a collection, import documents and search
Create a movies collection with a text field, a facet, a sort field and a 3-dimension vector field. Then import five documents (JSON Lines) with the admin key:
C=/etc/ssl/typesense/typesense.crt; U=https://127.0.0.1 admin() {
sudo sed -n 's/^TYPESENSE_API_KEY=/X-TYPESENSE-API-KEY: /p' /root/typesense-credentials.txt | curl -s --cacert "$C" -H @- "$@"; } admin -H 'Content-Type: application/json' -X POST --data '{"name":"movies","fields":[{"name":"title","type":"string"},{"name":"genres","type":"string[]","facet":true},{"name":"year","type":"int32"},{"name":"embedding","type":"float[]","num_dim":3}],"default_sorting_field":"year"}' "$U/collections" | jq -c '{name, num_documents}' admin -X POST --data-binary @<(printf '%s\n' \
'{"id":"1","title":"Carol","genres":["Romance","Drama"],"year":2015,"embedding":[0.9,0.1,0.1]}' \
'{"id":"2","title":"Wonder Woman","genres":["Action","Adventure"],"year":2017,"embedding":[0.1,0.2,0.3]}' \
'{"id":"3","title":"Life of Pi","genres":["Adventure","Drama"],"year":2012,"embedding":[0.1,0.8,0.2]}' \
'{"id":"4","title":"Mad Max: Fury Road","genres":["Adventure","Science Fiction"],"year":2015,"embedding":[0.2,0.3,0.3]}' \
'{"id":"5","title":"Moana","genres":["Fantasy","Action"],"year":2016,"embedding":[0.7,0.6,0.1]}') \
"$U/collections/movies/documents/import?action=create"; echo{"name":"movies","num_documents":0} {"success":true} {"success":true} {"success":true} {"success":true} {"success":true}Now search with the search key. A query with two typos still finds the film, filters and sorting work, and the nearest neighbours of a vector come back with their distance. The search key cannot write:
C=/etc/ssl/typesense/typesense.crt; U=https://127.0.0.1 search() {
sudo sed -n 's/^TYPESENSE_SEARCH_API_KEY=/X-TYPESENSE-API-KEY: /p' /root/typesense-credentials.txt | curl -s --cacert "$C" -H @- "$@"; } search "$U/collections/movies/documents/search?q=wondr+womn&query_by=title" | jq -c '{found, titles: [.hits[].document.title]}' search "$U/collections/movies/documents/search?q=*&filter_by=genres:Adventure+%26%26+year:%3E%3D2015&sort_by=year:desc" | jq -c '[.hits[].document | {title, year}]' search "$U/collections/movies/documents/search?q=*&vector_query=embedding:(%5B0.1,0.2,0.3%5D,k:2)" | jq -c '[.hits[] | .document.title]' search -o /dev/null -w 'search key writing a document -> HTTP %{http_code}\n' -H 'Content-Type: application/json' -X POST --data '{"id":"9","title":"x","genres":[],"year":1,"embedding":[0,0,1]}' "$U/collections/movies/documents"{"found":1,"titles":["Wonder Woman"]} [{"title":"Wonder Woman","year":2017},{"title":"Mad Max: Fury Road","year":2015}] ["Wonder Woman","Mad Max: Fury Road"] search key writing a document -> HTTP 401In a real application, you store the embeddings your own model produces (any dimension) in a float[] field with num_dim. Combine keyword and vector relevance by adding query_by together with vector_query (hybrid search).
Typesense can also compute embeddings itself with a built-in model or a remote provider. Both need outbound connections, which this image keeps off until you open them (Step 11).
Run the built-in check
The image ships an end-to-end check you can run at any time. First boot runs a read-only version of it. The check reads the credentials file itself and talks to the API over HTTPS through nginx, with the instance's certificate pinned.
It verifies each of the following:
- Port 80 redirects, and an unknown host name is dropped.
- No key and a wrong key are refused, while the admin key works on the same request.
- The search key cannot create collections or read keys.
- The closed endpoints answer 403.
- The admin key creates a temporary collection. The search key then finds its documents by typo-tolerant text and by vector, before the collection is dropped.
Run the check:
sudo typesense-verify.shport 80 -> 301 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ ; an unknown Host is dropped on 80 and 443 ; certificate verifies for ec2-<public-ip-dashed>.<region>.compute.amazonaws.com auth: no key 401, wrong key 401, admin key 200 (/collections); /debug without a key 401, with the admin key 200: version 30.2 search key: create collection 401, /keys 401, /debug 401 closed at nginx: /proxy, /proxy_sse and /personalization answer 403 even with the admin key round trip: admin key created sac_verify_<n> and imported 3 documents; the search key found 'Wonder Woman' for 'wondr womn' and by vector, could not write or drop; collection dropped TYPESENSE_ROUNDTRIP_OKSecurity checks
The files that matter are locked down. The configuration file holds the admin key. Check the permissions:
sudo stat -c '%a %U:%G %n' /etc/typesense/typesense-server.ini /root/typesense-credentials.txt /var/lib/typesense /etc/ssl/typesense/typesense.key640 root:typesense /etc/typesense/typesense-server.ini 600 root:root /root/typesense-credentials.txt 750 typesense:typesense /var/lib/typesense 600 root:root /etc/ssl/typesense/typesense.keyThe binary is the official 30.2 release. Its SHA-256 equals that of the typesense-server binary in the official typesense/typesense:30.2 container image. It is configured for loopback only:
sha256sum /opt/typesense/typesense-server; /opt/typesense/typesense-server --version 2>&1 | head -1 sudo grep -E '^(api-address|api-port|peering-address|peering-port|data-dir|log-dir|enable-cors) ' /etc/typesense/typesense-server.ini1178111344c96bf91567f579a30e0153e346f716b6f3e10f484ba099f21450b5 /opt/typesense/typesense-server Typesense 30.2 api-address = 127.0.0.1 api-port = 8108 peering-address = 127.0.0.1 peering-port = 8107 data-dir = /var/lib/typesense log-dir = /var/log/typesense enable-cors = trueTypesense runs unprivileged in a sandbox that can write only to its data and log directories. It may connect to loopback addresses only, so neither an embedder, a conversation model nor the proxy endpoint can reach the instance metadata service or anything else. nginx cannot reach the instance metadata service either:
systemctl show typesense -p User -p ProtectSystem -p ReadWritePaths -p NoNewPrivileges -p IPAddressDeny -p IPAddressAllow
systemctl show nginx -p IPAddressDenyIPAddressAllow=::1/128 127.0.0.0/8 IPAddressDeny=::/0 0.0.0.0/0 User=typesense ReadWritePaths=/var/lib/typesense /var/log/typesense ProtectSystem=strict NoNewPrivileges=yes IPAddressDeny=169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128nginx passes Typesense a fixed host name and the real client address from the connection, never values a client sends. Check the proxy headers:
grep -E 'proxy_set_header (Host|X-Forwarded-For|X-Real-IP|Forwarded)' /etc/nginx/typesense-proxy.confproxy_set_header Host $ts_host; proxy_set_header Forwarded ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;nginx closes Typesense's /proxy endpoint, which fetches any URL a key holder supplies, and its /personalization model upload. The cluster port refuses every account except Typesense's own, because it serves built-in status and file services without authentication. Test both:
C=/etc/ssl/typesense/typesense.crt for p in /proxy /personalization/models; do curl -s --cacert $C -o /dev/null -w "$p -> HTTP %{http_code}\n" -X POST https://127.0.0.1$p; done curl -s -m 5 -o /dev/null -w 'peering port 8107 as ubuntu -> %{http_code}\n' http://127.0.0.1:8107/status || true/proxy -> HTTP 403 /personalization/models -> HTTP 403 peering port 8107 as ubuntu -> 000This instance generated the certificate, and it names the instance's own addresses. Inspect it:
H=$(sudo sed -n 's#^TYPESENSE_URL=https://\([^/]*\)/.*#\1#p' /root/typesense-credentials.txt)
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=CN = ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, DNS:ip-<private-ip-dashed>.ec2.internal, IP Address:127.0.0.1, DNS:localhostNo key reaches a log, the journal, shell history, backups or /etc, other than the configuration file. Run the leak check:
sudo typesense-secret-leak-check.shLEAKCHECK_OK no admin or search key in the journal, auth.log, syslog, cloud-init, nginx logs, the Typesense log, shell history, MOTD, /var/backups, /etc (admin key only in typesense-server.ini), /usr/local, /opt or /tmpYour own DNS name and certificate
Point a DNS record at the instance, then set the name Typesense is served as. This command creates a new self-signed certificate for the name, updates nginx's host rule and the URL in /root/typesense-credentials.txt, reloads nginx and keeps the name across reboots:
sudo typesense-set-hostname <your-domain>Without a configured name, the instance re-reads its address from EC2 instance metadata at every boot. A stop and start that changes the public IP address therefore keeps the API reachable.
To use a certificate from your own certificate authority instead, copy it over /etc/ssl/typesense/typesense.crt and typesense.key (key mode 0600) and run sudo systemctl reload nginx. Running typesense-set-hostname again replaces it with a self-signed one. A certbot client works too if you open port 80 to the certificate authority.
API keys and key rotation
Create a key for each application with the admin key. You can limit a key to some collections, some actions and an expiry time. For example, create a key that can only search the movies collection:
sudo sed -n 's/^TYPESENSE_API_KEY=/X-TYPESENSE-API-KEY: /p' /root/typesense-credentials.txt \
| curl -s --cacert /etc/ssl/typesense/typesense.crt -H @- -H 'Content-Type: application/json' \
-X POST --data '{"description":"movies-search","actions":["documents:search"],"collections":["movies"]}' \
https://127.0.0.1/keysTypesense shows a new key's value only in that response, so store it then. From a search-only key, you can also derive scoped search keys (with embedded filters) in your backend without calling the server. See the Typesense documentation on scoped API keys.
If either key was ever exposed, generate a new admin key and a new search-only key:
sudo typesense-rotate-api-keyThe command writes the new admin key to /etc/typesense/typesense-server.ini and restarts Typesense. It deletes the old SecureAnyCloud search-only key, creates a new one and rewrites /root/typesense-credentials.txt. Keys you created yourself are kept. Update every client that used the old keys.
Outbound connections (off by default)
Typesense can call out to the internet for some optional features. These include downloading a built-in embedding model (from models.typesense.org), remote embedding providers (OpenAI, Google, Azure or any OpenAI-compatible URL), conversation (RAG) and natural language search models, and the /proxy endpoint.
This image blocks every outbound connection from the Typesense service. Typesense's HTTP client does not verify the TLS certificate of the server it calls, and its bundled OpenSSL and curl libraries carry advisories that upstream has not yet updated (see Security recommendations). Keyword, faceted, geo and vector search with embeddings you supply work without outbound access.
If you need one of those features, allow outbound access by removing the drop-in and restarting Typesense. Point those features only at providers you trust, ideally over a private network path such as a VPC endpoint or a proxy you control:
sudo rm /etc/systemd/system/typesense.service.d/60-sac-egress.conf
sudo systemctl daemon-reload && sudo systemctl restart typesenseTypesense stays blocked from the instance metadata service by the other drop-in, 50-sac-imds-deny.conf. Its proxy-disallowed-dest-cidrs setting keeps refusing private, loopback and link-local destinations.
To close outbound access again, recreate the file with IPAddressAllow=localhost and IPAddressDeny=any under [Service]. The /proxy and /personalization endpoints stay closed at nginx unless you remove their location blocks from /etc/nginx/sites-available/sac-typesense.
Data volume, snapshots and backups
The data directory is its own EBS volume, mounted by filesystem UUID. Confirm the mount:
findmnt -n -o SOURCE,FSTYPE,TARGET /var/lib/typesense; df -h /var/lib/typesense | tail -1/dev/nvme1n1 ext4 /var/lib/typesense /dev/nvme1n1 30G 13M 28G 1% /var/lib/typesenseTo grow it, enlarge the volume in the EC2 console (or with aws ec2 modify-volume), then run sudo resize2fs /dev/nvme1n1 on the instance. No restart is needed. If the volume is ever missing, Typesense refuses to start rather than write your data to the root disk.
Typesense can write a consistent snapshot of its data directory while it runs. Write the snapshot onto the data volume, then copy it off the instance. It holds your documents and API keys, so treat it as secret:
sudo install -d -o typesense -g typesense -m 0750 /var/lib/typesense/backups
sudo sed -n 's/^TYPESENSE_API_KEY=/X-TYPESENSE-API-KEY: /p' /root/typesense-credentials.txt \
| curl -s --cacert /etc/ssl/typesense/typesense.crt -H @- -X POST \
'https://127.0.0.1/operations/snapshot?snapshot_path=/var/lib/typesense/backups/snapshot-1'EBS snapshots of the data volume are the simplest whole-dataset backup.
Configuration
Settings live in /etc/typesense/typesense-server.base.ini, which holds no key. The image renders /etc/typesense/typesense-server.ini from it plus the admin key.
Edit the base file, for example cors-domains, cache-num-entries or log-slow-requests-time-ms. See the Typesense server configuration reference. Then re-render with the current keys and restart:
sudo nano /etc/typesense/typesense-server.base.ini
sudo typesense-set-api-key --keepKeep api-address and peering-address on 127.0.0.1 so nginx stays the only public listener, and leave TLS to nginx. The service refuses to start otherwise.
The setting enable-cors = true lets a browser front end call the API with the search key. Set cors-domains to your own origins to restrict it. This image runs Typesense as a single node.
Server components
Check the installed versions and the licence files:
/opt/typesense/typesense-server --version 2>&1 | head -1; nginx -v 2>&1; lsb_release -ds ls /usr/share/doc/sac/typesense/Typesense 30.2 nginx version: nginx/1.24.0 (Ubuntu) Ubuntu 24.04.5 LTS LICENSE.txt SOURCE VERSION- Typesense 30.2: /opt/typesense/typesense-server, service typesense, data /var/lib/typesense (own EBS volume), log /var/log/typesense.
- nginx 1.24.0: TLS on 443, redirect on 80, site /etc/nginx/sites-available/sac-typesense.
- Ubuntu 24.04 LTS: unattended security upgrades on.
To upgrade Typesense, take a snapshot (Step 12) and stop the service. Replace the binary with the newer official typesense-server-<version>-linux-amd64.tar.gz release from dl.typesense.org, then start the service again. Check the Typesense release notes for upgrade steps.
Troubleshooting
curl: (60) SSL certificate problem: the certificate is self-signed. Pass--cacert /etc/ssl/typesense/typesense.crton the instance, use-kfor a quick test elsewhere, or install your own certificate (Step 9).- The connection is closed without a response: the request used a host name the instance does not serve, and nginx drops unknown names. Use
TYPESENSE_URLor the instance's IP address, or set your name withtypesense-set-hostname. - HTTP 401 Forbidden - a valid x-typesense-api-key header must be sent. The key is missing, wrong, expired, or not allowed that action or collection. A search-only key gets 401 for any write. After typesense-rotate-api-key, both SecureAnyCloud keys have changed.
- HTTP 403
closed by sac: the request went to/proxyor/personalization, which this image closes at nginx (Step 11). - An embedding model or remote embedder fails with a connection error or "Model not found": outbound connections are off by default (Step 11).
- Typesense does not start after a configuration change:
journalctl -u typesenseshows the reason.typesense-check-configrefuses a missing key, a public address, server TLS or a missing data volume. - First boot:
journalctl -u typesense-firstbootshows what it did. If first boot failed, it closed the public listener. Fix the cause and runsudo systemctl restart typesense-firstboot.
Security recommendations
- Restrict the security group to your own networks. Use the search key (or keys you create per collection) in front ends and the admin key only in backends.
- Rotate the keys if either was ever exposed, and create expiring, narrowly scoped keys for applications.
- Typesense is a single C++ binary that includes its own copies of third-party libraries. The 30.2 release bundles OpenSSL 3.0.5, curl 7.87.0, zlib 1.2.12 and libarchive 3.7.7, for which fixed versions with security advisories exist upstream.
- On this image, those libraries are not reachable. Typesense does not terminate TLS (nginx does), and it cannot open outbound connections (OpenSSL and curl are used only for outbound HTTPS). The only feature that unpacks archives (/personalization model uploads) is closed.
- Opening outbound access (Step 11) makes the outbound path reachable again, so use it only towards providers you trust. SecureAnyCloud publishes a new version when Typesense ships updated libraries.
Support and licensing
SecureAnyCloud provides 24/7 technical support by email and live chat: sales@secureanycloud.com.
Typesense is licensed under the GNU General Public License version 3 (/usr/share/doc/sac/typesense/LICENSE.txt). This image contains the unmodified official Typesense 30.2 release binary. Its complete source code is the upstream tag v30.2, named with its commit in /usr/share/doc/sac/typesense/SOURCE, and SecureAnyCloud provides it on request.
Typesense is a trademark of Typesense, Inc. SecureAnyCloud is not affiliated with or endorsed by Typesense, Inc.
Deploy on AWS
Launch Typesense 30.2 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need help?
Our support team is available 24/7.
sales@secureanycloud.com