```go
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"golang.org/x/time/rate"
)

type RateLimiter struct {
	rate  int
	burst int
}

var elasticsearchHost string
var elasticsearchPort int
var apiKey string
var rateLimiters map[string]*rate.Limiter

func init() {
	flag.StringVar(&elasticsearchHost, "host", "localhost", "Elasticsearch host")
	flag.IntVar(&elasticsearchPort, "port", 9200, "Elasticsearch port")
	flag.StringVar(&apiKey, "apikey", "", "API key for authentication")

	rateLimiters = make(map[string]*rate.Limiter)
}

func getRateLimiter(ip string) *rate.Limiter {
	if limiter, exists := rateLimiters[ip]; exists {
		return limiter
	}
	newLimiter := rate.NewLimiter(rate.Every(time.Minute), 100)
	rateLimiters[ip] = newLimiter
	return newLimiter
}

func proxyHandler(w http.ResponseWriter, r *http.Request) {
	ip := strings.Split(r.RemoteAddr, ":")[0]
	limiter := getRateLimiter(ip)

	if !limiter.Allow() {
		http.Error(w, "Too many requests", http.StatusTooManyRequests)
		return
	}

	url := fmt.Sprintf("http://%s:%d%s", elasticsearchHost, elasticsearchPort, r.URL.Path)
	req, err := http.NewRequest(r.Method, url, r.Body)
	if err != nil {
		http.Error(w, "Error creating request", http.StatusInternalServerError)
		return
	}

	for name, values := range r.Header {
		for _, value := range values {
			req.Header.Add(name, value)
		}
	}

	req.Header.Set("Authorization", fmt.Sprintf("ApiKey %s", apiKey))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		http.Error(w, "Error forwarding request", http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		http.Error(w, "Error reading response body", http.StatusInternalServerError)
		return
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		http.Error(w, "Error unmarshalling JSON", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(jsonResponse)
}

func main() {
	flag.Parse()
	router := mux.NewRouter()
	router.PathPrefix("/").HandlerFunc(proxyHandler)

	fmt.Printf("Starting proxy server on :8080\n")
	http.ListenAndServe(":8080", router)
}
```

This Golang program serves as a RESTful API proxy for Elasticsearch with additional security features such as authentication and rate limiting. It accepts command line arguments for the Elasticsearch host, port, and API key.

To run this program, you need to have Go installed on your system. Save the code in a file named `main.go` and then execute the following commands:

```sh
go mod init elasticsearch-proxy
go get -u github.com/gorilla/mux
go build
./elasticsearch-proxy --host=<ElasticsearchHost> --port=<ElasticsearchPort> --apikey=<APIKey>
```

Replace `<ElasticsearchHost>`, `<ElasticsearchPort>`, and `<APIKey>` with appropriate values.

The program listens on port 8080 and forwards incoming requests to the specified Elasticsearch instance after checking the rate limits. The rate limiter is configured to allow 100 requests per minute for each IP address. You can modify the rate limiting rules by changing the values in the `getRateLimiter` function.

Please note that this is a basic implementation and may not cover all possible scenarios or edge cases. For production use, consider using more advanced libraries and techniques to handle authentication, rate limiting, and other security features.
```go
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"golang.org/x/time/rate"
)

type RateLimiter struct {
	rate  int
	burst int
}

var elasticsearchHost string
var elasticsearchPort int
var apiKey string
var rateLimiters map[string]*rate.Limiter

func init() {
	flag.StringVar(&elasticsearchHost, "host", "localhost", "Elasticsearch host")
	flag.IntVar(&elasticsearchPort, "port", 9200, "Elasticsearch port")
	flag.StringVar(&apiKey, "apikey", "", "API key for authentication")

	rateLimiters = make(map[string]*rate.Limiter)
}

func getRateLimiter(ip string) *rate.Limiter {
	if limiter, exists := rateLimiters[ip]; exists {
		return limiter
	}
	newLimiter := rate.NewLimiter(rate.Every(time.Minute), 100)
	rateLimiters[ip] = newLimiter
	return newLimiter
}

func proxyHandler(w http.ResponseWriter, r *http.Request) {
	ip := strings.Split(r.RemoteAddr, ":")[0]
	limiter := getRateLimiter(ip)

	if !limiter.Allow() {
		http.Error(w, "Too many requests", http.StatusTooManyRequests)
		return
	}

	url := fmt.Sprintf("http://%s:%d%s", elasticsearchHost, elasticsearchPort, r.URL.Path)
	req, err := http.NewRequest(r.Method, url, r.Body)
	if err != nil {
		http.Error(w, "Error creating request", http.StatusInternalServerError)
		return
	}

	for name, values := range r.Header {
		for _, value := range values {
			req.Header.Add(name, value)
		}
	}

	req.Header.Set("Authorization", fmt.Sprintf("ApiKey %s", apiKey))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		http.Error(w, "Error forwarding request", http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		http.Error(w, "Error reading response body", http.StatusInternalServerError)
		return
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		http.Error(w, "Error unmarshalling JSON", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(jsonResponse)
}

func main() {
	flag.Parse()
	router := mux.NewRouter()
	router.PathPrefix("/").HandlerFunc(proxyHandler)

	fmt.Printf("Starting proxy server on :8080\n")
	http.ListenAndServe(":8080", router)
}
```

이 Golang 프로그램은 인증 및 속도 제한과 같은 추가 보안 기능을 갖춘 Elasticsearch용 RESTful API 프록시 역할을 합니다. Elasticsearch 호스트, 포트 및 API 키에 대한 명령줄 인수를 허용합니다.

이 프로그램을 실행하려면 시스템에 Go가 설치되어 있어야 합니다. 'main.go'라는 파일에 코드를 저장한 다음 다음 명령을 실행합니다:

```sh
go mod init elasticsearch-proxy
go get -u github.com/gorilla/mux
go build
./elasticsearch-proxy --host=<ElasticsearchHost> --port=<ElasticsearchPort> --apikey=<APIKey>
```

'<ElasticsearchHost>`, '<ElasticsearchPort>`, '<APIKey>`를 적절한 값으로 바꿉니다.

프로그램은 포트 8080에서 수신 대기하고 속도 제한을 확인한 후 들어오는 요청을 지정된 Elasticsearch 인스턴스로 전달합니다. 속도 제한기는 각 IP 주소에 대해 분당 100건의 요청을 허용하도록 구성됩니다. getRateLimiter` 함수의 값을 변경하여 전송률 제한 규칙을 수정할 수 있습니다.

이것은 기본 구현이며 가능한 모든 시나리오나 에지 케이스를 다루지 못할 수도 있습니다. 프로덕션 환경에서는 인증, 전송률 제한 및 기타 보안 기능을 처리하기 위해 고급 라이브러리 및 기술을 사용하는 것이 좋습니다.