Category Archives: Google Cloud Platform Blog

Product updates, customer stories, and tips and tricks on Google Cloud Platform

Google Cloud using P4Runtime to build smart networks



Data networks are difficult to design, build and manage, and often don’t work as well as we would like. Here at Google, we deploy and use a lot of network capacity in and between data centers to deliver our portfolio of services, and the costs and burdens of deploying and managing these networks have only grown with the the scale and complexity of these networks. Almost ten years ago, we took steps to address this by adopting software-defined networking (SDN) as the basis for our network architecture. SDN allowed us to program our networks with software running on standard servers and became a fundamental component of our largest systems. In that time, we’ve continued to develop and improve our SDN technology, and now it’s time to take the next step with P4Runtime.

We are excited to announce our collaboration with the Open Networking Foundation (ONF) on Stratum, an open source project to implement an open reference platform for a truly "software-defined" data plane, designed and built around P4Runtime from the beginning. P4 Runtime allows the SDN control plane to establish a contract with the dataplane about forwarding behavior, and to then establish forwarding behavior through simple RPCs. As part of the project, we’re working with network vendors to make this functionality available in networking products across the industry. As a small-but-complete SDN embedded software solution, Stratum will help bring P4Runtime to a variety of network devices.

But just what is it about P4Runtime that helps with the challenges of building large-scale and reliable networks? Network hardware is typically closed, runs proprietary software and is complex, thanks to the need to operate autonomously and run legacy protocols. Modern data centers and wide-area networks are large, must be fast and simple and are often built using commodity network switch chips interconnected into a large fabric. And despite high-quality whitebox switches and open SDN technology such as OpenFlow, there still aren’t a lot of good, portable options on the market to build these networks.

At Google, we designed our own hardware switches and switch software, but our goal has always been to leverage industry SDN solutions that interoperate with our data centers and wide-area networks. P4Runtime is a new way for control plane software to program the forwarding path of a switch and provides a well-defined API to specify the switch forwarding pipelines, as well as to configure these pipelines via simple RPCs. P4Runtime can be used to control any forwarding plane, from a fixed-function ASIC to a fully programmable network switch.

Google Cloud is looking to P4Runtime as the foundation for our next generation of data centers and wide area network control-plane programming, to drive industry adoption and to enable others to benefit from it. With P4Runtime we’ll be able to continue to build the larger, higher performance and smarter networks that you’ve come to expect.

How to run Windows Containers on Compute Engine



Container virtualization is a rapidly evolving technology that can simplify how you deploy and manage distributed applications. When people discuss containers, they usually mean Linux-based containers. This makes sense, because native Linux kernel features like cgroups introduced the idea of resource isolation, eventually leading to containers as we know them today.

For a long time, you could only containerize Linux processes, but Microsoft introduced support for Windows-based containers in Windows Server 2016 and Windows 10. With this, you can now take an existing Windows application, containerize it using Docker, and run it as an isolated container on Windows. Microsoft supports two flavors of Windows containers: Windows Server and Hyper-V. You can build Windows containers on either the microsoft/windowsservercore and microsoft/nanoserver base images. You can read more about Windows containers in the Microsoft Windows containers documentation.

Windows containers, meet Google Cloud


Google Cloud provides container-optimized VM images that you can use to run containers on Compute Engine. We also offer a Windows VM image for containers that comes with Docker, microsoft/windowsservercore, and microsoft/nanoserver base images installed.

To run Windows containers on Compute Engine, first you need a Windows VM. In Google Cloud Platform Console, go to the Compute Engine section and create an instance. Make sure you’ve selected Windows Server version 1709 Datacenter Core for Containers (Beta) for the boot disk.

After you’ve created the instance, create a new Windows password either from the console or gcloud and RDP into the VM. Once inside the VM, you’ll notice that it’s a bare-minimum OS with a minimal UI. The good news is that Docker and the base images are already installed; that’s all you need to run Windows containers.
For the first Windows container, let’s create a HelloWorld PowerShell script that we can call, similar to this example.

The microsoft/nanoserver:1709 image is already installed, but that image does not include PowerShell. Instead, there's a microsoft/powershell image based on microsoft/nanoserver:1709 image that we can use.

First, let’s pull the PowerShell image and run it:

C:\..> docker pull microsoft/powershell:6.0.1-nanoserver-1709
...
C:\..> docker run -it microsoft/powershell:6.0.1-nanoserver-1709

This takes us inside the PowerShell container. Now, we can create a HelloWorld PowerShell script and exit the container:

PS C:\> Add-Content C:\Users\Public\helloworld.ps1 'Write-Host "Hello World"'
PS C:\> exit

We now need to create a new image that has the PowerShell script, using the modified container. Get the container ID and create a new container image with that ID using the docker commit command:

C:\..> docker ps -a
C:\..> docker commit  helloworld

Finally, we can run the image by pointing to the script inside the container:


C:\..> docker run --rm helloworld pwsh c:\Users\Public\helloworld.ps1
Hello World!

There you go, you’re running a Windows container on GCP!

If you want to try the steps on your own, we have a codelab you can try out: 
Just don’t forget to to shut down or delete the VM when you’re done experimenting, to avoid incurring charges!

To learn more about Windows containers and Windows on GCP, check out our documentation. And if you have feedback or want to know more, drop us a note in the comments.

How to export logs from Stackdriver Logging: new solution documentation



Stackdriver Logging is broadly integrated with Google Cloud Platform (GCP), offering rich logging information about GCP services and how you use them. The Stackdriver Logging Export functionality allows you to export your logs and use the information to suit your needs.

There are lots of reasons to export your logs: to retain them for long-term storage (months or years) to meet compliance requirements; to run data analytics against the metrics extracted from the logs; or simply to import them into another system. Stackdriver Logging can export to Cloud Storage, BigQuery and Cloud Pub/Sub.

How you set up Logging Export on GCP depends on the complexity of your GCP organization, the types of logs to export and how you want to use the logs.

We recently put together a three-part solution that explores best practices for three common logging export scenarios:
  1. Export to GCS for Compliance Requirements 
  2. Export to BigQuery for Security and Access Analytics
  3. Export to Pub/Sub for 3rd party (Splunk) integration
For each scenario, we provide examples of export requirements, detailed setup steps, best practices and tips on using the exported logs.

We’re always looking for more feedback and suggestions on how to improve Stackdriver Logging. Please keep sending us your requests and feedback.

Exploring container security: An overview



Containers are increasingly being used to deploy applications, and with good reason, given their portability, simple scalability and lower management burden. However, the security of containerized applications is still not well understood. How does container security differ from that of traditional VMs? How can we use the features of container management platforms to improve security?

This is the first in a series of blog posts that will cover container security on Google Cloud Platform (GCP), and how we help you secure your containers running in Google Kubernetes Engine. The posts in the series will cover the following topics:
  • Container networking security 
  • New security features in Kubernetes Engine 1.10
  • Image security The container software supply chain 
  • Container runtime security 
  • Multitenancy 
Container security is a huge topic. To kick off the the series, here’s an overview of container security and how we think about it at Google.

At Google, we divide container security into three main areas:
  1. Infrastructure security, i.e., does the platform provide the necessary container security features? This is how you use Kubernetes security features to protect your identities, secrets, and network; and how Kubernetes Engine uses native GCP functionality, like IAM, audit logging and networking, to bring the best of Google security to your workloads. 
  2. Software supply chain, i.e., is my container image secure to deploy? This is how you make sure your container images are vulnerability-free, and that the images you built aren't modified before they're deployed. 
  3. Runtime security, i.e., is my container secure to run? This is how you identify a container acting maliciously in production, and take action to protect your workload.
Let’s dive a bit more into each of these.

Infrastructure security


Container infrastructure security is about ensuring that your developers have the tools they need to securely build containerized services. This covers a wide variety of areas, including:
  • Identity, authorization and authentication: How do my users assert their identities in my containers and prove they are who they say they are, and how do I manage these permissions?
    • In Kubernetes, Role-Based Access Control (RBAC) allows the use of fine-grained permissions to control access to resources such as the kubelet. (RBAC is enabled by default since Kubernetes 1.8.)
    • In Kubernetes Engine, you can use IAM permissions to control access to Kubernetes resources at the project level. You can still use RBAC to restrict access to Kubernetes resources within a specific cluster.
  • Logging: How are changes to my containers logged, and can they be audited?
    • In Kubernetes, Audit Logging automatically captures API audit logs. You can configure audit logging based on whether the event is metadata, a request or a request response.
    • Kubernetes Engine integrates with Cloud Audit Logging, and you can view audit logs in Stackdriver Logging or in the GCP Activity console. The most commonly audited operations are logged by default, and you can view and filter these.
  • Secrets: How does Kubernetes store secrets, and how do containerized applications access them?
  • Networking: How should I segment containers in a network, and what traffic flows should I allow?
    • In Kubernetes, you can use network policies to specify how to segment the pod network. When created, network policies define with which pods and endpoints a particular pod can communicate.
    • In Kubernetes Engine, you can create a network policy, currently in beta, and manage these for your entire cluster. You can also create Private Clusters, in beta, to use only private IPs for your master and nodes.
These are just some of the tools that Kubernetes uses to secure your cluster the way you want, making it easier to maintain the security of your cluster.

Software supply chain 


Managing the software supply chain, including container image layers that you didn't create, is about ensuring that you know exactly what’s being deployed in your environment, and that it belongs there. In particular, that means giving your developers access to images and packagers that are known to be free of vulnerabilities, to avoid introducing known vulnerabilities into your environment.

A container runs on a server's OS kernel but in a sandboxed environment. A container's image typically includes its own operating system tools and libraries. So when you think about software security, there are in fact many layers of images and packages to secure:
  • The host OS, which is running the container 
  • The container image, and any other dependencies you need to run the container. Note that these are not necessarily images you built yourself—container images included from public repositories like Docker Hub also fall into this category 
  • The application code itself, which runs inside the container. This is outside of the scope of container security, but you should follow best practices and scan your code for known vulnerabilities. Be sure to review your code for security vulnerabilities and consider more advanced techniques such as fuzzing to find vulnerabilities. The OWASP Top Ten web application security risks is a good resource for knowing what to avoid. 

Runtime security 


Lastly, runtime security is about ensuring that your security response team can detect and respond to security threats to containers running in your environment. There are a few desirable capabilities here:
  • Detection of abnormal behaviour from the baseline, leveraging syscalls, network calls and other available information 
  • Remediation of a potential threat, for example, via container isolation on a different network, pausing the container, or restarting it 
  • Forensics to identify the event, based on detailed logs and the containers’ image during the event 
  • Run-time policies and isolation, limiting what kinds of behaviour are allowed in your environment 
All of these capabilities are fairly nascent across the industry, and there are many different ways today to perform runtime security.

A container isn’t a strong security boundary 


There’s one myth worth clearing up: containers do not provide an impermeable security boundary, nor do they aim to. They provide some restrictions on access to shared resources on a host, but they don’t necessarily prevent a malicious attacker from circumventing these restrictions. Although both containers and VMs encapsulate an application, the container is a boundary for the application, but the VM is a boundary for the application and its resources, including resource allocation.

If you're running an untrusted workload on Kubernetes Engine and need a strong security boundary, you should fall back on the isolation provided by the Google Cloud Platform project. For workloads sharing the same level of trust, you may get by with multi-tenancy, where a container is run on the same node as other containers or another node in the same cluster.

Upcoming talks at KubeCon EU 


In addition to this blog post series, we’ll be giving several talks on container security at KubeCon Europe in Copenhagen. If you’ll be at the show, make sure to add these to your calendar:
Note that everything discussed above is really just focused at the container level; you still need a secure platform underlying this infrastructure, and you need application security to protect the applications you build in containers. To learn more about Google Cloud’s security, see the Google Infrastructure Security Design Overview whitepaper.

Stay tuned for next week’s installment about image security!

API design: Which version of versioning is right for you?



There's a lot of advice on the web about API versioning, much of it contradictory and inconclusive: One expert says to put version identifiers in HTTP headers, another expert insists on version identifiers in URL paths, and a third says that versioning of APIs is not necessary at all. (For some examples of those divergent views, take a look at this blog post and its bibliography and this interview with the author of the original REST dissertation).

With all this information, who’s an API developer to believe?

Here on the Apigee team at Google Cloud, we design, use and see a lot of APIs, and have developed some strong opinions about the right way to version them. My aim is to bring some clarity and offer unequivocal practical advice.

A significant part of the confusion around API versioning stems from the fact that the word “versioning” is used to describe at least two fundamentally different techniques, each with different uses and consequences. Understanding the two different meanings of API versioning is a prerequisite to deciding how and when to use each.


Type 1 versioning: format versioning


Consider the example of a bank that maintains accounts for customers. These accounts have been around for a long time and customers can get information about these accounts through multiple channels (the postal service, the telephone or the bank website, for example).

In addition, the bank has a web API that allows access to accounts programmatically. At some point, the bank sees a way to improve the web API; to attract more developers to it they decide to introduce a new version. I don't think there's an API designer who hasn't one day wished they had organized the information in some request or response differently.

The important point in this example is that version 1 and version 2 of the API both allow access to the same bank accounts. The API change introduces no new entities; versions 1 and 2 simply provide two different "formats" [my word1] for manipulating the same bank accounts.

Further, any change made using the version 2 API changes the underlying account entity in ways that are visible to clients of the version 1 API. In other words, each new API version defines a new format for viewing a common set of entities. It’s in this sense that I use the phrase "format versioning" in the rest of this post.

Format versioning seems straightforward, but it presents a technical challenge: how do you ensure that any changes made to an entity using one version of the API are seen correctly through all other versions of the API, and how do you ensure that changes made by older clients don't undo or corrupt changes made by newer clients?

In practice, this means that format versioning often can’t accommodate major functional changes. Another problem is that if a lot of format versions are introduced, the server code can become bloated and complex, raising costs for the API publisher.

Type 2 versioning: entity versioning


Given that format versioning can be complex to implement, and that it cannot be used for substantial changes that would cause older API clients to stop working, it’s a good thing that there’s another way to version APIs.

Consider how car manufacturers do versioning. Car manufacturers typically introduce a new generation of popular models every 4 or 5 years. Car model generations are sometimes also called marks; they're a form of versioning. When you buy a specific car of a particular model, it’s a generation 2 car or a generation 3 car, but not both. Car manufacturers will recall cars to fix faults, but they can’t make your generation 2 car look and behave like a generation 3 car on demand.

This model can work well for software too. Extending the bank example, imagine that the bank wants to introduce checking accounts based on blockchain technology, which requires the underlying data for the account to be organized quite differently. If the API that was previously exposed for accounts made assumptions that are simply not compatible with the new technology, it's not going to be possible to read and manipulate the blockchain accounts using the old API. The bank’s solution is the same as the car company’s: introduce "version 2" checking accounts. Each account is either a conventional account or a blockchain account, but not both at the same time. Each version has its own API that are the same where possible but different where necessary.

While "entity versioning" is attractive for its flexibility and simplicity, it also is not free; you still have to maintain the old versions for as long as people use them.

You could think of entity versioning as a limited form of software product lines (SPLs), where the product line evolves along a single time dimension. There's quite a bit of material on the general topic of SPLs on the internet.

New entity version or new entity?


From a technical perspective, introducing a new "entity version" is very similar to introducing a brand new entity type. The argument by Roy Fielding, the creator of REST, that you don't need to version APIs at all seems to be based on this idea.

Fielding makes an important point, but there are good reasons not to present a new API for similar concepts as something completely unrelated. We have all seen advertisements that say something like "Acme Motors introduces the all-new model Y," where model Y is an existing car model that Acme Motors has been selling for years. Not every statement made in car advertisements is accurate, but when car companies say "all-new," they're usually being truthful in the sense that there isn't a single part on the new model that is the same as on the old one.

So if the model is really "all-new," why is it still a model Y, and not some completely different model? The answer is that the manufacturer is choosing to emphasize brand continuity; although it's "all-new," the new model serves the same market segment in a similar way, and the manufacturer wants to leverage its existing investment in the model Y brand.

The bank has a similar choice to make when it introduces accounts based on blockchain technology. Although the new accounts are based on a different technology, they provide all of the basic capabilities of traditional accounts to the same customers. They may offer additional capabilities, or they may just hold the promise of greater security, or shorter delays in transferring money. The bank likely chooses to present them as a new version of their traditional bank accounts, rather than a completely different financial product.

One of the reasons why this form of versioning works well for car companies is that customers replace their cars every few years, so there's a natural migration from older to newer inventory over time. Banking customers may keep bank accounts for a long time, so the bank may want to offer to automatically migrate their customers to move them onto the new version more quickly. If your company's products are digital technology products, the natural inventory turnover may be even more rapid, which makes this versioning model even more attractive.

When is versioning required?


It turns out that in practice, many APIs don’t need versioning of either kind. We can say with certainty that some of our own APIs (Apigee’s management API is one example) have never had the need for a subsequent version or only in limited portions of the API.

One reason why many APIs never need versioning is that you can make many small enhancements to APIs in a backwards-compatible way, usually by adding new properties or new entities that older clients can safely ignore. Your first thought should always be to try to find a backwards-compatible way of introducing an API change without versioning; versioning of either sort should only be attempted if that fails. Fortunately, there are things you can do up front when designing your API to maximize the number of changes that can be made in a backwards-compatible way. One example is using PATCH instead of PUT for updates. You can also add a couple of random and meaningless properties to every entity representation; this will test the clients' ability to ignore future properties they haven't seen before.

One of the simplest changes that might motivate a version change is to change the name of a particular property or entity type. We all know that naming is hard, and finding the right names for concepts is difficult even when the concepts are clear. Names that were carefully chosen during development often become obsolete as concepts evolve and ideas become clearer. A format version can be an opportunity to clean up nomenclature without changing the fundamental meaning of entities and their properties. Format versioning lends itself to this sort of change—the same changes can be made by old and new clients using different names for the same things.

Another example that can motivate a version change is restructuring the representation of a resource. Here's an example of two ways of structuring the same information in JSON:

{"kind": "Book",
 "name": "The Adventures of Tom Sawyer",
 "characters": {
   "Tom Sawyer": {"address": "St Petersburg, Mo"},
   "Huckleberry Finn": {"father": "Pap Finn"}
  }
}

{"kind": "Book",
 "name": "The Adventures of Tom Sawyer",
 "characters": [
   {"name": "Tom Sawyer", "address": "St Petersburg, Mo"},
   {"name": "Huckleberry Finn", "father": "Pap Finn"}
  ]
}

One of these formats encodes the list of characters as a JSON object keyed by the characters' name, and the other encodes it as a JSON array. Neither are right or wrong. The first format is convenient for clients that always access the characters by name, but it requires clients to learn that the name of the character is to be found in the place that a property name is usually found in JSON, rather than as a property value. The second format does not favor one access pattern over another and is more self-describing; if in doubt, I recommend you use this one. This particular representation choice may not seem very important, but as an API designer you're faced with a large number of options, and you may sometimes wish you had chosen differently.

Sadly, there's no practical way to write API clients that are insensitive to name changes and changes in data representation like these. A version format allows you to make changes like this without breaking existing API clients.

Browsers are able to survive HTML webpage changes without versioning, but the techniques that make this work for browsers—e.g., the ability to download and execute client code that is specific to the current format of a particular resource, enormous investment in the technology of the browser itself, industry-level standardization of HTML, and the human user's ability to adapt to changes in the final outcome—are not available or practical for most API clients. An exception is when the API client runs in a web browser and is loaded on demand each time an API resource is accessed. Even then, you have to be willing to manage a tight coordination between the team producing the browser code and the team producing the API—this doesn't happen often, even for browser UI development within a single company.

A very common situation that usually requires an entity version change, rather than just a format version change, is when you split or merge entity hierarchies. In the bank example, imagine that Accounts belong to Customers, and each Account entity has a reference to the Customer it belongs to. Because some customers have many Accounts, the bank wants Accounts to be grouped into Portfolios. Now Accounts need to reference the Portfolio they belong to, not the Customer, and it's the Portfolio that references the Customer. Changes like this are hard to accommodate with format versions, because older clients will try to set a property linking an Account to a Customer and newer clients will try to set a property linking an Account to a Portfolio. You can sometimes find ways to make both sets of clients work in cases like this, but more often you are forced to introduce new entity versions, each of which is updated using only one API format.

The sort of structural changes that force a new entity version usually introduce new concepts and new capabilities that are visible to the user, whereas the changes handled by format version changes are more superficial.

In general, the more clients an API has, and the greater the independence of the clients from the API provider, the more careful the API provider has to be about API compatibility and versioning.

Providers of APIs sometimes make different choices if the consumers of the API are internal to the same company, or limited to a small number of partners. In that case they may be tempted to try to avoid versioning by coordinating with consumers of the API to introduce a breaking change. In our experience this approach has limited success; it typically causes disruption and a large coordination effort on both sides. Google uses this approach internally, but at considerable cost—this article describes some of Google's investments to make it work. It is usually much better for API providers to treat internal users and partners as if they were external consumers whose development process is independent.

Choosing the appropriate technique


You can probably see already that format version and entity versioning are fundamentally different techniques that solve different problems with different consequences, even though they both sail under the flag of versioning.

So when should you choose to do format versioning versus entity versioning? Usually the business requirements make the choice obvious.

In the case of the bank, it isn’t feasible to introduce a new entity version of an account in order to enable an API improvement. Accounts are stable and long-lived, and moving from old accounts to new ones is disruptive. A bank is unwilling to inconvenience its banking customers just to make life better for API developers. If the goal is just to improve the API, the bank should pick format versioning, which will limit the sort of changes that they make to superficial improvements.

The bank should consider introducing a new entity version if there's significant new value that it wants to expose to its banking customers, or if it's forced to do so for security or regulatory reasons. In the case of blockchain accounts, there may be publicity value as well as practical value. Entity version upgrades are less common than format versioning changes for established services, but they do happen; you may have received messages from your bank telling you about a significant technology upgrade to your accounts and alerting you to actions you need to take, or changes you will see.

Entity versioning puts an additional burden on API clients, because the older clients cannot work with the newer entities, even though they continue to work unchanged with the older ones. This puts pressure on client developers to produce a new client application or upgrade an existing one to work with the new API.

Entity versioning can work well for technology products, where the the users of the API and the core customers are often one and the same and rapid obsolescence is considered normal.

How do you implement the different versions of versioning?


On the web, you often see conflicting advice on whether or not a version number should appear in the URLs of a web API. The primary alternative is to put the version ID in an HTTP header. The better choice depends on whether you're doing format versioning or entity versioning.

For format versioning, put the version identifier in an HTTP header, not in the URL. Continuing the banking example, it’s conceptually simpler for each account to have a single URL, regardless of which format the API client wants to see it in. If you put a format version identifier in the URL, you are effectively making each format of each entity a separate web resource, with some behind-the-scenes magic that causes changes in one to be reflected in the other.

Not only is this a more complex conceptual model for users, it also creates problems with links. Suppose that in addition to having an API for accounts, the bank also has an API for customer records, and that each account contains a link to the record for the customer that owns it. If the developer asks for the version 2 format of the account, what version should be used in the link to the customer record? Should the server assume that the developer will also want to use the version 2 format of the customer record and provide that link? What if customer records don't even have a version 2 format?

Some APIs that put version identifiers in URLs (OpenStack, for example, and at least one bank we know) solve the link problem by having a “canonical” URL for each entity that's used in links, and a set of version-specific URLs for the same entity that are used to access the entity's format versions. Clients that want to follow a link have to convert a canonical URL in a link into a version-specific URL by following a documented formula. This is more complex for both the provider and the client; it's simpler to use a header.

The usual objection to putting format version identifiers in a header is that it's no longer possible to simply type a URL into a browser to test the result of a GET on a specific version. While this is true, it's not very hard to add headers in the browser using plugins like Postman, and you'll probably have to set headers anyway for the Authorization and Accept headers. If you'ew using the cURL shell command to test your API, adding headers is even simpler. You'll also need more than just the browser to create, update or delete requests to your API, so optimizing for GET only helps for one scenario. Your judgement may be different, but I have never found it very onerous to set a header.

There's no standard request header that's ideal for the client to say what format version it wants. The standard "Accept" header specifies which media types the client can accept (e.g., json, yaml, xml, html, plain text), and the standard "Accept-Language" header denotes which natural languages the client can accept (e.g., French, English, Spanish). Some API designers (e.g., the authors of the Restify framework) use a non-standard header called "Accept-Version". If you're doing format versioning, I recommend this header. The standard "Accept" headers allow the client to give a list of values they accept, and even provide a weighting for each. This level of complexity isn’t necessary for "Accept-Version"; a single value is enough. If you're meticulous, you should set a corresponding "Content-Version" header in the response. Further, it can be useful for clients if the server also puts the format version in the body of the response; in fact, if the representation of one resource is embedded in another, the body is the only place to put it. [This argument applies to a number of the standard headers too: e.g., Etag, Location, and Content-Location.]

By contrast, if you're doing entity versioning, the version identifier will appear somewhere in the URL of each entity—usually either in the domain name or the path. Users of the API do not have to be aware of this; for them, it's just the entity's URL. The version identifier will appear in the URL because the URL has to contain information for two different purposes: for routing requests to the correct part of the implementation for processing, and for identifying the entity within that implementation. Because requests for entities that belong to two different entity versions are almost always processed by a different part of the implementation or use different storage, the version identifier (or a proxy for it) must be somewhere in the URL for your routing infrastructure or implementation to use.

Coincidentally, banking provides a simple illustration of the principle that identifiers contain information for both routing and identification. If you have a checking account at a U.S. bank (the details are different in other countries, but the idea is similar), you'll find two numbers at the bottom of each check. The first is called the routing number. It identifies the institution that issued and can process this check. The second number identifies the check itself. Conceptually, entity URLs are like the numbers at the bottom of a check, though their formats may be different.

Do I have to define my versioning strategy up front?


You'll sometimes hear the advice that you must define a versioning strategy before you release your first version, or evolving your API will be impossible. This is not true.

You can always add a new versioning header later if you find the need to do format versioning and you can always add new URLs for new entities for a different entity version. Any requests that lack the format versioning header should be interpreted as meaning the first format version. Since instances of a new entity version get new URLs, you can easily introduce a version ID in those URLs without affecting the URLs of the entities of the first version. The new URLs may use a new hostname rather than adding path segments to URLs on the original hostname; whether or not you like that option will depend on your overall approach for managing hostnames.

Procrastination can be good


Laziness is not the only reason why you might not add versioning to the initial version of your API. If it turns out that versioning is never needed for your API, or for significant portions of your API, then the API will look better and be easier to use if it doesn’t include versioning in its initial release.

If you introduce an "Accept-Version" header in V1 of your API in anticipation of future "format versions" that never materialize, then you force your clients to set a header unnecessarily on every request.

Likewise, if you start all your URLs with the path prefix '/v1' in anticipation of future "entity version" introductions that never happen, then you make your URLs longer and uglier than they need to be.

More importantly, in both cases you introduce a complex topic to clients that you didn’t need to introduce.

Some more versioning tips


If you use versioning, make it clear what sort of versioning you use. If there'a a field in your HTTP requests and responses that says "version: V1," what does that mean? Does V1 apply to the persistent entity itself (entity versioning), or does it reflect the format in which the client asked to see the entity (format versioning)? Having a clear understanding of which versioning scheme or schemes you use helps your users understand how to use your API as it evolves.

If you're using format versioning and entity versioning together, signal them with different mechanisms. Format versions should go in headers—Accept-Version and Content-Version—in the request and response. Format versions can also be included in the bodies of responses and requests, for those requests that have them. Entity versions (which are really part of the entity type) belong in the request and response bodies; they're part of the representation of the entity.

Do not try to put versioning identifiers of either kind or entity type identifiers into the standard Accept or Content-Type headers; those headers should only include standard media types like text/html or application/json. Avoid using values like application/v2+json or application/customer+json; the media-type is not the place to try to encode version or type information. Unfortunately, even some of the web standards do this the wrong way, for example application/json-patch+json.

Don't put words like "beta" or "alpha" in version IDs for either format versioning or entity versioning. When you move from alpha to beta, or beta to general availability, you're making a statement about your level of support for the API, or its likely stability. You don't want to be in a position where the API version changes just because your level of support changes; you only want to change the version if there's a technical or functional reason for changing it. To illustrate this point, imagine I am a customer who develops a number of client applications that are using the V1beta4 version of an interface—a late-beta version. The API provider declares the product to be GA, and introduces the V1 version of the API, which is actually exactly the same as the V1beta4 API, since there were no breaking API changes between V1beta4 and GA. The V1Beta4 version of the API is still available, so my client applications don't break, but the language of the support agreement is clear—only users of the V1 version get full product support. The change to my client applications to upgrade to V1 is small—I only have to change the version number I'm using, which may even be as simple as recompiling with the latest release of the vendor-provided client libraries—but any change to my applications, no matter how small, needs to go through a full release process with QA testing, which costs me thousands of dollars. This is very annoying.

Hopefully this post helps bring a little more clarity to the topic of API versioning, and helps you with your design and implementation choices. Let us know what you think.

For more on API design, read the eBook, “Web API Design: The Missing Link” or check out more API design posts on the Apigee blog.

1 Representation would be another word for this concept that might be better aligned with REST terminology. For reasons I can't explain, the term "representation versioning" is not as appealing to me as "format versioning". 

Now, you can automatically document your API with Cloud Endpoints



With Cloud Endpoints, our service for building, deploying and managing APIs on Google Cloud Platform (GCP), you get to focus on your API’s logic and design, and our team handles everything else. Today, we’re expanding “everything else” and announcing new developer portals where developers can learn how to interact with your API.

Developer portals are the first thing your users see when they try to use your API, and are an opportunity to answer many of their questions: How do I evaluate the API? How do I get working code that calls the API? And for you, the API developer, how do you keep this documentation up-to-date as your API develops and changes over time?

Much like with auth, rate-limiting and monitoring, we know you prefer to focus on your API rather than on documentation. We think it should be easy to stand up a developer portal that’s customized with your branding and content, and that requires minimal effort to keep its contents fresh.

Here’s an example of a developer portal for the Swagger Petstore (YAML):

The portal includes, from left to right, the list of methods and resources, any custom pages that the API developer has added, details of the individual API method and an interactive tool to try out the API live!

If you’re already using Cloud Endpoints, you can start creating developer portals immediately by signing up for this alpha. The portal will always be up-to-date; any specification you push with gcloud also gets pushed to the developer portal. From the portal, you can browse the documentation, try the APIs interactively alongside the docs, and share the portal with your team. You can point your custom domain at it, for which we provision an SSL certificate, and add your own pages for content such as tutorials and guides. And perhaps the nicest thing is that this portal works out of the box for both gRPC and OpenAPI—so your docs are always up-to-date, regardless of which flavor of APIs you use.

Please reach out to our team if you’re interested in testing out Cloud Endpoints developer portals. Your feedback will help us shape the product and prioritize new features over the coming months.

Introducing Stackdriver APM and Stackdriver Profiler

Distributed tracing, debugging, and profiling for your performance-sensitive applications


Like all developers that care about their users, you’re probably obsessed with how your applications perform and how you can make them faster and more reliable. Monitoring and logging software like Stackdriver Monitoring and Logging provide a first line of defense, alerting you to potential infrastructure or security problems, but what if the performance problem lies deeper than that, in your code?

Here at Google, we’re developers too, and we know that tracking down performance problems in your code can be hard—particularly if the application is live. Today we’re announcing new products that offer the same Application Performance Management (APM) capabilities that we use internally to monitor and tune the performance of our own applications. These tools are powerful, can be used on applications running anywhere, and are priced so that virtually any developer can make use of them.

The foundation of our APM tooling is two existing products, Stackdriver Trace and Debugger, which give you the power to analyze and debug applications while they're running in production, without impacting user experience in any way.

On top of that, we’re introducing Stackdriver Profiler to our APM toolkit, which lets you profile and explore how your code actually executes in production, to optimize performance and reduce cost of computation.

We’re also announcing integrations between Stackdriver Debugger and GitHub Enterprise and GitLab, adding to our existing code mirroring functionality for GitHub, Bitbucket, Google Cloud Repositories, as well as locally-stored source code.

All of these tools work with code and applications that run on any cloud or even on-premises infrastructure, so no matter where you run your application, you now have a consistent, accessible APM toolkit to monitor and manage the performance of your applications.

Introducing Stackdriver Profiler


Production profiling is immensely powerful, and lets you gauge the impact of any function or line of code on your application’s overall performance. If you don’t analyze code execution in production, unexpectedly resource-intensive functions increase the latency and cost of web services every day, without anyone knowing or being able to do anything about it.

At Google, we continuously profile our applications to identify inefficiently written code, and these tools are used every day across the company. Outside of Google, however, these techniques haven’t been widely adopted by service developers, for a few reasons:
  1. While profiling client applications locally can yield useful results, inspecting service execution in development or test environments does not. 
  2. Profiling production service performance through traditional methods can be difficult and risks causing slowdowns for customers. 
  3. Existing production profiling tools can be expensive, and there’s always the option of simply scaling up a poorly performing service with more computing power (for a price).
Stackdriver Profiler addresses all of these concerns:
  1. It analyzes code execution across all environments. 
  2. It runs continually and uses statistical methods to minimize impact on targeted codebases.
  3. It makes it more cost-effective to identify and remediate your performance problems rather than scaling up and increasing your monthly bill. 
Stackdriver Profiler collects data via lightweight sampling-based instrumentation that runs across all of your application’s instances. It then displays this data on a flame chart, presenting the selected metric (CPU time, wall time, RAM used, contention, etc.) for each function on the horizontal axis, with the function call hierarchy on the vertical axis.
Early access customers have used Stackdriver Profiler to improve performance and reduce their costs.
"We used Stackdriver Profiler as part of an effort to improve the scalability of our services. It helped us to pinpoint areas we can optimize and reduce CPU time, which means a lot to us at our scale." 
 Evan Yin, Software Engineer, Snap Inc. 
 "Profiler helped us identify very slow parts of our code which were hidden in the middle of large and complex batch processes. We run hundreds of batches every day, each with different data sets and configurations, which makes it hard to track down performance issues related to client-specific configurations. Stackdriver Profiler was super helpful." 
Nicolas Fonrose, CEO, Teevity 

 Stackdriver Profiler is now in public beta, available for everyone. It supports:

Unearth tricky code problems with Stackdriver Debugger

Stackdriver Debugger provides a familiar breakpoint-style debugging process for production applications, with no negative customer impact.


Additionally, Stackdriver Debugger’s logpoints feature allows you to add log statements to production apps, instantly, without having to redeploy them.
Debugger simplifies root-cause analysis for hard-to-find production code issues. Without Debugger, finding these kinds of problems usually requires manually adding new log statements to application code, redeploying any affected services, analyzing logs to determine what is actually going wrong, and finally, either discovering and fixing the issue or adding additional log statements and starting the cycle all over again. Debugger reduces this iteration cycle to zero.

Stackdriver Debugger is generally available and supports the following languages and platforms:

Reduce latency with Stackdriver Trace


Stackdriver Trace allows you to analyze how customer requests propagate through your application, and is immensely useful for reducing latency and performing root cause analysis. Trace continuously samples requests, automatically captures their propagation and latency, presents the results for display, and finds any latency-related trends. You can also add custom metadata to your traces for deeper analysis.
Trace is based off of Google’s own Dapper, which pioneered the concept of distributed tracing and which we still used every day to make our services faster and more reliable.

We’re also adding multi-project support to Trace in the coming weeks, a long-requested feature that will let you view complete traces across multiple GCP projects at the same time. Expect to hear more about this very soon.

Stackdriver Trace is generally available and offers the following platform and language support:

Get started today with Stackdriver APM


Whether your application is just getting off the ground, or live and in production, using APM tools to monitor and tune its performance can be a game changer. To get started with Stackdriver APM, simply link the appropriate instrumentation library for each tool to your app and start gathering telemetry for analysis. Stackdriver Debugger is currently free, as is the beta of Stackdriver Profiler. Stackdriver Trace includes a large monthly quota of free trace submissions.

To learn more, see the Stackdriver Profiler, Debugger and Trace documentation

How we used Cloud Spanner to build our email personalization system—from “Soup” to nuts



[Editor’s note: Today we hear from Tokyo-based Recruit Technologies Co., Ltd., whose email marketing platform is built on top of GCP. The company recently migrated its database to Cloud Spanner for lower cost and operational requirements, and higher availability compared to their previous HBase-based database system. Cloud Spanner also allows Recruit to calculate metrics (KPIs) in real time without having to transfer the data first. Read on to learn more about their workload and how Cloud Spanner fits into the picture.]

There are just under 8 billion people on Earth, depending on the source. Here at Recruit, our work is to develop and maintain an email marketing system that sends personalized emails to tens of millions of customers of hundreds of web services, all with the goal of providing the best, most relevant customer experience.

When Recruit was founded in 1960, the company was focused on helping match graduates to jobs. Over the years, we’ve expanded to help providers that deal with almost every personal moment and event a person encounters in their life. From travel plans to real estate, restaurant choices to haircuts, we offer software and services to help providers deliver on virtually everything and connect to their end-customers.

Recruit depends on email as a key marketing vehicle to end-customers and to provide a communications channel to clients and advertisers across its services. To maximize the impact of these emails, we customize each email we send. To help power this business objective, we developed a proprietary system named “Soup” that we host on Google Cloud Platform (GCP). Making use of Google Cloud Spanner, Soup is the connective tissue that manages the complex customization data needed for this system.

Of course, getting from idea to functioning product is easier said than done. We have massive datasets so requirements like high availability and serving data in real-time are particularly tricky. Add in a complex existing on-premises environment, some of which we had to maintain in our journey to the cloud creating a hybrid environment, and the project became even more challenging.

A Soup primer


First, why the name “Soup”? The name of the app is actually “dashi-wake” in Japanese, from “dashi,” a type of soup. In theory, Soup is a fairly simple application: its API returns recommendation results based on the data we compute about a user via the user's user ID. Soup ingests pre-computed recommendations and then serves those recommendations to the email generation engine and tracks metrics. While Soup doesn’t actually send the customer emails, it manages the entire volume of personalization and customization data for tens of millions of users. It also manages the computed metrics associated with these email sends such as opens, clicks, and other metadata.

Soup leverages other GCP services such as App Engine Flex (Node.js), BigQuery, Data Studio, and Stackdriver in addition to Cloud Spanner.
(click to enlarge)

Soup requirements


High availability

If the system is unavailable when a user decides to open an email they see a white screen with no content at all. Not only is that lost revenue for that particular email, it makes customers less likely to open future emails from us.

Low latency

Given a user ID, the system needs to search all its prediction data and generate the appropriate contentan HTML file, an image, multiple images, or other contentand deliver it, all very quickly.

Real-time log ingestion and fast JOINs

In today’s marketing environment, tracking user activity and being able to make dynamic recommendations based on it is a must-have. We live in an increasingly real-time world. In the past, it might have been OK to take a week or longer to adapt content based on customer behavior. Now? A delay of even a day can make the difference between a conversion and a lost opportunity.

The problem


Pushing out billions of personalized emails to tens of millions of customers comes with some unique challenges. Our previous on-premises system was based on Apache HBase, the open-source NoSQL database, and Hive data warehouse software. This setup presented three major obstacles:

Cluster sizing

Email marketing is a bursty workload. You typically send a large batch of emails, which requires a lot of compute, and then there’s a quiet period. For our email workloads, we pre-compute a large set of recommendations and then serve those recommendations dynamically upon email open. On-premises, there wasn’t much flexibility and we had to resize clusters manually. We were plagued by errors whenever loads of email opens and the resulting requests to the system outpaced the traffic we could handle, because the cluster size of our HBase/Hive system couldn’t keep up.

Performance

The next issue was optimizing the schema model for performance. Soup has a couple of main functions: services write customer tracking data to it, and downstream “customers” read that data from it to create the personalized emails. On the write side, after the data is written to Soup, the writes need to be aggregated. We initially did this on-premises, which was quite difficult and time consuming because Hbase’s doesn’t offer aggregation queries, and because it was hard to scale in response to traffic bursts.

Transfer delays

Finally, every time we needed to generate a recommendation model for a personalized email blast, we needed to transfer the necessary data from HBase to Hive to create the model, then back to HBase. These complex data transfers were taking two-to-three days. Needless to say, this didn’t allow for the type of agility that we need to provide the best service to our customers.

Cloud Spanner allows us to store all our data in one place, and simply join the data tables and do aggregates; there’s no need for a time-intensive data transfer. Using this model, we believe we can cut the recommendation generation time from days to under a minute, bringing real-time back into the equation.

Why Cloud Spanner?

Compared to the previous application running on-premises, Cloud Spanner offers lower cost, lower operations requirements and higher availability. Most critically, we wanted to calculate metrics (KPIs) in real time without data transfer. Cloud Spanner allows us to do this by pumping SQL queries into a custom dashboard that monitors KPIs in real time.

Soup now runs on GCP, although the recommendations themselves are still generated in an on-premise Hadoop cluster. The computed recommendations are stored in Cloud Spanner for the reasons mentioned above. After moving to GCP and architecting for the cloud, we see an error rate of .005% per second vs. a previous rate of 4% per second, an improvement of 1/800. This means that for an email blast sent to all users in Japan, one user won’t be able to see one image in one email. Since these emails often contain 10 images or more, this error rate is acceptable.

Cloud Spanner also solved our scaling problem. In the future, Soup will have to support one million concurrent users in different geographical areas. Likewise, Soup has to perform 5,000 queries per second (QPS) at peak times on the read side, and will expand this requirement to 20,000 to 30,000 QPS in the near future. Cloud Spanner can handle all the different, complex transactions Soup has to run, while scaling horizontally with ease.

Takeaways


In migrating our database to Cloud Spanner, we learned many things that are worth taking note of, whether you have 10 or 10 million users.

Be prepared to scale

We took scaling into account from Day One, sketching out specific requirements for speed, high availability, and other metrics. Only by having these requirements specifically laid out were we able to choose—and build—a solution that could meet them. We knew we needed elastic scale.

With Cloud Spanner, we didn’t have to make any of the common trade-offs between the relational database structure we wanted, and the scalability and availability needed to keep up with the business requirements. Likewise, with a growing company, you don’t want to place any artificial limits on growth, and Cloud Spanner’s ability to scale to “arbitrarily large” database sizes eliminates this cap, as well as the need to rewrite or migrate in the future as our data needs grow.

Be realistic about downtime

For us, any downtime can result in literally thousands of lost opportunities. That meant that we had to demand virtually zero downtime from any solution, to avoid serving up errors to our users. This was an important realization. Google Cloud provides an SLA guarantee for Cloud Spanner. This solution is more available and resistant to outages than anything we would build on our own.

Don’t waste time on management overhead

When you’re worrying about millions of users and billions of emails, the last thing you have time to do is all the maintenance and administrative tasks required to keep a database system healthy and running. Of course, this is true for the smallest installations, as well. Nobody has a lot of extra time to do things that should be taken care of automatically.

Don’t be afraid of hybrid

We found that a hybrid architecture that leverages the cloud for fast data access but still using our existing on-premises investments for batch processing to be effective. In the future, we may move the entire workload to the cloud but data has gravity, and we currently have lots of data stored on-premises.

Aim for real-time

At this time, we can only move data in and out of Cloud Spanner in small volumes. This prevents us from making real-time changes to recommendations. Once Cloud Spanner supports batch and streaming connections, we'll be able to enable an implementation to provide more real-time recommendations to deliver even more relevant results and outcomes.

Overall, we’re extremely happy with Cloud Spanner and GCP. Google Cloud has been a great partner in our move to the cloud, and the unique services provided enable us to offer the best service to our customers and stay competitive.

Introducing Cloud Text-to-Speech powered by DeepMind WaveNet technology



Many Google products (e.g., the Google Assistant, Search, Maps) come with built-in high-quality text-to-speech synthesis that produces natural sounding speech. Developers have been telling us they’d like to add text-to-speech to their own applications, so today we’re bringing this technology to Google Cloud Platform with Cloud Text-to-Speech.

You can use Cloud Text-to-Speech in a variety of ways, for example:
  • To power voice response systems for call centers (IVRs) and enabling real-time natural language conversations 
  • To enable IoT devices (e.g., TVs, cars, robots) to talk back to you 
  •  To convert text-based media (e.g., news articles, books) into spoken format (e.g., podcast or audiobook)
Cloud Text-to-Speech lets you choose from 32 different voices from 12 languages and variants. Cloud Text-to-Speech correctly pronounces complex text such as names, dates, times and addresses for authentic sounding speech right out of the gate. Cloud Text-to-Speech also allows you to customize pitch, speaking rate, and volume gain, and supports a variety of audio formats, including MP3 and WAV.

Rolling in the DeepMind


In addition, we're excited to announce that Cloud Text-to-Speech also includes a selection of high-fidelity voices built using WaveNet, a generative model for raw audio created by DeepMind. WaveNet synthesizes more natural-sounding speech and, on average, produces speech audio that people prefer over other text-to-speech technologies.

In late 2016, DeepMind introduced the first version of WaveNet  a neural network trained with a large volume of speech samples that's able to create raw audio waveforms from scratch. During training, the network extracts the underlying structure of the speech, for example which tones follow one another and what shape a realistic speech waveform should have. When given text input, the trained WaveNet model generates the corresponding speech waveforms, one sample at a time, achieving higher accuracy than alternative approaches.

Fast forward to today, and we're now using an updated version of WaveNet that runs on Google’s Cloud TPU infrastructure.The new, improved WaveNet model generates raw waveforms 1,000 times faster than the original model, and can generate one second of speech in just 50 milliseconds. In fact, the model is not just quicker, but also higher-fidelity, capable of creating waveforms with 24,000 samples a second. We’ve also increased the resolution of each sample from 8 bits to 16 bits, producing higher quality audio for a more human sound.
With these adjustments, the new WaveNet model produces more natural sounding speech. In tests, people gave the new US English WaveNet voices an average mean-opinion-score (MOS) of 4.1 on a scale of 1-5 — over 20% better than for standard voices and reducing the gap with human speech by over 70%. As WaveNet voices also require less recorded audio input to produce high quality models, we expect to continue to improve both the variety as well as quality of the WaveNet voices available to Cloud customers in the coming months.
Cloud Text-to-Speech is already helping multiple customers deliver a better experience to their end users. Customers include Cisco and Dolphin ONE.
“As the leading provider of collaboration solutions, Cisco has a long history of bringing the latest technology advances into the enterprise. Google’s Cloud Text-to-Speech has enabled us to achieve the natural sound quality that our customers desire."  
 Tim Tuttle, CTO of Cognitive Collaboration, Cisco
“Dolphin ONE’s Calll.io telephony platform offers connectivity from a multitude of devices, at practically any location. We’ve integrated Cloud Text-to-Speech into our products and allow our users to create natural call center experiences. By using Google Cloud’s machine learning tools, we’re instantly delivering cutting-edge technology to our users.” 
Jason Berryman, Dolphin ONE

Get started today


With Cloud Text-to-Speech, you’re now a few clicks away from one of the most advanced speech technologies in the world. To learn more, please visit the documentation or our pricing page. To get started with our public beta or try out the new voices, visit the Cloud Text-to-Speech website.

Monitor your GCP environment with Cloud Security Command Center



Last week, we announced the release of Cloud Security Command CenterAlpha (Cloud SCC), a new security data analysis and monitoring platform for Google Cloud Platform (GCP). Cloud SCC, now available in alpha, helps enterprises gather security information, identify threats and take action on them.

As the use of cloud services continues to grow, clear visibility into the security status of an organization’s cloud services and resources is more important than ever. Businesses need the right data and actionable insights to stop threats before security incidents do any damage. Cloud SCC takes inventory of your cloud assets, flags unwanted changes to those assets and uses a number of unique detectors to identify risky areas in your environment. Its findings are populated into a single, centralized dashboard and data platform so that you can quickly get a read on the security health of your cloud applications and data.
Cloud SCC aggregates security information in a single, centralized dashboard
In this blog post, we’ll take a deeper look into the capabilities and features of Cloud Security Command Center.

Gain visibility into your cloud services and resources


Cloud SCC gives enterprises consolidated visibility into their cloud assets across App Engine, Compute Engine, Cloud Storage, and Datastore. Using asset inventory, you can view resources for the entire GCP organization or just for particular projects. Cloud SCC performs ongoing discovery scans which allows you to see asset history to understand exactly what changed in your environment and act on unauthorized modifications.
Cloud SCC gives you broad visibility cloud assets at the org and project level
Cloud SCC also features security “marks” that let you personalize how your security information is displayed, organized and managed in order to meet the unique requirements of your organization. With security marks, you can annotate your assets and then search, select, or filter using the mark—for example, you can filter out projects that you group together using the same mark.

Leverage powerful security insights from Google and leading security partners


Cloud SCC generates curated insights that provide you with a unique view of threats to your cloud assets. For example, security teams can answer questions like “Which cloud storage buckets contain PII?”, “Do I have any buckets that are open to the Internet?” and “Which cloud applications are vulnerable to XSS vulnerabilities?” With increasingly frequent reports of sensitive data being inadvertently exposed, gaining visibility into these key risk areas is especially important for enterprises. Cloud SCC integrates with Google Cloud security tools and leading security partners to give you these valuable security insights.

Detection from Google

Cloud SCC integrates with a number of Google Cloud security tools. With information from the DLP API, you can find out which storage buckets contain sensitive and regulated data, help prevent unintended exposure, and ensure access is based on need-to-know. You can also pull in information from Cloud Security Scanner which uncovers common vulnerabilities such as cross-site-scripting (XSS) and Flash injection that put your Google App Engine applications at risk. Using Forseti, an open source security toolkit for GCP, you can identify misconfigured access control policies and respond right away.
These Cloud SCC views show permission changes detected by Forseti, an open source GCP security toolkit
Administrators can also identify threats like botnets, cryptocurrency mining, and suspicious network traffic in your projects and virtual machine (VM) instances with built-in anomaly detection developed by the Google security team.
Cloud SCC features built-in anomaly detection from Google to identify threats to your cloud environment
This Cloud SCC "card" shows sensitive data uncovered by the DLP API
Detection from security partners

Using Cloud SCC, you can leverage intelligence from your existing security tools such as Cloudflare, CrowdStrike, Dome9, Palo Alto Networks, Qualys, and RedLock into Cloud Security Command Center to help detect DDoS attacks, compromised endpoints, compliance policy violations, network attacks, and instance vulnerabilities and threats. Our partner solutions cover a broad set of enterprise security needs and we’ll continue to add new partnerships to our network in the future.

Take advantage of an open and flexible platform


Cloud Security Command Center features a REST API which gives you the flexibility to work with your existing security systems and workflows. Using the API, enterprises can easily integrate the full range of their own threat detection capabilities—once the data sources are forwarded to Cloud Security Command Center, they can be viewed just like the Google-provided Command Center detectors. In addition, you can take advantage of the Pub/Sub notification integration to receive Cloud SCC alerts via Gmail, SMS, and Jira.

Try Cloud Security Command Center today


We’re excited to bring the Cloud SCC security monitoring platform to the suite of GCP security services. To learn more, check out the product documentation, or get started today by signing up for the Cloud SCC alpha program.