The way to “protect” actions from being accessible via a URL is to not provide a URL mapping to them. The default url mapping looks something like this…
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
// ...
}
}
That “/$controller/$action?/$id?(.$format)?” mapping is convenient for simple crud apps and demos well but for any substantial app you should almost always remove that. Without it, only the actions you explicitly expose are accessible.